Compare commits
4 Commits
4cbeafd447
...
1.2.3+1
| Author | SHA1 | Date | |
|---|---|---|---|
| de39799301 | |||
| 4b921602a2 | |||
| 6cde218393 | |||
| c896185af0 |
@@ -433,6 +433,7 @@
|
||||
"updateCheckStrictly": "Strict mode",
|
||||
"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.",
|
||||
"updateNow": "Update now",
|
||||
"termAccept": "I've read and agree to Solar Network's Terms",
|
||||
"termAcceptDesc": "Including but not limited to \"User Agreement\" and \"Privacy Policy\"",
|
||||
"termAcceptLink": "View terms",
|
||||
|
||||
@@ -428,6 +428,7 @@
|
||||
"update": "更新",
|
||||
"updateCheckStrictly": "严格模式",
|
||||
"updateCheckStrictlyDesc": "如果启用,应用程序将会在本地版本与远程版本不同时询问更新,而不会检查版本号大小。",
|
||||
"updateNow": "立即更新",
|
||||
"updateMayAvailable": "版本 @version 现已可用,你可以前往应用商店或是我们的官网下载更新。",
|
||||
"termAccept": "我已阅读并同意 Solar Network 各项条款",
|
||||
"termAcceptDesc": "包括但不限于《用户守则》和《隐私政策》",
|
||||
|
||||
@@ -227,7 +227,7 @@ PODS:
|
||||
- TOCropViewController (~> 2.7.4)
|
||||
- image_picker_ios (0.0.1):
|
||||
- Flutter
|
||||
- livekit_client (2.2.5):
|
||||
- livekit_client (2.2.6):
|
||||
- Flutter
|
||||
- WebRTC-SDK (= 125.6422.04)
|
||||
- media_kit_libs_ios_video (1.0.4):
|
||||
@@ -482,7 +482,7 @@ SPEC CHECKSUMS:
|
||||
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||
image_cropper: 37d40f62177c101ff4c164906d259ea2c3aa70cf
|
||||
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
|
||||
livekit_client: 9c8080879256a0fb16da13c9be4845248209d896
|
||||
livekit_client: 20e01637431bc108dad451c8a11c1d206e1dd2cd
|
||||
media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1
|
||||
media_kit_native_event_loop: e6b2ab20cf0746eb1c33be961fcf79667304fa2a
|
||||
media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e
|
||||
|
||||
@@ -42,6 +42,28 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
|
||||
|
||||
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 {
|
||||
if (PlatformInfo.isWeb) return;
|
||||
try {
|
||||
@@ -70,25 +92,7 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
|
||||
remoteBuildNumber > localBuildNumber) ||
|
||||
(remoteVersionString != localVersionString && strictUpdate)) {
|
||||
if (PlatformInfo.isAndroid) {
|
||||
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);
|
||||
}
|
||||
});
|
||||
_updateNow(localVersionString, remoteVersionString);
|
||||
} else {
|
||||
context.showInfoDialog(
|
||||
'updateAvailable'.tr,
|
||||
@@ -97,9 +101,19 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
|
||||
}
|
||||
} else if (remoteVersionString != localVersionString) {
|
||||
_bootCompleter.future.then((_) {
|
||||
context.showSnackbar('updateMayAvailable'.trParams({
|
||||
'version': remoteVersionString,
|
||||
}));
|
||||
context.showSnackbar(
|
||||
'updateMayAvailable'.trParams({
|
||||
'version': remoteVersionString,
|
||||
}),
|
||||
action: PlatformInfo.isAndroid
|
||||
? SnackBarAction(
|
||||
label: 'updateNow'.tr,
|
||||
onPressed: () {
|
||||
_updateNow(localVersionString, remoteVersionString);
|
||||
},
|
||||
)
|
||||
: null,
|
||||
);
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:get/get.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/exts.dart';
|
||||
import 'package:solian/models/account.dart';
|
||||
import 'package:solian/models/attachment.dart';
|
||||
import 'package:solian/models/daily_sign.dart';
|
||||
import 'package:solian/models/pagination.dart';
|
||||
import 'package:solian/models/post.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/app_bar_leading.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_warped_list.dart';
|
||||
import 'package:solian/widgets/sized_container.dart';
|
||||
@@ -45,6 +51,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
||||
Account? _userinfo;
|
||||
Subscription? _subscription;
|
||||
List<Post> _pinnedPosts = List.empty();
|
||||
List<DailySignRecord> _dailySignRecords = List.empty();
|
||||
int _totalUpvote = 0, _totalDownvote = 0;
|
||||
|
||||
Future<void> _getSubscription() async {
|
||||
@@ -57,7 +64,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
||||
Future<void> _getUserinfo() async {
|
||||
setState(() => _isBusy = true);
|
||||
|
||||
var client = await ServiceFinder.configureClient('auth');
|
||||
var client = await ServiceFinder.configureClient('id');
|
||||
var resp = await client.get('/users/${widget.name}');
|
||||
if (resp.statusCode != 200) {
|
||||
context.showErrorDialog(resp.bodyString).then((_) {
|
||||
@@ -67,7 +74,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
||||
_userinfo = Account.fromJson(resp.body);
|
||||
}
|
||||
|
||||
client = await ServiceFinder.configureClient('interactive');
|
||||
client = await ServiceFinder.configureClient('co');
|
||||
resp = await client.get('/users/${widget.name}');
|
||||
if (resp.statusCode != 200) {
|
||||
context.showErrorDialog(resp.bodyString).then((_) {
|
||||
@@ -82,7 +89,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
||||
}
|
||||
|
||||
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');
|
||||
if (resp.statusCode != 200) {
|
||||
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 {
|
||||
return _totalUpvote * 2 - _totalDownvote + _postController.postTotal.value;
|
||||
}
|
||||
@@ -129,6 +153,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
||||
_getUserinfo().then((_) {
|
||||
_getSubscription();
|
||||
_getPinnedPosts();
|
||||
_getDailySignRecords();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -168,96 +193,99 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
||||
toolbarHeight: AppTheme.toolbarHeight(context),
|
||||
leadingWidth: 24,
|
||||
automaticallyImplyLeading: false,
|
||||
flexibleSpace: Row(
|
||||
children: [
|
||||
AppBarLeadingButton.adaptive(context) ?? const Gap(8),
|
||||
const Gap(8),
|
||||
if (_userinfo != null)
|
||||
AccountAvatar(content: _userinfo!.avatar, radius: 16),
|
||||
const Gap(12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (_userinfo != null)
|
||||
Text(
|
||||
_userinfo!.nick,
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
if (_userinfo != null)
|
||||
Text(
|
||||
'@${_userinfo!.name}',
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (_userinfo != null && _subscription == null)
|
||||
OutlinedButton(
|
||||
style: const ButtonStyle(
|
||||
visualDensity:
|
||||
VisualDensity(horizontal: -4, vertical: -2),
|
||||
flexibleSpace: SizedBox(
|
||||
height: 56,
|
||||
child: Row(
|
||||
children: [
|
||||
AppBarLeadingButton.adaptive(context) ?? const Gap(8),
|
||||
const Gap(8),
|
||||
if (_userinfo != null)
|
||||
AccountAvatar(content: _userinfo!.avatar, radius: 16),
|
||||
const Gap(12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (_userinfo != null)
|
||||
Text(
|
||||
_userinfo!.nick,
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
if (_userinfo != null)
|
||||
Text(
|
||||
'@${_userinfo!.name}',
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: _isSubscribing
|
||||
? null
|
||||
: () async {
|
||||
setState(() => _isSubscribing = true);
|
||||
_subscription =
|
||||
await Get.find<SubscriptionProvider>()
|
||||
.subscribeToUser(_userinfo!.id);
|
||||
setState(() => _isSubscribing = false);
|
||||
},
|
||||
child: Text('subscribe'.tr),
|
||||
)
|
||||
else if (_userinfo != null)
|
||||
OutlinedButton(
|
||||
style: const ButtonStyle(
|
||||
visualDensity:
|
||||
VisualDensity(horizontal: -4, vertical: -2),
|
||||
),
|
||||
if (_userinfo != null && _subscription == null)
|
||||
OutlinedButton(
|
||||
style: const ButtonStyle(
|
||||
visualDensity:
|
||||
VisualDensity(horizontal: -4, vertical: -2),
|
||||
),
|
||||
onPressed: _isSubscribing
|
||||
? null
|
||||
: () async {
|
||||
setState(() => _isSubscribing = true);
|
||||
_subscription =
|
||||
await Get.find<SubscriptionProvider>()
|
||||
.subscribeToUser(_userinfo!.id);
|
||||
setState(() => _isSubscribing = false);
|
||||
},
|
||||
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
|
||||
? null
|
||||
: () async {
|
||||
setState(() => _isSubscribing = true);
|
||||
await Get.find<SubscriptionProvider>()
|
||||
.unsubscribeFromUser(_userinfo!.id);
|
||||
_subscription = null;
|
||||
setState(() => _isSubscribing = false);
|
||||
},
|
||||
child: Text('unsubscribe'.tr),
|
||||
if (_userinfo != null &&
|
||||
!_relationshipProvider.hasFriend(_userinfo!))
|
||||
IconButton(
|
||||
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,
|
||||
),
|
||||
if (_userinfo != null &&
|
||||
!_relationshipProvider.hasFriend(_userinfo!))
|
||||
IconButton(
|
||||
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,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
).paddingOnly(top: MediaQuery.of(context).padding.top),
|
||||
bottom: TabBar(
|
||||
tabs: [
|
||||
Tab(text: 'profilePage'.tr),
|
||||
@@ -271,21 +299,132 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
||||
body: TabBarView(
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
children: [
|
||||
Column(
|
||||
ListView(
|
||||
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 [],
|
||||
CenteredContainer(
|
||||
child: 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: [
|
||||
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(
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () =>
|
||||
Future.sync(() => _albumPagingController.refresh()),
|
||||
onRefresh: () => Future.sync(
|
||||
() => _albumPagingController.refresh(),
|
||||
),
|
||||
child: PagedGridView<int, Attachment>(
|
||||
padding: EdgeInsets.zero,
|
||||
pagingController: _albumPagingController,
|
||||
|
||||
@@ -88,7 +88,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
||||
Future<void> _pullDaily() async {
|
||||
try {
|
||||
_signRecord = await _dailySign.getToday();
|
||||
_dailySign.listLastRecord(30).then((value) {
|
||||
_dailySign.listLastRecord(14).then((value) {
|
||||
setState(() => _signRecordHistory = value);
|
||||
});
|
||||
} catch (e) {
|
||||
@@ -103,7 +103,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
||||
|
||||
try {
|
||||
_signRecord = await _dailySign.signToday();
|
||||
_dailySign.listLastRecord(30).then((value) {
|
||||
_dailySign.listLastRecord(14).then((value) {
|
||||
setState(() => _signRecordHistory = value);
|
||||
});
|
||||
} catch (e) {
|
||||
|
||||
@@ -21,6 +21,7 @@ class AttachmentItem extends StatefulWidget {
|
||||
final bool showBadge;
|
||||
final bool showHideButton;
|
||||
final bool autoload;
|
||||
final bool isDense;
|
||||
final BoxFit fit;
|
||||
final String? badge;
|
||||
final Function? onHide;
|
||||
@@ -34,6 +35,7 @@ class AttachmentItem extends StatefulWidget {
|
||||
this.showBadge = true,
|
||||
this.showHideButton = true,
|
||||
this.autoload = false,
|
||||
this.isDense = false,
|
||||
this.onHide,
|
||||
});
|
||||
|
||||
@@ -53,6 +55,7 @@ class _AttachmentItemState extends State<AttachmentItem> {
|
||||
fit: widget.fit,
|
||||
showBadge: widget.showBadge,
|
||||
showHideButton: widget.showHideButton,
|
||||
isDense: widget.isDense,
|
||||
onHide: widget.onHide,
|
||||
);
|
||||
case 'video':
|
||||
@@ -120,6 +123,7 @@ class _AttachmentItemImage extends StatelessWidget {
|
||||
final bool showBadge;
|
||||
final bool showHideButton;
|
||||
final BoxFit fit;
|
||||
final bool isDense;
|
||||
final String? badge;
|
||||
final Function? onHide;
|
||||
|
||||
@@ -128,6 +132,7 @@ class _AttachmentItemImage extends StatelessWidget {
|
||||
required this.item,
|
||||
required this.showBadge,
|
||||
required this.showHideButton,
|
||||
required this.isDense,
|
||||
required this.fit,
|
||||
this.badge,
|
||||
this.onHide,
|
||||
@@ -146,6 +151,7 @@ class _AttachmentItemImage extends StatelessWidget {
|
||||
'/attachments/${item.rid}',
|
||||
),
|
||||
fit: fit,
|
||||
isDense: isDense,
|
||||
),
|
||||
if (showBadge && badge != null)
|
||||
Positioned(
|
||||
|
||||
@@ -338,6 +338,7 @@ class AttachmentListEntry extends StatelessWidget {
|
||||
badge: showBadge ? badgeContent : null,
|
||||
showHideButton: !item!.isMature || showMature,
|
||||
autoload: autoload,
|
||||
isDense: isDense,
|
||||
onHide: () {
|
||||
onReveal(false);
|
||||
},
|
||||
|
||||
@@ -12,7 +12,7 @@ class DailySignHistoryChartDialog extends StatelessWidget {
|
||||
|
||||
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(
|
||||
(a, b) => DateTime.fromMillisecondsSinceEpoch(
|
||||
@@ -42,215 +42,222 @@ class DailySignHistoryChartDialog extends StatelessWidget {
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
)
|
||||
: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'dailySignHistoryRecent'.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.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(),
|
||||
),
|
||||
: SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
Text(
|
||||
'dailySignHistoryRecent'.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(),
|
||||
),
|
||||
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!
|
||||
.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,
|
||||
spots: data!
|
||||
.map(
|
||||
(x) => FlSpot(
|
||||
x.createdAt
|
||||
.copyWith(
|
||||
hour: 0,
|
||||
minute: 0,
|
||||
second: 0,
|
||||
millisecond: 0,
|
||||
microsecond: 0,
|
||||
)
|
||||
.millisecondsSinceEpoch
|
||||
.toDouble(),
|
||||
x.resultTier.toDouble(),
|
||||
),
|
||||
))
|
||||
.toList(),
|
||||
getTooltipColor: (_) =>
|
||||
Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||
)),
|
||||
titlesData: FlTitlesData(
|
||||
topTitles: const AxisTitles(
|
||||
sideTitles: SideTitles(showTitles: false),
|
||||
)
|
||||
.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,
|
||||
),
|
||||
),
|
||||
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),
|
||||
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),
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
reservedSize: 28,
|
||||
interval: 86400000,
|
||||
getTitlesWidget: (value, _) => Text(
|
||||
DateFormat('dd').format(
|
||||
DateTime.fromMillisecondsSinceEpoch(
|
||||
value.toInt(),
|
||||
),
|
||||
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(),
|
||||
),
|
||||
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,
|
||||
autoload: false,
|
||||
isColumn: true,
|
||||
).paddingOnly(left: 60, right: 24);
|
||||
).paddingOnly(left: 60, right: 24, top: 4, bottom: 4);
|
||||
} else {
|
||||
return AttachmentList(
|
||||
flatMaxHeight: MediaQuery.of(context).size.width,
|
||||
|
||||
@@ -158,7 +158,7 @@ PODS:
|
||||
- GoogleUtilities/UserDefaults (8.0.2):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Privacy
|
||||
- livekit_client (2.2.5):
|
||||
- livekit_client (2.2.6):
|
||||
- FlutterMacOS
|
||||
- WebRTC-SDK (= 125.6422.04)
|
||||
- macos_window_utils (1.0.0):
|
||||
@@ -359,7 +359,7 @@ SPEC CHECKSUMS:
|
||||
GoogleAppMeasurement: 6e49ffac7d3f2c3ded9cc663f912a13b67bbd0de
|
||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||
livekit_client: be04a950a4b84b9dbc87507ffad5154fe75fa067
|
||||
livekit_client: 98d09566e3a936b3402be8091ec3845556d36800
|
||||
macos_window_utils: 933f91f64805e2eb91a5bd057cf97cd097276663
|
||||
media_kit_libs_macos_video: b3e2bbec2eef97c285f2b1baa7963c67c753fb82
|
||||
media_kit_native_event_loop: 81fd5b45192b72f8b5b69eaf5b540f45777eb8d5
|
||||
|
||||
@@ -751,10 +751,10 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_launcher_icons
|
||||
sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
|
||||
sha256: a38f2f1b3c373d42bf08bd17d60e20d3c73abce7727607b4d085ec7d5acaa294
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.13.1"
|
||||
version: "0.14.0"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
|
||||
@@ -2,7 +2,7 @@ name: solian
|
||||
description: "The Solar Network App"
|
||||
publish_to: "none"
|
||||
|
||||
version: 1.2.2+3
|
||||
version: 1.2.3+1
|
||||
|
||||
environment:
|
||||
sdk: ">=3.3.4 <4.0.0"
|
||||
@@ -89,7 +89,7 @@ dev_dependencies:
|
||||
sdk: flutter
|
||||
|
||||
flutter_lints: ^4.0.0
|
||||
flutter_launcher_icons: ^0.13.1
|
||||
flutter_launcher_icons: ^0.14.0
|
||||
|
||||
build_runner: ^2.4.12
|
||||
flutter_native_splash: ^2.4.1
|
||||
|
||||
Reference in New Issue
Block a user