✨ User experience & level
This commit is contained in:
		
							
								
								
									
										51
									
								
								lib/providers/experience.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								lib/providers/experience.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | |||||||
|  | import 'package:get/get.dart'; | ||||||
|  | import 'package:intl/intl.dart'; | ||||||
|  |  | ||||||
|  | class ExperienceProvider extends GetxController { | ||||||
|  |   static List<int> experienceToLevelRequirements = [ | ||||||
|  |     0, // Level 0 | ||||||
|  |     100, // Level 1 | ||||||
|  |     400, // Level 2 | ||||||
|  |     900, // Level 3 | ||||||
|  |     1600, // Level 4 | ||||||
|  |     2500, // Level 5 | ||||||
|  |     3600, // Level 6 | ||||||
|  |     4900, // Level 7 | ||||||
|  |     6400, // Level 8 | ||||||
|  |     8100, // Level 9 | ||||||
|  |     10000, // Level 10 | ||||||
|  |     12100, // Level 11 | ||||||
|  |     14400, // Level 12 | ||||||
|  |     36800 // Level 13 | ||||||
|  |   ]; | ||||||
|  |  | ||||||
|  |   static List<String> levelLabelMapping = | ||||||
|  |       List.generate(experienceToLevelRequirements.length, (x) => 'userLevel$x'); | ||||||
|  |  | ||||||
|  |   static (int level, String label) getLevelFromExp(int experience) { | ||||||
|  |     final exp = experienceToLevelRequirements.reversed | ||||||
|  |         .firstWhere((x) => x <= experience); | ||||||
|  |     final idx = experienceToLevelRequirements.indexOf(exp); | ||||||
|  |     return (idx, levelLabelMapping[idx]); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static double calcLevelUpProgress(int experience) { | ||||||
|  |     final exp = experienceToLevelRequirements.reversed | ||||||
|  |         .firstWhere((x) => x <= experience); | ||||||
|  |     final idx = experienceToLevelRequirements.indexOf(exp); | ||||||
|  |     if (idx + 1 >= experienceToLevelRequirements.length) return 1; | ||||||
|  |     final nextExp = experienceToLevelRequirements[idx + 1]; | ||||||
|  |     return exp / nextExp; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static String calcLevelUpProgressLevel(int experience) { | ||||||
|  |     final exp = experienceToLevelRequirements.reversed | ||||||
|  |         .firstWhere((x) => x <= experience); | ||||||
|  |     final idx = experienceToLevelRequirements.indexOf(exp); | ||||||
|  |     if (idx + 1 >= experienceToLevelRequirements.length) return 'Infinity'; | ||||||
|  |     final nextExp = experienceToLevelRequirements[idx + 1]; | ||||||
|  |     final formatter = | ||||||
|  |         NumberFormat.compactCurrency(symbol: '', decimalDigits: 1); | ||||||
|  |     return '${formatter.format(exp)}/${formatter.format(nextExp)}'; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -8,10 +8,12 @@ import 'package:solian/models/account.dart'; | |||||||
| import 'package:solian/models/attachment.dart'; | import 'package:solian/models/attachment.dart'; | ||||||
| import 'package:solian/models/pagination.dart'; | import 'package:solian/models/pagination.dart'; | ||||||
| import 'package:solian/models/post.dart'; | import 'package:solian/models/post.dart'; | ||||||
|  | import 'package:solian/providers/account_status.dart'; | ||||||
| import 'package:solian/providers/relation.dart'; | import 'package:solian/providers/relation.dart'; | ||||||
| import 'package:solian/services.dart'; | import 'package:solian/services.dart'; | ||||||
| import 'package:solian/theme.dart'; | import 'package:solian/theme.dart'; | ||||||
| import 'package:solian/widgets/account/account_avatar.dart'; | import 'package:solian/widgets/account/account_avatar.dart'; | ||||||
|  | import 'package:solian/widgets/account/account_heading.dart'; | ||||||
| import 'package:solian/widgets/app_bar_leading.dart'; | import 'package:solian/widgets/app_bar_leading.dart'; | ||||||
| import 'package:solian/widgets/attachments/attachment_list.dart'; | import 'package:solian/widgets/attachments/attachment_list.dart'; | ||||||
| import 'package:solian/widgets/posts/post_list.dart'; | import 'package:solian/widgets/posts/post_list.dart'; | ||||||
| @@ -143,7 +145,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> { | |||||||
|     return Material( |     return Material( | ||||||
|       color: Theme.of(context).colorScheme.surface, |       color: Theme.of(context).colorScheme.surface, | ||||||
|       child: DefaultTabController( |       child: DefaultTabController( | ||||||
|         length: 2, |         length: 3, | ||||||
|         child: NestedScrollView( |         child: NestedScrollView( | ||||||
|           headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { |           headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { | ||||||
|             return [ |             return [ | ||||||
| @@ -211,6 +213,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> { | |||||||
|                 ), |                 ), | ||||||
|                 bottom: TabBar( |                 bottom: TabBar( | ||||||
|                   tabs: [ |                   tabs: [ | ||||||
|  |                     Tab(text: 'profilePage'.tr), | ||||||
|                     Tab(text: 'profilePosts'.tr), |                     Tab(text: 'profilePosts'.tr), | ||||||
|                     Tab(text: 'profileAlbum'.tr), |                     Tab(text: 'profileAlbum'.tr), | ||||||
|                   ], |                   ], | ||||||
| @@ -221,6 +224,24 @@ class _AccountProfilePageState extends State<AccountProfilePage> { | |||||||
|           body: TabBarView( |           body: TabBarView( | ||||||
|             physics: const NeverScrollableScrollPhysics(), |             physics: const NeverScrollableScrollPhysics(), | ||||||
|             children: [ |             children: [ | ||||||
|  |               Column( | ||||||
|  |                 children: [ | ||||||
|  |                   const Gap(16), | ||||||
|  |                   AccountHeadingWidget( | ||||||
|  |                     name: _userinfo!.name, | ||||||
|  |                     nick: _userinfo!.nick, | ||||||
|  |                     desc: _userinfo!.description, | ||||||
|  |                     badges: _userinfo!.badges, | ||||||
|  |                     banner: _userinfo!.banner, | ||||||
|  |                     avatar: _userinfo!.avatar, | ||||||
|  |                     status: Get.find<StatusProvider>() | ||||||
|  |                         .getSomeoneStatus(_userinfo!.name), | ||||||
|  |                     detail: _userinfo, | ||||||
|  |                     profile: _userinfo!.profile, | ||||||
|  |                     extraWidgets: const [], | ||||||
|  |                   ), | ||||||
|  |                 ], | ||||||
|  |               ), | ||||||
|               RefreshIndicator( |               RefreshIndicator( | ||||||
|                 onRefresh: () => Future.wait([ |                 onRefresh: () => Future.wait([ | ||||||
|                   _postController.reloadAllOver(), |                   _postController.reloadAllOver(), | ||||||
|   | |||||||
| @@ -136,10 +136,12 @@ class _DashboardScreenState extends State<DashboardScreen> { | |||||||
|             crossAxisAlignment: CrossAxisAlignment.start, |             crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|             children: [ |             children: [ | ||||||
|               Text( |               Text( | ||||||
|                 'today'.tr, |                 DateTime.now().day == DateTime.now().toUtc().day | ||||||
|  |                     ? 'today'.tr | ||||||
|  |                     : 'yesterday'.tr, | ||||||
|                 style: Theme.of(context).textTheme.headlineSmall, |                 style: Theme.of(context).textTheme.headlineSmall, | ||||||
|               ), |               ), | ||||||
|               Text(DateFormat('yyyy/MM/dd').format(DateTime.now())), |               Text(DateFormat('yyyy/MM/dd').format(DateTime.now().toUtc())), | ||||||
|             ], |             ], | ||||||
|           ).paddingOnly(top: 8, left: 18, right: 18, bottom: 12), |           ).paddingOnly(top: 8, left: 18, right: 18, bottom: 12), | ||||||
|           Card( |           Card( | ||||||
| @@ -502,16 +504,7 @@ class _DashboardScreenState extends State<DashboardScreen> { | |||||||
|               ), |               ), | ||||||
|               Text( |               Text( | ||||||
|                 'dashboardFooter'.tr, |                 'dashboardFooter'.tr, | ||||||
|                 style: [const Locale('zh', 'CN'), const Locale('zh', 'HK')] |                 style: TextStyle(color: _unFocusColor, fontSize: 12), | ||||||
|                         .contains(Get.deviceLocale) |  | ||||||
|                     ? GoogleFonts.notoSerifHk( |  | ||||||
|                         color: _unFocusColor, |  | ||||||
|                         fontSize: 12, |  | ||||||
|                       ) |  | ||||||
|                     : TextStyle( |  | ||||||
|                         color: _unFocusColor, |  | ||||||
|                         fontSize: 12, |  | ||||||
|                       ), |  | ||||||
|               ) |               ) | ||||||
|             ], |             ], | ||||||
|           ).paddingAll(8), |           ).paddingAll(8), | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart'; | |||||||
| import 'package:solian/theme.dart'; | import 'package:solian/theme.dart'; | ||||||
| import 'package:solian/widgets/app_bar_title.dart'; | import 'package:solian/widgets/app_bar_title.dart'; | ||||||
| import 'package:solian/widgets/app_bar_leading.dart'; | import 'package:solian/widgets/app_bar_leading.dart'; | ||||||
|  | import 'package:solian/widgets/current_state_action.dart'; | ||||||
|  |  | ||||||
| class TitleShell extends StatelessWidget { | class TitleShell extends StatelessWidget { | ||||||
|   final bool showAppBar; |   final bool showAppBar; | ||||||
| @@ -32,6 +33,12 @@ class TitleShell extends StatelessWidget { | |||||||
|               ), |               ), | ||||||
|               centerTitle: isCenteredTitle, |               centerTitle: isCenteredTitle, | ||||||
|               toolbarHeight: SolianTheme.toolbarHeight(context), |               toolbarHeight: SolianTheme.toolbarHeight(context), | ||||||
|  |               actions: [ | ||||||
|  |                 const BackgroundStateWidget(), | ||||||
|  |                 SizedBox( | ||||||
|  |                   width: SolianTheme.isLargeScreen(context) ? 8 : 16, | ||||||
|  |                 ), | ||||||
|  |               ], | ||||||
|             ) |             ) | ||||||
|           : null, |           : null, | ||||||
|       body: child, |       body: child, | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ const i18nEnglish = { | |||||||
|   'draft': 'Draft', |   'draft': 'Draft', | ||||||
|   'dashboard': 'Dashboard', |   'dashboard': 'Dashboard', | ||||||
|   'today': 'Today', |   'today': 'Today', | ||||||
|  |   'yesterday': 'Yesterday', | ||||||
|   'draftSave': 'Save', |   'draftSave': 'Save', | ||||||
|   'draftBox': 'Draft Box', |   'draftBox': 'Draft Box', | ||||||
|   'more': 'More', |   'more': 'More', | ||||||
| @@ -33,6 +34,7 @@ const i18nEnglish = { | |||||||
|   'dailySignTier4': 'Everything will be awesome', |   'dailySignTier4': 'Everything will be awesome', | ||||||
|   'dashboardFooter': 'Don\'t be serious, just for fun.', |   'dashboardFooter': 'Don\'t be serious, just for fun.', | ||||||
|   'visitProfilePage': 'Visit Profile Page', |   'visitProfilePage': 'Visit Profile Page', | ||||||
|  |   'profilePage': 'Page', | ||||||
|   'profilePosts': 'Posts', |   'profilePosts': 'Posts', | ||||||
|   'profileAlbum': 'Album', |   'profileAlbum': 'Album', | ||||||
|   'chat': 'Chat', |   'chat': 'Chat', | ||||||
| @@ -400,4 +402,18 @@ const i18nEnglish = { | |||||||
|   'collapse': 'Collapse', |   'collapse': 'Collapse', | ||||||
|   'expand': 'Expand', |   'expand': 'Expand', | ||||||
|   'typingMessage': '@user are typing...', |   'typingMessage': '@user are typing...', | ||||||
|  |   'userLevel0': 'Newbie', | ||||||
|  |   'userLevel1': 'Novice', | ||||||
|  |   'userLevel2': 'Apprentice', | ||||||
|  |   'userLevel3': 'Explorer', | ||||||
|  |   'userLevel4': 'Adventurer', | ||||||
|  |   'userLevel5': 'Warrior', | ||||||
|  |   'userLevel6': 'Knight', | ||||||
|  |   'userLevel7': 'Champion', | ||||||
|  |   'userLevel8': 'Hero', | ||||||
|  |   'userLevel9': 'Master', | ||||||
|  |   'userLevel10': 'Grandmaster', | ||||||
|  |   'userLevel11': 'Legend', | ||||||
|  |   'userLevel12': 'Mythic', | ||||||
|  |   'userLevel13': 'Immortal', | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ const i18nSimplifiedChinese = { | |||||||
|   'unlink': '移除链接', |   'unlink': '移除链接', | ||||||
|   'dashboard': '仪表盘', |   'dashboard': '仪表盘', | ||||||
|   'today': '今日', |   'today': '今日', | ||||||
|  |   'yesterday': '昨日', | ||||||
|   'feedSearch': '搜索资讯', |   'feedSearch': '搜索资讯', | ||||||
|   'feedSearchWithTag': '检索带有 #@key 标签的资讯', |   'feedSearchWithTag': '检索带有 #@key 标签的资讯', | ||||||
|   'feedSearchWithCategory': '检索位于分类 @category 的资讯', |   'feedSearchWithCategory': '检索位于分类 @category 的资讯', | ||||||
| @@ -41,6 +42,7 @@ const i18nSimplifiedChinese = { | |||||||
|   'dailySignTier4': '诸事皆宜', |   'dailySignTier4': '诸事皆宜', | ||||||
|   'dashboardFooter': '占卜多少沾点玩,人生还得靠实力', |   'dashboardFooter': '占卜多少沾点玩,人生还得靠实力', | ||||||
|   'visitProfilePage': '造访个人主页', |   'visitProfilePage': '造访个人主页', | ||||||
|  |   'profilePage': '主页', | ||||||
|   'profilePosts': '帖子', |   'profilePosts': '帖子', | ||||||
|   'profileAlbum': '相簿', |   'profileAlbum': '相簿', | ||||||
|   'chat': '聊天', |   'chat': '聊天', | ||||||
| @@ -370,4 +372,18 @@ const i18nSimplifiedChinese = { | |||||||
|   'collapse': '折叠', |   'collapse': '折叠', | ||||||
|   'expand': '展开', |   'expand': '展开', | ||||||
|   'typingMessage': '@user 正在输入中…', |   'typingMessage': '@user 正在输入中…', | ||||||
|  |   'userLevel0': '不慕名利', | ||||||
|  |   'userLevel1': '初出茅庐', | ||||||
|  |   'userLevel2': '小试牛刀', | ||||||
|  |   'userLevel3': '磨杵成针', | ||||||
|  |   'userLevel4': '披荆斩棘', | ||||||
|  |   'userLevel5': '力挽狂澜', | ||||||
|  |   'userLevel6': '一骑当千', | ||||||
|  |   'userLevel7': '所向披靡', | ||||||
|  |   'userLevel8': '气吞山河', | ||||||
|  |   'userLevel9': '登峰造极', | ||||||
|  |   'userLevel10': '出神入化', | ||||||
|  |   'userLevel11': '名垂千古', | ||||||
|  |   'userLevel12': '独占鳌头', | ||||||
|  |   'userLevel13': '万古流芳', | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -1,11 +1,13 @@ | |||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
| import 'package:gap/gap.dart'; | import 'package:gap/gap.dart'; | ||||||
| import 'package:get/get.dart'; | import 'package:get/get.dart'; | ||||||
|  | import 'package:google_fonts/google_fonts.dart'; | ||||||
| import 'package:intl/intl.dart'; | import 'package:intl/intl.dart'; | ||||||
| import 'package:solian/models/account.dart'; | import 'package:solian/models/account.dart'; | ||||||
| import 'package:solian/models/account_status.dart'; | import 'package:solian/models/account_status.dart'; | ||||||
| import 'package:solian/platform.dart'; | import 'package:solian/platform.dart'; | ||||||
| import 'package:solian/providers/account_status.dart'; | import 'package:solian/providers/account_status.dart'; | ||||||
|  | import 'package:solian/providers/experience.dart'; | ||||||
| import 'package:solian/widgets/account/account_avatar.dart'; | import 'package:solian/widgets/account/account_avatar.dart'; | ||||||
| import 'package:solian/widgets/account/account_badge.dart'; | import 'package:solian/widgets/account/account_badge.dart'; | ||||||
| import 'package:solian/widgets/account/account_status_action.dart'; | import 'package:solian/widgets/account/account_status_action.dart'; | ||||||
| @@ -18,6 +20,7 @@ class AccountHeadingWidget extends StatelessWidget { | |||||||
|   final String nick; |   final String nick; | ||||||
|   final String? desc; |   final String? desc; | ||||||
|   final Account? detail; |   final Account? detail; | ||||||
|  |   final AccountProfile? profile; | ||||||
|   final List<AccountBadge>? badges; |   final List<AccountBadge>? badges; | ||||||
|   final List<Widget>? extraWidgets; |   final List<Widget>? extraWidgets; | ||||||
|  |  | ||||||
| @@ -33,6 +36,7 @@ class AccountHeadingWidget extends StatelessWidget { | |||||||
|     required this.desc, |     required this.desc, | ||||||
|     required this.badges, |     required this.badges, | ||||||
|     this.detail, |     this.detail, | ||||||
|  |     this.profile, | ||||||
|     this.status, |     this.status, | ||||||
|     this.extraWidgets, |     this.extraWidgets, | ||||||
|     this.onEditStatus, |     this.onEditStatus, | ||||||
| @@ -130,7 +134,10 @@ class AccountHeadingWidget extends StatelessWidget { | |||||||
|                         child: Row( |                         child: Row( | ||||||
|                           crossAxisAlignment: CrossAxisAlignment.center, |                           crossAxisAlignment: CrossAxisAlignment.center, | ||||||
|                           children: [ |                           children: [ | ||||||
|                             Text(info.$3), |                             Text( | ||||||
|  |                               info.$3, | ||||||
|  |                               style: const TextStyle(height: 1), | ||||||
|  |                             ).paddingOnly(bottom: 3), | ||||||
|                             if (!status.isOnline && status.lastSeenAt != null) |                             if (!status.isOnline && status.lastSeenAt != null) | ||||||
|                               Opacity( |                               Opacity( | ||||||
|                                 opacity: 0.75, |                                 opacity: 0.75, | ||||||
| @@ -182,6 +189,63 @@ class AccountHeadingWidget extends StatelessWidget { | |||||||
|                 ), |                 ), | ||||||
|               ), |               ), | ||||||
|             ).paddingSymmetric(horizontal: 16), |             ).paddingSymmetric(horizontal: 16), | ||||||
|  |           if (profile != null) | ||||||
|  |             Card( | ||||||
|  |               child: ListTile( | ||||||
|  |                 shape: const RoundedRectangleBorder( | ||||||
|  |                   borderRadius: BorderRadius.all(Radius.circular(8)), | ||||||
|  |                 ), | ||||||
|  |                 visualDensity: | ||||||
|  |                     const VisualDensity(horizontal: -4, vertical: -2), | ||||||
|  |                 title: Row( | ||||||
|  |                   crossAxisAlignment: CrossAxisAlignment.center, | ||||||
|  |                   children: [ | ||||||
|  |                     Text( | ||||||
|  |                       ExperienceProvider.getLevelFromExp( | ||||||
|  |                         profile!.experience ?? 0, | ||||||
|  |                       ).$2.tr, | ||||||
|  |                     ), | ||||||
|  |                     const Gap(4), | ||||||
|  |                     Badge( | ||||||
|  |                       label: Text( | ||||||
|  |                         'Lv${ExperienceProvider.getLevelFromExp( | ||||||
|  |                           profile!.experience ?? 0, | ||||||
|  |                         ).$1}', | ||||||
|  |                         style: GoogleFonts.dosis( | ||||||
|  |                           fontWeight: FontWeight.bold, | ||||||
|  |                         ), | ||||||
|  |                       ), | ||||||
|  |                     ).paddingOnly(top: 1), | ||||||
|  |                   ], | ||||||
|  |                 ), | ||||||
|  |                 subtitle: SizedBox( | ||||||
|  |                   height: 20, | ||||||
|  |                   child: Row( | ||||||
|  |                     crossAxisAlignment: CrossAxisAlignment.center, | ||||||
|  |                     children: [ | ||||||
|  |                       Expanded( | ||||||
|  |                         child: LinearProgressIndicator( | ||||||
|  |                           borderRadius: const BorderRadius.all( | ||||||
|  |                             Radius.circular(8), | ||||||
|  |                           ), | ||||||
|  |                           value: ExperienceProvider.calcLevelUpProgress( | ||||||
|  |                             profile!.experience ?? 0, | ||||||
|  |                           ), | ||||||
|  |                         ), | ||||||
|  |                       ), | ||||||
|  |                       const Gap(8), | ||||||
|  |                       Text( | ||||||
|  |                         '${ExperienceProvider.calcLevelUpProgressLevel(profile!.experience ?? 0)} EXP', | ||||||
|  |                         style: GoogleFonts.robotoMono( | ||||||
|  |                           fontSize: 10, | ||||||
|  |                           height: 0.5, | ||||||
|  |                         ), | ||||||
|  |                       ), | ||||||
|  |                     ], | ||||||
|  |                   ), | ||||||
|  |                 ), | ||||||
|  |               ), | ||||||
|  |             ).paddingSymmetric(horizontal: 16), | ||||||
|           SizedBox( |           SizedBox( | ||||||
|             width: double.infinity, |             width: double.infinity, | ||||||
|             child: Card( |             child: Card( | ||||||
|   | |||||||
| @@ -99,6 +99,7 @@ class _AccountProfilePopupState extends State<AccountProfilePopup> { | |||||||
|             nick: _userinfo!.nick, |             nick: _userinfo!.nick, | ||||||
|             desc: _userinfo!.description, |             desc: _userinfo!.description, | ||||||
|             detail: _userinfo!, |             detail: _userinfo!, | ||||||
|  |             profile: _userinfo!.profile, | ||||||
|             badges: _userinfo!.badges, |             badges: _userinfo!.badges, | ||||||
|             status: |             status: | ||||||
|                 Get.find<StatusProvider>().getSomeoneStatus(_userinfo!.name), |                 Get.find<StatusProvider>().getSomeoneStatus(_userinfo!.name), | ||||||
|   | |||||||
| @@ -347,8 +347,9 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> { | |||||||
|                             FutureBuilder( |                             FutureBuilder( | ||||||
|                               future: element.file.length(), |                               future: element.file.length(), | ||||||
|                               builder: (context, snapshot) { |                               builder: (context, snapshot) { | ||||||
|                                 if (!snapshot.hasData) |                                 if (!snapshot.hasData) { | ||||||
|                                   return const SizedBox.shrink(); |                                   return const SizedBox.shrink(); | ||||||
|  |                                 } | ||||||
|                                 return Text( |                                 return Text( | ||||||
|                                   _formatBytes(snapshot.data!), |                                   _formatBytes(snapshot.data!), | ||||||
|                                   style: Theme.of(context).textTheme.bodySmall, |                                   style: Theme.of(context).textTheme.bodySmall, | ||||||
|   | |||||||
| @@ -131,7 +131,7 @@ class DailySignHistoryChartDialog extends StatelessWidget { | |||||||
|                             reservedSize: 28, |                             reservedSize: 28, | ||||||
|                             interval: 86400000, |                             interval: 86400000, | ||||||
|                             getTitlesWidget: (value, _) => Text( |                             getTitlesWidget: (value, _) => Text( | ||||||
|                               DateFormat('MM/dd').format( |                               DateFormat('dd').format( | ||||||
|                                 DateTime.fromMillisecondsSinceEpoch( |                                 DateTime.fromMillisecondsSinceEpoch( | ||||||
|                                   value.toInt(), |                                   value.toInt(), | ||||||
|                                 ), |                                 ), | ||||||
| @@ -231,7 +231,7 @@ class DailySignHistoryChartDialog extends StatelessWidget { | |||||||
|                             reservedSize: 28, |                             reservedSize: 28, | ||||||
|                             interval: 86400000, |                             interval: 86400000, | ||||||
|                             getTitlesWidget: (value, _) => Text( |                             getTitlesWidget: (value, _) => Text( | ||||||
|                               DateFormat('MM/dd').format( |                               DateFormat('dd').format( | ||||||
|                                 DateTime.fromMillisecondsSinceEpoch( |                                 DateTime.fromMillisecondsSinceEpoch( | ||||||
|                                   value.toInt(), |                                   value.toInt(), | ||||||
|                                 ), |                                 ), | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user