🐛 Bug fixes

This commit is contained in:
LittleSheep 2024-09-22 22:56:28 +08:00
parent 6cde218393
commit 4b921602a2
8 changed files with 446 additions and 412 deletions

View File

@ -433,6 +433,7 @@
"updateCheckStrictly": "Strict mode", "updateCheckStrictly": "Strict mode",
"updateCheckStrictlyDesc": "If enabled, the app will ask for updating once the local version is different from remote one.", "updateCheckStrictlyDesc": "If enabled, the app will ask for updating once the local version is different from remote one.",
"updateMayAvailable": "App version @version is available, you can update from app store or our website.", "updateMayAvailable": "App version @version is available, you can update from app store or our website.",
"updateNow": "Update now",
"termAccept": "I've read and agree to Solar Network's Terms", "termAccept": "I've read and agree to Solar Network's Terms",
"termAcceptDesc": "Including but not limited to \"User Agreement\" and \"Privacy Policy\"", "termAcceptDesc": "Including but not limited to \"User Agreement\" and \"Privacy Policy\"",
"termAcceptLink": "View terms", "termAcceptLink": "View terms",

View File

@ -428,6 +428,7 @@
"update": "更新", "update": "更新",
"updateCheckStrictly": "严格模式", "updateCheckStrictly": "严格模式",
"updateCheckStrictlyDesc": "如果启用,应用程序将会在本地版本与远程版本不同时询问更新,而不会检查版本号大小。", "updateCheckStrictlyDesc": "如果启用,应用程序将会在本地版本与远程版本不同时询问更新,而不会检查版本号大小。",
"updateNow": "立即更新",
"updateMayAvailable": "版本 @version 现已可用,你可以前往应用商店或是我们的官网下载更新。", "updateMayAvailable": "版本 @version 现已可用,你可以前往应用商店或是我们的官网下载更新。",
"termAccept": "我已阅读并同意 Solar Network 各项条款", "termAccept": "我已阅读并同意 Solar Network 各项条款",
"termAcceptDesc": "包括但不限于《用户守则》和《隐私政策》", "termAcceptDesc": "包括但不限于《用户守则》和《隐私政策》",

View File

