Compare commits
4 Commits
4cbeafd447
...
1.2.3+1
| Author | SHA1 | Date | |
|---|---|---|---|
| de39799301 | |||
| 4b921602a2 | |||
| 6cde218393 | |||
| c896185af0 |
@@ -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",
|
||||||
|
|||||||
@@ -428,6 +428,7 @@
|
|||||||
"update": "更新",
|
"update": "更新",
|
||||||
"updateCheckStrictly": "严格模式",
|
"updateCheckStrictly": "严格模式",
|
||||||
"updateCheckStrictlyDesc": "如果启用,应用程序将会在本地版本与远程版本不同时询问更新,而不会检查版本号大小。",
|
"updateCheckStrictlyDesc": "如果启用,应用程序将会在本地版本与远程版本不同时询问更新,而不会检查版本号大小。",
|
||||||
|
"updateNow": "立即更新",
|
||||||
"updateMayAvailable": "版本 @version 现已可用,你可以前往应用商店或是我们的官网下载更新。",
|
"updateMayAvailable": "版本 @version 现已可用,你可以前往应用商店或是我们的官网下载更新。",
|
||||||
"termAccept": "我已阅读并同意 Solar Network 各项条款",
|
"termAccept": "我已阅读并同意 Solar Network 各项条款",
|
||||||
"termAcceptDesc": "包括但不限于《用户守则》和《隐私政策》",
|
"termAcceptDesc": "包括但不限于《用户守则》和《隐私政策》",
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ PODS:
|
|||||||
- TOCropViewController (~> 2.7.4)
|
- TOCropViewController (~> 2.7.4)
|
||||||
- image_picker_ios (0.0.1):
|
- image_picker_ios (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- livekit_client (2.2.5):
|
- livekit_client (2.2.6):
|
||||||
- Flutter
|
- Flutter
|
||||||
- WebRTC-SDK (= 125.6422.04)
|
- WebRTC-SDK (= 125.6422.04)
|
||||||
- media_kit_libs_ios_video (1.0.4):
|
- media_kit_libs_ios_video (1.0.4):
|
||||||
@@ -482,7 +482,7 @@ SPEC CHECKSUMS:
|
|||||||
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||||
image_cropper: 37d40f62177c101ff4c164906d259ea2c3aa70cf
|
image_cropper: 37d40f62177c101ff4c164906d259ea2c3aa70cf
|
||||||
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
|
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
|
||||||
livekit_client: 9c8080879256a0fb16da13c9be4845248209d896
|
livekit_client: 20e01637431bc108dad451c8a11c1d206e1dd2cd
|
||||||
media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1
|
media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1
|
||||||
media_kit_native_event_loop: e6b2ab20cf0746eb1c33be961fcf79667304fa2a
|
media_kit_native_event_loop: e6b2ab20cf0746eb1c33be961fcf79667304fa2a
|
||||||
media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e
|
media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:fl_chart/fl_chart.dart';
|
||||||
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:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
import 'package:solian/controllers/post_list_controller.dart';
|
import 'package:solian/controllers/post_list_controller.dart';
|
||||||
import 'package:solian/exts.dart';
|
import 'package:solian/exts.dart';
|
||||||
import 'package:solian/models/account.dart';
|
import 'package:solian/models/account.dart';
|
||||||
import 'package:solian/models/attachment.dart';
|
import 'package:solian/models/attachment.dart';
|
||||||
|
import 'package:solian/models/daily_sign.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/models/subscription.dart';
|
import 'package:solian/models/subscription.dart';
|
||||||
@@ -18,6 +23,7 @@ import 'package:solian/widgets/account/account_avatar.dart';
|
|||||||
import 'package:solian/widgets/account/account_heading.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/daily_sign/history_chart.dart';
|
||||||
import 'package:solian/widgets/posts/post_list.dart';
|
import 'package:solian/widgets/posts/post_list.dart';
|
||||||
import 'package:solian/widgets/posts/post_warped_list.dart';
|
import 'package:solian/widgets/posts/post_warped_list.dart';
|
||||||
import 'package:solian/widgets/sized_container.dart';
|
import 'package:solian/widgets/sized_container.dart';
|
||||||
@@ -45,6 +51,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
|||||||
Account? _userinfo;
|
Account? _userinfo;
|
||||||
Subscription? _subscription;
|
Subscription? _subscription;
|
||||||
List<Post> _pinnedPosts = List.empty();
|
List<Post> _pinnedPosts = List.empty();
|
||||||
|
List<DailySignRecord> _dailySignRecords = List.empty();
|
||||||
int _totalUpvote = 0, _totalDownvote = 0;
|
int _totalUpvote = 0, _totalDownvote = 0;
|
||||||
|
|
||||||
Future<void> _getSubscription() async {
|
Future<void> _getSubscription() async {
|
||||||
@@ -57,7 +64,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
|||||||
Future<void> _getUserinfo() async {
|
Future<void> _getUserinfo() async {
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
var client = await ServiceFinder.configureClient('auth');
|
var client = await ServiceFinder.configureClient('id');
|
||||||
var resp = await client.get('/users/${widget.name}');
|
var resp = await client.get('/users/${widget.name}');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
context.showErrorDialog(resp.bodyString).then((_) {
|
context.showErrorDialog(resp.bodyString).then((_) {
|
||||||
@@ -67,7 +74,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
|||||||
_userinfo = Account.fromJson(resp.body);
|
_userinfo = Account.fromJson(resp.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
client = await ServiceFinder.configureClient('interactive');
|
client = await ServiceFinder.configureClient('co');
|
||||||
resp = await client.get('/users/${widget.name}');
|
resp = await client.get('/users/${widget.name}');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
context.showErrorDialog(resp.bodyString).then((_) {
|
context.showErrorDialog(resp.bodyString).then((_) {
|
||||||
@@ -82,7 +89,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _getPinnedPosts() async {
|
Future<void> _getPinnedPosts() async {
|
||||||
final client = await ServiceFinder.configureClient('interactive');
|
final client = await ServiceFinder.configureClient('co');
|
||||||
final resp = await client.get('/users/${widget.name}/pin');
|
final resp = await client.get('/users/${widget.name}/pin');
|
||||||
if (resp.statusCode != 200) {
|
if (resp.statusCode != 200) {
|
||||||
context.showErrorDialog(resp.bodyString).then((_) {
|
context.showErrorDialog(resp.bodyString).then((_) {
|
||||||
@@ -96,6 +103,23 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _getDailySignRecords() async {
|
||||||
|
final client = await ServiceFinder.configureClient('id');
|
||||||
|
final resp = await client.get('/users/${widget.name}/daily?take=14');
|
||||||
|
if (resp.statusCode != 200) {
|
||||||
|
context.showErrorDialog(resp.bodyString).then((_) {
|
||||||
|
Navigator.pop(context);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
final result = PaginationResult.fromJson(resp.body);
|
||||||
|
setState(() {
|
||||||
|
_dailySignRecords = List.from(
|
||||||
|
result.data?.map((x) => DailySignRecord.fromJson(x)) ?? [],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int get _userSocialCreditPoints {
|
int get _userSocialCreditPoints {
|
||||||
return _totalUpvote * 2 - _totalDownvote + _postController.postTotal.value;
|
return _totalUpvote * 2 - _totalDownvote + _postController.postTotal.value;
|
||||||
}
|
}
|
||||||
@@ -129,6 +153,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
|||||||
_getUserinfo().then((_) {
|
_getUserinfo().then((_) {
|
||||||
_getSubscription();
|
_getSubscription();
|
||||||
_getPinnedPosts();
|
_getPinnedPosts();
|
||||||
|
_getDailySignRecords();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,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),
|
||||||
@@ -271,21 +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: const [],
|
profile: _userinfo!.profile,
|
||||||
|
extraWidgets: [
|
||||||
|
if (_dailySignRecords.isNotEmpty)
|
||||||
|
Card(
|
||||||
|
child: 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(
|
||||||
|
_dailySignRecords.length,
|
||||||
|
Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.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),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
gridData: const FlGridData(show: false),
|
||||||
|
borderData: FlBorderData(show: false),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
).marginOnly(
|
||||||
|
right: 24, left: 12, bottom: 8, top: 24),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -373,8 +512,9 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
|||||||
),
|
),
|
||||||
CenteredContainer(
|
CenteredContainer(
|
||||||
child: RefreshIndicator(
|
child: RefreshIndicator(
|
||||||
onRefresh: () =>
|
onRefresh: () => Future.sync(
|
||||||
Future.sync(() => _albumPagingController.refresh()),
|
() => _albumPagingController.refresh(),
|
||||||
|
),
|
||||||
child: PagedGridView<int, Attachment>(
|
child: PagedGridView<int, Attachment>(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
pagingController: _albumPagingController,
|
pagingController: _albumPagingController,
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
|||||||
Future<void> _pullDaily() async {
|
Future<void> _pullDaily() async {
|
||||||
try {
|
try {
|
||||||
_signRecord = await _dailySign.getToday();
|
_signRecord = await _dailySign.getToday();
|
||||||
_dailySign.listLastRecord(30).then((value) {
|
_dailySign.listLastRecord(14).then((value) {
|
||||||
setState(() => _signRecordHistory = value);
|
setState(() => _signRecordHistory = value);
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -103,7 +103,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
_signRecord = await _dailySign.signToday();
|
_signRecord = await _dailySign.signToday();
|
||||||
_dailySign.listLastRecord(30).then((value) {
|
_dailySign.listLastRecord(14).then((value) {
|
||||||
setState(() => _signRecordHistory = value);
|
setState(() => _signRecordHistory = value);
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class DailySignHistoryChartDialog extends StatelessWidget {
|
|||||||
|
|
||||||
const DailySignHistoryChartDialog({super.key, required this.data});
|
const DailySignHistoryChartDialog({super.key, required this.data});
|
||||||
|
|
||||||
static List<String> signSymbols = ['大凶', '凶', '中平', '吉', '大吉'];
|
static final List<String> signSymbols = ['大凶', '凶', '中平', '吉', '大吉'];
|
||||||
|
|
||||||
DateTime? get _firstRecordDate => data?.map((x) => x.createdAt).reduce(
|
DateTime? get _firstRecordDate => data?.map((x) => x.createdAt).reduce(
|
||||||
(a, b) => DateTime.fromMillisecondsSinceEpoch(
|
(a, b) => DateTime.fromMillisecondsSinceEpoch(
|
||||||
@@ -42,215 +42,222 @@ 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),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
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),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
).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!
|
||||||
spots: data!
|
.map(
|
||||||
.map(
|
(x) => FlSpot(
|
||||||
(x) => FlSpot(
|
x.createdAt
|
||||||
x.createdAt
|
.copyWith(
|
||||||
.copyWith(
|
hour: 0,
|
||||||
hour: 0,
|
minute: 0,
|
||||||
minute: 0,
|
second: 0,
|
||||||
second: 0,
|
millisecond: 0,
|
||||||
millisecond: 0,
|
microsecond: 0,
|
||||||
microsecond: 0,
|
)
|
||||||
)
|
.millisecondsSinceEpoch
|
||||||
.millisecondsSinceEpoch
|
.toDouble(),
|
||||||
.toDouble(),
|
x.resultTier.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(),
|
.toList(),
|
||||||
getTooltipColor: (_) =>
|
)
|
||||||
Theme.of(context).colorScheme.surfaceContainerHigh,
|
],
|
||||||
)),
|
lineTouchData: LineTouchData(
|
||||||
titlesData: FlTitlesData(
|
touchTooltipData: LineTouchTooltipData(
|
||||||
topTitles: const AxisTitles(
|
getTooltipItems: (spots) => spots
|
||||||
sideTitles: SideTitles(showTitles: false),
|
.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,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
rightTitles: const AxisTitles(
|
titlesData: FlTitlesData(
|
||||||
sideTitles: SideTitles(showTitles: false),
|
topTitles: const AxisTitles(
|
||||||
),
|
sideTitles: SideTitles(showTitles: false),
|
||||||
leftTitles: AxisTitles(
|
),
|
||||||
sideTitles: SideTitles(
|
rightTitles: const AxisTitles(
|
||||||
showTitles: true,
|
sideTitles: SideTitles(showTitles: false),
|
||||||
reservedSize: 40,
|
),
|
||||||
getTitlesWidget: (value, _) => Align(
|
leftTitles: AxisTitles(
|
||||||
alignment: Alignment.centerRight,
|
sideTitles: SideTitles(
|
||||||
child: Text(
|
showTitles: true,
|
||||||
value.toStringAsFixed(0),
|
reservedSize: 40,
|
||||||
textAlign: TextAlign.right,
|
interval: 1,
|
||||||
).paddingOnly(right: 8),
|
getTitlesWidget: (value, _) => Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: Text(
|
||||||
|
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),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
bottomTitles: AxisTitles(
|
gridData: const FlGridData(show: false),
|
||||||
sideTitles: SideTitles(
|
borderData: FlBorderData(show: false),
|
||||||
showTitles: true,
|
),
|
||||||
reservedSize: 28,
|
),
|
||||||
interval: 86400000,
|
).marginOnly(right: 24, bottom: 8, top: 8),
|
||||||
getTitlesWidget: (value, _) => Text(
|
const Gap(16),
|
||||||
DateFormat('dd').format(
|
Text(
|
||||||
DateTime.fromMillisecondsSinceEpoch(
|
'dailySignHistoryReward'.tr,
|
||||||
value.toInt(),
|
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(),
|
||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
),
|
||||||
).paddingOnly(top: 8),
|
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
|
||||||
|
.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(),
|
||||||
|
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,
|
||||||
|
getTitlesWidget: (value, _) => Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: Text(
|
||||||
|
value.toStringAsFixed(0),
|
||||||
|
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(right: 24, bottom: 8, top: 8),
|
||||||
).marginOnly(right: 24, bottom: 8, top: 8),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ class _PostItemState extends State<PostItem> {
|
|||||||
attachmentsId: attachments,
|
attachmentsId: attachments,
|
||||||
autoload: false,
|
autoload: false,
|
||||||
isColumn: true,
|
isColumn: true,
|
||||||
).paddingOnly(left: 60, right: 24);
|
).paddingOnly(left: 60, right: 24, top: 4, bottom: 4);
|
||||||
} else {
|
} else {
|
||||||
return AttachmentList(
|
return AttachmentList(
|
||||||
flatMaxHeight: MediaQuery.of(context).size.width,
|
flatMaxHeight: MediaQuery.of(context).size.width,
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ PODS:
|
|||||||
- GoogleUtilities/UserDefaults (8.0.2):
|
- GoogleUtilities/UserDefaults (8.0.2):
|
||||||
- GoogleUtilities/Logger
|
- GoogleUtilities/Logger
|
||||||
- GoogleUtilities/Privacy
|
- GoogleUtilities/Privacy
|
||||||
- livekit_client (2.2.5):
|
- livekit_client (2.2.6):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- WebRTC-SDK (= 125.6422.04)
|
- WebRTC-SDK (= 125.6422.04)
|
||||||
- macos_window_utils (1.0.0):
|
- macos_window_utils (1.0.0):
|
||||||
@@ -359,7 +359,7 @@ SPEC CHECKSUMS:
|
|||||||
GoogleAppMeasurement: 6e49ffac7d3f2c3ded9cc663f912a13b67bbd0de
|
GoogleAppMeasurement: 6e49ffac7d3f2c3ded9cc663f912a13b67bbd0de
|
||||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||||
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||||
livekit_client: be04a950a4b84b9dbc87507ffad5154fe75fa067
|
livekit_client: 98d09566e3a936b3402be8091ec3845556d36800
|
||||||
macos_window_utils: 933f91f64805e2eb91a5bd057cf97cd097276663
|
macos_window_utils: 933f91f64805e2eb91a5bd057cf97cd097276663
|
||||||
media_kit_libs_macos_video: b3e2bbec2eef97c285f2b1baa7963c67c753fb82
|
media_kit_libs_macos_video: b3e2bbec2eef97c285f2b1baa7963c67c753fb82
|
||||||
media_kit_native_event_loop: 81fd5b45192b72f8b5b69eaf5b540f45777eb8d5
|
media_kit_native_event_loop: 81fd5b45192b72f8b5b69eaf5b540f45777eb8d5
|
||||||
|
|||||||
@@ -751,10 +751,10 @@ packages:
|
|||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_launcher_icons
|
name: flutter_launcher_icons
|
||||||
sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
|
sha256: a38f2f1b3c373d42bf08bd17d60e20d3c73abce7727607b4d085ec7d5acaa294
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.13.1"
|
version: "0.14.0"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -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"
|
||||||
@@ -89,7 +89,7 @@ dev_dependencies:
|
|||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
flutter_lints: ^4.0.0
|
flutter_lints: ^4.0.0
|
||||||
flutter_launcher_icons: ^0.13.1
|
flutter_launcher_icons: ^0.14.0
|
||||||
|
|
||||||
build_runner: ^2.4.12
|
build_runner: ^2.4.12
|
||||||
flutter_native_splash: ^2.4.1
|
flutter_native_splash: ^2.4.1
|
||||||
|
|||||||
Reference in New Issue
Block a user