✨ Show user level
This commit is contained in:
parent
594f57e0d3
commit
67a29b4305
41
lib/providers/experience.dart
Normal file
41
lib/providers/experience.dart
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
const List<int> kExperienceToLevelRequirements = [
|
||||||
|
0, // Level 0
|
||||||
|
1000, // Level 1
|
||||||
|
4000, // Level 2
|
||||||
|
9000, // Level 3
|
||||||
|
16000, // Level 4
|
||||||
|
25000, // Level 5
|
||||||
|
36000, // Level 6
|
||||||
|
49000, // Level 7
|
||||||
|
64000, // Level 8
|
||||||
|
81000, // Level 9
|
||||||
|
100000, // Level 10
|
||||||
|
121000, // Level 11
|
||||||
|
144000, // Level 12
|
||||||
|
368000 // Level 13
|
||||||
|
];
|
||||||
|
|
||||||
|
int getLevelFromExp(int experience) {
|
||||||
|
final exp = kExperienceToLevelRequirements.reversed.firstWhere((x) => x <= experience);
|
||||||
|
final idx = kExperienceToLevelRequirements.indexOf(exp);
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
double calcLevelUpProgress(int experience) {
|
||||||
|
final exp = kExperienceToLevelRequirements.reversed.firstWhere((x) => x <= experience);
|
||||||
|
final idx = kExperienceToLevelRequirements.indexOf(exp);
|
||||||
|
if (idx + 1 >= kExperienceToLevelRequirements.length) return 1;
|
||||||
|
final nextExp = kExperienceToLevelRequirements[idx + 1];
|
||||||
|
return (experience - exp).abs() / (exp - nextExp).abs();
|
||||||
|
}
|
||||||
|
|
||||||
|
String calcLevelUpProgressLevel(int experience) {
|
||||||
|
final exp = kExperienceToLevelRequirements.reversed.firstWhere((x) => x <= experience);
|
||||||
|
final idx = kExperienceToLevelRequirements.indexOf(exp);
|
||||||
|
if (idx + 1 >= kExperienceToLevelRequirements.length) return 'Infinity';
|
||||||
|
final nextExp = exp - kExperienceToLevelRequirements[idx + 1];
|
||||||
|
final formatter = NumberFormat.compactCurrency(symbol: '', decimalDigits: 1);
|
||||||
|
return '${formatter.format((exp - experience).abs())}/${formatter.format(nextExp.abs())}';
|
||||||
|
}
|
@ -9,6 +9,7 @@ import 'package:material_symbols_icons/symbols.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:relative_time/relative_time.dart';
|
import 'package:relative_time/relative_time.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
import 'package:surface/providers/experience.dart';
|
||||||
import 'package:surface/providers/relationship.dart';
|
import 'package:surface/providers/relationship.dart';
|
||||||
import 'package:surface/providers/sn_network.dart';
|
import 'package:surface/providers/sn_network.dart';
|
||||||
import 'package:surface/screens/abuse_report.dart';
|
import 'package:surface/screens/abuse_report.dart';
|
||||||
@ -437,6 +438,7 @@ class _UserScreenState extends State<UserScreen> with SingleTickerProviderStateM
|
|||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
const Icon(Symbols.calendar_add_on),
|
const Icon(Symbols.calendar_add_on),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
@ -444,6 +446,7 @@ class _UserScreenState extends State<UserScreen> with SingleTickerProviderStateM
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
const Icon(Symbols.cake),
|
const Icon(Symbols.cake),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
@ -457,6 +460,7 @@ class _UserScreenState extends State<UserScreen> with SingleTickerProviderStateM
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
const Icon(Symbols.identity_platform),
|
const Icon(Symbols.identity_platform),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
@ -466,6 +470,26 @@ class _UserScreenState extends State<UserScreen> with SingleTickerProviderStateM
|
|||||||
).opacity(0.8),
|
).opacity(0.8),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Icon(Symbols.star),
|
||||||
|
const Gap(8),
|
||||||
|
Text('Lv${getLevelFromExp(_account?.profile?.experience ?? 0)}'),
|
||||||
|
const Gap(8),
|
||||||
|
Text(calcLevelUpProgressLevel(_account?.profile?.experience ?? 0)).fontSize(11).opacity(0.5),
|
||||||
|
const Gap(8),
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
constraints: const BoxConstraints(maxWidth: 160),
|
||||||
|
child: LinearProgressIndicator(
|
||||||
|
value: calcLevelUpProgress(_account?.profile?.experience ?? 0),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.surfaceContainer,
|
||||||
|
).alignment(Alignment.centerLeft),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
).padding(horizontal: 8),
|
).padding(horizontal: 8),
|
||||||
],
|
],
|
||||||
|
@ -45,17 +45,9 @@ class _PostPublisherScreenState extends State<PostPublisherScreen> with SingleTi
|
|||||||
Future<void> _fetchPublisher() async {
|
Future<void> _fetchPublisher() async {
|
||||||
try {
|
try {
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
final ud = context.read<UserDirectoryProvider>();
|
|
||||||
final rel = context.read<SnRelationshipProvider>();
|
|
||||||
final resp = await sn.client.get('/cgi/co/publishers/${widget.name}');
|
final resp = await sn.client.get('/cgi/co/publishers/${widget.name}');
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
_publisher = SnPublisher.fromJson(resp.data);
|
_publisher = SnPublisher.fromJson(resp.data);
|
||||||
_account = await ud.getAccount(_publisher?.accountId);
|
|
||||||
_accountRelationship = await rel.getRelationship(_account!.id);
|
|
||||||
if (_publisher?.realmId != null && _publisher!.realmId != 0) {
|
|
||||||
final resp = await sn.client.get('/cgi/id/realms/${_publisher!.realmId}');
|
|
||||||
_realm = SnRealm.fromJson(resp.data);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
context.showErrorDialog(err).then((_) {
|
context.showErrorDialog(err).then((_) {
|
||||||
@ -65,6 +57,20 @@ class _PostPublisherScreenState extends State<PostPublisherScreen> with SingleTi
|
|||||||
} finally {
|
} finally {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
final ud = context.read<UserDirectoryProvider>();
|
||||||
|
final rel = context.read<SnRelationshipProvider>();
|
||||||
|
_account = await ud.getAccount(_publisher?.accountId);
|
||||||
|
_accountRelationship = await rel.getRelationship(_account!.id);
|
||||||
|
if (_publisher?.realmId != null && _publisher!.realmId != 0) {
|
||||||
|
final resp = await sn.client.get('/cgi/id/realms/${_publisher!.realmId}');
|
||||||
|
_realm = SnRealm.fromJson(resp.data);
|
||||||
|
}
|
||||||
|
} catch (_) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isSubscribing = false;
|
bool _isSubscribing = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user