@ -42,6 +42,28 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
final Completer _bootCompleter = Completer(); final Completer _bootCompleter = Completer();
void _updateNow(String localVersionString, String remoteVersionString) {
context
.showConfirmDialog(
'updateAvailable'.tr,
'updateAvailableDesc'.trParams({
'from': localVersionString,
'to': remoteVersionString,
}),
)
.then((result) {
if (result) {
final model = UpdateModel(
'https://files.solsynth.dev/d/production01/solian/app-arm64-v8a-release.apk',
'solian-app-arm64-v8a-release.apk',
'ic_launcher',
'https://testflight.apple.com/join/YJ0lmN6O',
);
AzhonAppUpdate.update(model);
}
});
}
Future<void> _checkForUpdate() async { Future<void> _checkForUpdate() async {
if (PlatformInfo.isWeb) return; if (PlatformInfo.isWeb) return;
try { try {
@ -70,25 +92,7 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
remoteBuildNumber > localBuildNumber) || remoteBuildNumber > localBuildNumber) ||
(remoteVersionString != localVersionString && strictUpdate)) { (remoteVersionString != localVersionString && strictUpdate)) {
if (PlatformInfo.isAndroid) { if (PlatformInfo.isAndroid) {
context _updateNow(localVersionString, remoteVersionString);
.showConfirmDialog(
'updateAvailable'.tr,
'updateAvailableDesc'.trParams({
'from': localVersionString,
'to': remoteVersionString,
}),
)
.then((result) {
if (result) {
final model = UpdateModel(
'https://files.solsynth.dev/d/production01/solian/app-arm64-v8a-release.apk',
'solian-app-arm64-v8a-release.apk',
'ic_launcher',
'https://testflight.apple.com/join/YJ0lmN6O',
);
AzhonAppUpdate.update(model);
}
});
} else { } else {
context.showInfoDialog( context.showInfoDialog(
'updateAvailable'.tr, 'updateAvailable'.tr,
@ -97,9 +101,19 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
} }
} else if (remoteVersionString != localVersionString) { } else if (remoteVersionString != localVersionString) {
_bootCompleter.future.then((_) { _bootCompleter.future.then((_) {
context.showSnackbar('updateMayAvailable'.trParams({ context.showSnackbar(
'version': remoteVersionString, 'updateMayAvailable'.trParams({
})); 'version': remoteVersionString,
}),
action: PlatformInfo.isAndroid
? SnackBarAction(
label: 'updateNow'.tr,
onPressed: () {
_updateNow(localVersionString, remoteVersionString);
},
)
: null,
);
}); });
} }
} catch (e) { } catch (e) {

View File

@ -193,96 +193,99 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
toolbarHeight: AppTheme.toolbarHeight(context), toolbarHeight: AppTheme.toolbarHeight(context),
leadingWidth: 24, leadingWidth: 24,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
flexibleSpace: Row( flexibleSpace: SizedBox(
children: [ height: 56,
AppBarLeadingButton.adaptive(context) ?? const Gap(8), child: Row(
const Gap(8), children: [
if (_userinfo != null) AppBarLeadingButton.adaptive(context) ?? const Gap(8),
AccountAvatar(content: _userinfo!.avatar, radius: 16), const Gap(8),
const Gap(12), if (_userinfo != null)
Expanded( AccountAvatar(content: _userinfo!.avatar, radius: 16),
child: Column( const Gap(12),
mainAxisAlignment: MainAxisAlignment.center, Expanded(
crossAxisAlignment: CrossAxisAlignment.start, child: Column(
children: [ mainAxisAlignment: MainAxisAlignment.center,
if (_userinfo != null) crossAxisAlignment: CrossAxisAlignment.start,
Text( children: [
_userinfo!.nick, if (_userinfo != null)
style: Theme.of(context).textTheme.bodyLarge, Text(
), _userinfo!.nick,
if (_userinfo != null) style: Theme.of(context).textTheme.bodyLarge,
Text( ),
'@${_userinfo!.name}', if (_userinfo != null)
style: Theme.of(context).textTheme.bodySmall, Text(
), '@${_userinfo!.name}',
], style: Theme.of(context).textTheme.bodySmall,
), ),
), ],
if (_userinfo != null && _subscription == null)
OutlinedButton(
style: const ButtonStyle(
visualDensity:
VisualDensity(horizontal: -4, vertical: -2),
), ),
onPressed: _isSubscribing ),
? null if (_userinfo != null && _subscription == null)
: () async { OutlinedButton(
setState(() => _isSubscribing = true); style: const ButtonStyle(
_subscription = visualDensity:
await Get.find<SubscriptionProvider>() VisualDensity(horizontal: -4, vertical: -2),
.subscribeToUser(_userinfo!.id); ),
setState(() => _isSubscribing = false); onPressed: _isSubscribing
}, ? null
child: Text('subscribe'.tr), : () async {
) setState(() => _isSubscribing = true);
else if (_userinfo != null) _subscription =
OutlinedButton( await Get.find<SubscriptionProvider>()
style: const ButtonStyle( .subscribeToUser(_userinfo!.id);
visualDensity: setState(() => _isSubscribing = false);
VisualDensity(horizontal: -4, vertical: -2), },
child: Text('subscribe'.tr),
)
else if (_userinfo != null)
OutlinedButton(
style: const ButtonStyle(
visualDensity:
VisualDensity(horizontal: -4, vertical: -2),
),
onPressed: _isSubscribing
? null
: () async {
setState(() => _isSubscribing = true);
await Get.find<SubscriptionProvider>()
.unsubscribeFromUser(_userinfo!.id);
_subscription = null;
setState(() => _isSubscribing = false);
},
child: Text('unsubscribe'.tr),
), ),
onPressed: _isSubscribing if (_userinfo != null &&
? null !_relationshipProvider.hasFriend(_userinfo!))
: () async { IconButton(
setState(() => _isSubscribing = true); icon: const Icon(Icons.person_add),
await Get.find<SubscriptionProvider>() onPressed: _isMakingFriend
.unsubscribeFromUser(_userinfo!.id); ? null
_subscription = null; : () async {
setState(() => _isSubscribing = false); setState(() => _isMakingFriend = true);
}, try {
child: Text('unsubscribe'.tr), await _relationshipProvider
.makeFriend(widget.name);
context.showSnackbar(
'accountFriendRequestSent'.tr,
);
} catch (e) {
context.showErrorDialog(e);
} finally {
setState(() => _isMakingFriend = false);
}
},
)
else
const IconButton(
icon: Icon(Icons.handshake),
onPressed: null,
),
SizedBox(
width: AppTheme.isLargeScreen(context) ? 8 : 16,
), ),
if (_userinfo != null && ],
!_relationshipProvider.hasFriend(_userinfo!)) ),
IconButton( ).paddingOnly(top: MediaQuery.of(context).padding.top),
icon: const Icon(Icons.person_add),
onPressed: _isMakingFriend
? null
: () async {
setState(() => _isMakingFriend = true);
try {
await _relationshipProvider
.makeFriend(widget.name);
context.showSnackbar(
'accountFriendRequestSent'.tr,
);
} catch (e) {
context.showErrorDialog(e);
} finally {
setState(() => _isMakingFriend = false);
}
},
)
else
const IconButton(
icon: Icon(Icons.handshake),
onPressed: null,
),
SizedBox(
width: AppTheme.isLargeScreen(context) ? 8 : 16,
),
],
),
bottom: TabBar( bottom: TabBar(
tabs: [ tabs: [
Tab(text: 'profilePage'.tr), Tab(text: 'profilePage'.tr),
@ -296,128 +299,132 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
body: TabBarView( body: TabBarView(
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
children: [ children: [
Column( ListView(
children: [ children: [
const Gap(16), const Gap(16),
AccountHeadingWidget( CenteredContainer(
name: _userinfo!.name, child: AccountHeadingWidget(
nick: _userinfo!.nick, name: _userinfo!.name,
desc: _userinfo!.description, nick: _userinfo!.nick,
badges: _userinfo!.badges, desc: _userinfo!.description,
banner: _userinfo!.banner, badges: _userinfo!.badges,
avatar: _userinfo!.avatar, banner: _userinfo!.banner,
status: Get.find<StatusProvider>() avatar: _userinfo!.avatar,
.getSomeoneStatus(_userinfo!.name), status: Get.find<StatusProvider>()
detail: _userinfo, .getSomeoneStatus(_userinfo!.name),
profile: _userinfo!.profile, detail: _userinfo,
extraWidgets: [ profile: _userinfo!.profile,
if (_dailySignRecords.isNotEmpty) extraWidgets: [
Card( if (_dailySignRecords.isNotEmpty)
child: SizedBox( Card(
height: 180, child: SizedBox(
width: max(640, MediaQuery.of(context).size.width), height: 180,
child: LineChart( width:
LineChartData( max(640, MediaQuery.of(context).size.width),
lineBarsData: [ child: LineChart(
LineChartBarData( LineChartData(
isCurved: true, lineBarsData: [
isStrokeCapRound: true, LineChartBarData(
isStrokeJoinRound: true, isCurved: true,
color: isStrokeCapRound: true,
Theme.of(context).colorScheme.primary, isStrokeJoinRound: true,
belowBarData: BarAreaData( color:
show: true, Theme.of(context).colorScheme.primary,
gradient: LinearGradient( belowBarData: BarAreaData(
colors: List.filled( show: true,
_dailySignRecords.length, gradient: LinearGradient(
Theme.of(context) colors: List.filled(
.colorScheme _dailySignRecords.length,
.primary Theme.of(context)
.withOpacity(0.3), .colorScheme
).toList(), .primary
), .withOpacity(0.3),
), ).toList(),
spots: _dailySignRecords
.map(
(x) => FlSpot(
x.createdAt
.copyWith(
hour: 0,
minute: 0,
second: 0,
millisecond: 0,
microsecond: 0,
)
.millisecondsSinceEpoch
.toDouble(),
x.resultTier.toDouble(),
),
)
.toList(),
)
],
lineTouchData: LineTouchData(
touchTooltipData: LineTouchTooltipData(
getTooltipItems: (spots) => spots
.map((spot) => LineTooltipItem(
'${DailySignHistoryChartDialog.signSymbols[spot.y.toInt()]}\n${DateFormat('MM/dd').format(DateTime.fromMillisecondsSinceEpoch(spot.x.toInt()))}',
TextStyle(
color: Theme.of(context)
.colorScheme
.onSurface,
),
))
.toList(),
getTooltipColor: (_) => Theme.of(context)
.colorScheme
.surfaceContainerHigh,
),
),
titlesData: FlTitlesData(
topTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
rightTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 40,
interval: 1,
getTitlesWidget: (value, _) => Align(
alignment: Alignment.centerRight,
child: Text(
DailySignHistoryChartDialog
.signSymbols[value.toInt()],
textAlign: TextAlign.right,
).paddingOnly(right: 8),
),
),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 28,
interval: 86400000,
getTitlesWidget: (value, _) => Text(
DateFormat('dd').format(
DateTime.fromMillisecondsSinceEpoch(
value.toInt(),
),
), ),
textAlign: TextAlign.center, ),
).paddingOnly(top: 8), spots: _dailySignRecords
.map(
(x) => FlSpot(
x.createdAt
.copyWith(
hour: 0,
minute: 0,
second: 0,
millisecond: 0,
microsecond: 0,
)
.millisecondsSinceEpoch
.toDouble(),
x.resultTier.toDouble(),
),
)
.toList(),
)
],
lineTouchData: LineTouchData(
touchTooltipData: LineTouchTooltipData(
getTooltipItems: (spots) => spots
.map((spot) => LineTooltipItem(
'${DailySignHistoryChartDialog.signSymbols[spot.y.toInt()]}\n${DateFormat('MM/dd').format(DateTime.fromMillisecondsSinceEpoch(spot.x.toInt()))}',
TextStyle(
color: Theme.of(context)
.colorScheme
.onSurface,
),
))
.toList(),
getTooltipColor: (_) => Theme.of(context)
.colorScheme
.surfaceContainerHigh,
), ),
), ),
titlesData: FlTitlesData(
topTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
rightTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 40,
interval: 1,
getTitlesWidget: (value, _) => Align(
alignment: Alignment.centerRight,
child: Text(
DailySignHistoryChartDialog
.signSymbols[value.toInt()],
textAlign: TextAlign.right,
).paddingOnly(right: 8),
),
),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 28,
interval: 86400000,
getTitlesWidget: (value, _) => Text(
DateFormat('dd').format(
DateTime.fromMillisecondsSinceEpoch(
value.toInt(),
),
),
textAlign: TextAlign.center,
).paddingOnly(top: 8),
),
),
),
gridData: const FlGridData(show: false),
borderData: FlBorderData(show: false),
), ),
gridData: const FlGridData(show: false),
borderData: FlBorderData(show: false),
), ),
), ).marginOnly(
).marginOnly(right: 24, left: 12, bottom: 8, top: 24), right: 24, left: 12, bottom: 8, top: 24),
) )
], ],
),
), ),
], ],
), ),

View File

@ -21,6 +21,7 @@ class AttachmentItem extends StatefulWidget {
final bool showBadge; final bool showBadge;
final bool showHideButton; final bool showHideButton;
final bool autoload; final bool autoload;
final bool isDense;
final BoxFit fit; final BoxFit fit;
final String? badge; final String? badge;
final Function? onHide; final Function? onHide;
@ -34,6 +35,7 @@ class AttachmentItem extends StatefulWidget {
this.showBadge = true, this.showBadge = true,
this.showHideButton = true, this.showHideButton = true,
this.autoload = false, this.autoload = false,
this.isDense = false,
this.onHide, this.onHide,
}); });
@ -53,6 +55,7 @@ class _AttachmentItemState extends State<AttachmentItem> {
fit: widget.fit, fit: widget.fit,
showBadge: widget.showBadge, showBadge: widget.showBadge,
showHideButton: widget.showHideButton, showHideButton: widget.showHideButton,
isDense: widget.isDense,
onHide: widget.onHide, onHide: widget.onHide,
); );
case 'video': case 'video':
@ -120,6 +123,7 @@ class _AttachmentItemImage extends StatelessWidget {
final bool showBadge; final bool showBadge;
final bool showHideButton; final bool showHideButton;
final BoxFit fit; final BoxFit fit;
final bool isDense;
final String? badge; final String? badge;
final Function? onHide; final Function? onHide;
@ -128,6 +132,7 @@ class _AttachmentItemImage extends StatelessWidget {
required this.item, required this.item,
required this.showBadge, required this.showBadge,
required this.showHideButton, required this.showHideButton,
required this.isDense,
required this.fit, required this.fit,
this.badge, this.badge,
this.onHide, this.onHide,
@ -146,6 +151,7 @@ class _AttachmentItemImage extends StatelessWidget {
'/attachments/${item.rid}', '/attachments/${item.rid}',
), ),
fit: fit, fit: fit,
isDense: isDense,
), ),
if (showBadge && badge != null) if (showBadge && badge != null)
Positioned( Positioned(

View File

@ -338,6 +338,7 @@ class AttachmentListEntry extends StatelessWidget {
badge: showBadge ? badgeContent : null, badge: showBadge ? badgeContent : null,
showHideButton: !item!.isMature || showMature, showHideButton: !item!.isMature || showMature,
autoload: autoload, autoload: autoload,
isDense: isDense,
onHide: () { onHide: () {
onReveal(false); onReveal(false);
}, },

View File

@ -42,61 +42,168 @@ class DailySignHistoryChartDialog extends StatelessWidget {
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
), ),
) )
: Column( : SizedBox(
mainAxisSize: MainAxisSize.min, width: double.maxFinite,
crossAxisAlignment: CrossAxisAlignment.start, child: ListView(
children: [ shrinkWrap: true,
Text( children: [
'dailySignHistoryRecent'.tr, Text(
style: Theme.of(context).textTheme.titleMedium, 'dailySignHistoryRecent'.tr,
).paddingOnly(bottom: 18), style: Theme.of(context).textTheme.titleMedium,
SizedBox( ).paddingOnly(bottom: 18),
height: 180, SizedBox(
width: max(640, MediaQuery.of(context).size.width), height: 180,
child: LineChart( width: max(640, MediaQuery.of(context).size.width),
LineChartData( child: LineChart(
lineBarsData: [ LineChartData(
LineChartBarData( lineBarsData: [
isCurved: true, LineChartBarData(
isStrokeCapRound: true, isCurved: true,
isStrokeJoinRound: true, isStrokeCapRound: true,
color: Theme.of(context).colorScheme.primary, isStrokeJoinRound: true,
belowBarData: BarAreaData( color: Theme.of(context).colorScheme.primary,
show: true, belowBarData: BarAreaData(
gradient: LinearGradient( show: true,
colors: List.filled( gradient: LinearGradient(
data!.length, colors: List.filled(
Theme.of(context) data!.length,
.colorScheme Theme.of(context)
.primary .colorScheme
.withOpacity(0.3), .primary
).toList(), .withOpacity(0.3),
).toList(),
),
),
spots: data!
.map(
(x) => FlSpot(
x.createdAt
.copyWith(
hour: 0,
minute: 0,
second: 0,
millisecond: 0,
microsecond: 0,
)
.millisecondsSinceEpoch
.toDouble(),
x.resultTier.toDouble(),
),
)
.toList(),
)
],
lineTouchData: LineTouchData(
touchTooltipData: LineTouchTooltipData(
getTooltipItems: (spots) => spots
.map((spot) => LineTooltipItem(
'${signSymbols[spot.y.toInt()]}\n${DateFormat('MM/dd').format(DateTime.fromMillisecondsSinceEpoch(spot.x.toInt()))}',
TextStyle(
color: Theme.of(context)
.colorScheme
.onSurface,
),
))
.toList(),
getTooltipColor: (_) => Theme.of(context)
.colorScheme
.surfaceContainerHigh,
),
),
titlesData: FlTitlesData(
topTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
rightTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 40,
interval: 1,
getTitlesWidget: (value, _) => Align(
alignment: Alignment.centerRight,
child: Text(
signSymbols[value.toInt()],
textAlign: TextAlign.right,
).paddingOnly(right: 8),
),
), ),
), ),
spots: data! bottomTitles: AxisTitles(
.map( sideTitles: SideTitles(
(x) => FlSpot( showTitles: true,
x.createdAt reservedSize: 28,
.copyWith( interval: 86400000,
hour: 0, getTitlesWidget: (value, _) => Text(
minute: 0, DateFormat('dd').format(
second: 0, DateTime.fromMillisecondsSinceEpoch(
millisecond: 0, value.toInt(),
microsecond: 0, ),
)
.millisecondsSinceEpoch
.toDouble(),
x.resultTier.toDouble(),
), ),
) textAlign: TextAlign.center,
.toList(), ).paddingOnly(top: 8),
) ),
], ),
lineTouchData: LineTouchData( ),
touchTooltipData: LineTouchTooltipData( gridData: const FlGridData(show: false),
borderData: FlBorderData(show: false),
),
),
).marginOnly(right: 24, bottom: 8, top: 8),
const Gap(16),
Text(
'dailySignHistoryReward'.tr,
style: Theme.of(context).textTheme.titleMedium,
).paddingOnly(bottom: 18),
SizedBox(
height: 180,
width: max(640, MediaQuery.of(context).size.width),
child: LineChart(
LineChartData(
lineBarsData: [
LineChartBarData(
isCurved: true,
isStrokeCapRound: true,
isStrokeJoinRound: true,
color: Theme.of(context).colorScheme.primary,
belowBarData: BarAreaData(
show: true,
gradient: LinearGradient(
colors: List.filled(
data!.length,
Theme.of(context)
.colorScheme
.primary
.withOpacity(0.3),
).toList(),
),
),
spots: data!
.map(
(x) => FlSpot(
x.createdAt
.copyWith(
hour: 0,
minute: 0,
second: 0,
millisecond: 0,
microsecond: 0,
)
.millisecondsSinceEpoch
.toDouble(),
x.resultExperience.toDouble(),
),
)
.toList(),
)
],
lineTouchData: LineTouchData(
touchTooltipData: LineTouchTooltipData(
getTooltipItems: (spots) => spots getTooltipItems: (spots) => spots
.map((spot) => LineTooltipItem( .map((spot) => LineTooltipItem(
'${signSymbols[spot.y.toInt()]}\n${DateFormat('MM/dd').format(DateTime.fromMillisecondsSinceEpoch(spot.x.toInt()))}', '+${spot.y.toStringAsFixed(0)} EXP\n${DateFormat('MM/dd').format(DateTime.fromMillisecondsSinceEpoch(spot.x.toInt()))}',
TextStyle( TextStyle(
color: Theme.of(context) color: Theme.of(context)
.colorScheme .colorScheme
@ -107,153 +214,50 @@ class DailySignHistoryChartDialog extends StatelessWidget {
getTooltipColor: (_) => Theme.of(context) getTooltipColor: (_) => Theme.of(context)
.colorScheme .colorScheme
.surfaceContainerHigh, .surfaceContainerHigh,
), )),
), titlesData: FlTitlesData(
titlesData: FlTitlesData( topTitles: const AxisTitles(
topTitles: const AxisTitles( sideTitles: SideTitles(showTitles: false),
sideTitles: SideTitles(showTitles: false),
),
rightTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 40,
interval: 1,
getTitlesWidget: (value, _) => Align(
alignment: Alignment.centerRight,
child: Text(
signSymbols[value.toInt()],
textAlign: TextAlign.right,
).paddingOnly(right: 8),
),
), ),
), rightTitles: const AxisTitles(
bottomTitles: AxisTitles( sideTitles: SideTitles(showTitles: false),
sideTitles: SideTitles( ),
showTitles: true, leftTitles: AxisTitles(
reservedSize: 28, sideTitles: SideTitles(
interval: 86400000, showTitles: true,
getTitlesWidget: (value, _) => Text( reservedSize: 40,
DateFormat('dd').format( getTitlesWidget: (value, _) => Align(
DateTime.fromMillisecondsSinceEpoch( alignment: Alignment.centerRight,
value.toInt(), child: Text(
), value.toStringAsFixed(0),
textAlign: TextAlign.right,
).paddingOnly(right: 8),
), ),
textAlign: TextAlign.center,
).paddingOnly(top: 8),
),
),
),
gridData: const FlGridData(show: false),
borderData: FlBorderData(show: false),
),
),
).marginOnly(right: 24, bottom: 8, top: 8),
const Gap(16),
Text(
'dailySignHistoryReward'.tr,
style: Theme.of(context).textTheme.titleMedium,
).paddingOnly(bottom: 18),
SizedBox(
height: 180,
width: max(640, MediaQuery.of(context).size.width),
child: LineChart(
LineChartData(
lineBarsData: [
LineChartBarData(
isCurved: true,
isStrokeCapRound: true,
isStrokeJoinRound: true,
color: Theme.of(context).colorScheme.primary,
belowBarData: BarAreaData(
show: true,
gradient: LinearGradient(
colors: List.filled(
data!.length,
Theme.of(context)
.colorScheme
.primary
.withOpacity(0.3),
).toList(),
), ),
), ),
spots: data! bottomTitles: AxisTitles(
.map( sideTitles: SideTitles(
(x) => FlSpot( showTitles: true,
x.createdAt reservedSize: 28,
.copyWith( interval: 86400000,
hour: 0, getTitlesWidget: (value, _) => Text(
minute: 0, DateFormat('dd').format(
second: 0, DateTime.fromMillisecondsSinceEpoch(
millisecond: 0, value.toInt(),
microsecond: 0,
)
.millisecondsSinceEpoch
.toDouble(),
x.resultExperience.toDouble(),
),
)
.toList(),
)
],
lineTouchData: LineTouchData(
touchTooltipData: LineTouchTooltipData(
getTooltipItems: (spots) => spots
.map((spot) => LineTooltipItem(
'+${spot.y.toStringAsFixed(0)} EXP\n${DateFormat('MM/dd').format(DateTime.fromMillisecondsSinceEpoch(spot.x.toInt()))}',
TextStyle(
color:
Theme.of(context).colorScheme.onSurface,
), ),
)) ),
.toList(), textAlign: TextAlign.center,
getTooltipColor: (_) => ).paddingOnly(top: 8),
Theme.of(context).colorScheme.surfaceContainerHigh,
)),
titlesData: FlTitlesData(
topTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
rightTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 40,
getTitlesWidget: (value, _) => Align(
alignment: Alignment.centerRight,
child: Text(
value.toStringAsFixed(0),
textAlign: TextAlign.right,
).paddingOnly(right: 8),
), ),
), ),
), ),
bottomTitles: AxisTitles( gridData: const FlGridData(show: false),
sideTitles: SideTitles( borderData: FlBorderData(show: false),
showTitles: true,
reservedSize: 28,
interval: 86400000,
getTitlesWidget: (value, _) => Text(
DateFormat('dd').format(
DateTime.fromMillisecondsSinceEpoch(
value.toInt(),
),
),
textAlign: TextAlign.center,
).paddingOnly(top: 8),
),
),
), ),
gridData: const FlGridData(show: false),
borderData: FlBorderData(show: false),
), ),
), ).marginOnly(right: 24, bottom: 8, top: 8),
).marginOnly(right: 24, bottom: 8, top: 8), ],
], ),
), ),
); );
} }

View File

@ -2,7 +2,7 @@ name: solian
description: "The Solar Network App" description: "The Solar Network App"
publish_to: "none" publish_to: "none"
version: 1.2.2+3 version: 1.2.3+1
environment: environment:
sdk: ">=3.3.4 <4.0.0" sdk: ">=3.3.4 <4.0.0"