From 8e76ff3f84fdcd8a5c87dc00d8e0749026841576 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Thu, 27 Feb 2025 20:51:47 +0800 Subject: [PATCH] :zap: Optimize user loading api usage --- lib/providers/user_directory.dart | 7 +- lib/screens/account/profile_page.dart | 104 ++++++++++++++++++-------- lib/screens/chat.dart | 8 +- macos/Podfile.lock | 4 +- 4 files changed, 84 insertions(+), 39 deletions(-) diff --git a/lib/providers/user_directory.dart b/lib/providers/user_directory.dart index c3c5c07..db01a7c 100644 --- a/lib/providers/user_directory.dart +++ b/lib/providers/user_directory.dart @@ -27,8 +27,11 @@ class UserDirectoryProvider { plannedQuery.add(item); } } - final resp = await _sn.client.get('/cgi/id/users', queryParameters: {'id': plannedQuery.join(',')}); - final respDecoded = resp.data.map((e) => SnAccount.fromJson(e)).cast().toList(); + if (plannedQuery.isEmpty) return out; + final resp = await _sn.client + .get('/cgi/id/users', queryParameters: {'id': plannedQuery.join(',')}); + final respDecoded = + resp.data.map((e) => SnAccount.fromJson(e)).cast().toList(); var sideIdx = 0; for (var idx = 0; idx < out.length; idx++) { if (out[idx] != null) continue; diff --git a/lib/screens/account/profile_page.dart b/lib/screens/account/profile_page.dart index e6b3185..cef4db3 100644 --- a/lib/screens/account/profile_page.dart +++ b/lib/screens/account/profile_page.dart @@ -43,7 +43,8 @@ class UserScreen extends StatefulWidget { State createState() => _UserScreenState(); } -class _UserScreenState extends State with SingleTickerProviderStateMixin { +class _UserScreenState extends State + with SingleTickerProviderStateMixin { late final ScrollController _scrollController = ScrollController(); SnAccount? _account; @@ -67,7 +68,8 @@ class _UserScreenState extends State with SingleTickerProviderStateM Future> _getCheckInRecords() async { try { final sn = context.read(); - final resp = await sn.client.get('/cgi/id/users/${widget.name}/check-in?take=14'); + final resp = + await sn.client.get('/cgi/id/users/${widget.name}/check-in?take=14'); return List.from( resp.data['data']?.map((x) => SnCheckInRecord.fromJson(x)) ?? [], ); @@ -98,7 +100,8 @@ class _UserScreenState extends State with SingleTickerProviderStateM Future _fetchPublishers() async { try { final sn = context.read(); - final resp = await sn.client.get('/cgi/co/publishers?user=${widget.name}'); + final resp = + await sn.client.get('/cgi/co/publishers?user=${widget.name}'); _publishers = List.from( resp.data?.map((e) => SnPublisher.fromJson(e)) ?? [], ); @@ -144,7 +147,8 @@ class _UserScreenState extends State with SingleTickerProviderStateM 'related': _account!.name, }); if (!mounted) return; - context.showSnackbar('userBlocked'.tr(args: ['@${_account?.name ?? 'unknown'}'])); + context.showSnackbar( + 'userBlocked'.tr(args: ['@${_account?.name ?? 'unknown'}'])); } catch (err) { if (!mounted) return; context.showErrorDialog(err); @@ -160,9 +164,11 @@ class _UserScreenState extends State with SingleTickerProviderStateM try { final rel = context.read(); - await rel.updateRelationship(_account!.id, 1, _accountRelationship?.permNodes ?? {}); + await rel.updateRelationship( + _account!.id, 1, _accountRelationship?.permNodes ?? {}); if (!mounted) return; - context.showSnackbar('userUnblocked'.tr(args: ['@${_account?.name ?? 'unknown'}'])); + context.showSnackbar( + 'userUnblocked'.tr(args: ['@${_account?.name ?? 'unknown'}'])); } catch (err) { if (!mounted) return; context.showErrorDialog(err); @@ -188,12 +194,14 @@ class _UserScreenState extends State with SingleTickerProviderStateM double _appBarBlur = 0.0; late final _appBarWidth = MediaQuery.of(context).size.width; - late final _appBarHeight = (_appBarWidth * kBannerAspectRatio).roundToDouble(); + late final _appBarHeight = + (_appBarWidth * kBannerAspectRatio).roundToDouble(); void _updateAppBarBlur() { if (_scrollController.offset > _appBarHeight) return; setState(() { - _appBarBlur = (_scrollController.offset / _appBarHeight * 10).clamp(0.0, 10.0); + _appBarBlur = + (_scrollController.offset / _appBarHeight * 10).clamp(0.0, 10.0); }); } @@ -260,18 +268,20 @@ class _UserScreenState extends State with SingleTickerProviderStateM text: TextSpan(children: [ TextSpan( text: _account!.nick, - style: Theme.of(context).textTheme.titleLarge!.copyWith( - color: Colors.white, - shadows: labelShadows, - ), + style: + Theme.of(context).textTheme.titleLarge!.copyWith( + color: Colors.white, + shadows: labelShadows, + ), ), const TextSpan(text: '\n'), TextSpan( text: '@${_account!.name}', - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: Colors.white, - shadows: labelShadows, - ), + style: + Theme.of(context).textTheme.bodySmall!.copyWith( + color: Colors.white, + shadows: labelShadows, + ), ), ]), ), @@ -339,7 +349,8 @@ class _UserScreenState extends State with SingleTickerProviderStateM PopupMenuButton( padding: EdgeInsets.zero, style: ButtonStyle( - visualDensity: VisualDensity(horizontal: -4, vertical: -4), + visualDensity: + VisualDensity(horizontal: -4, vertical: -4), ), itemBuilder: (context) => [ PopupMenuItem( @@ -399,7 +410,9 @@ class _UserScreenState extends State with SingleTickerProviderStateM Symbols.circle, fill: 1, size: 16, - color: (_status?.isOnline ?? false) ? Colors.green : Colors.grey, + color: (_status?.isOnline ?? false) + ? Colors.green + : Colors.grey, ).padding(all: 4), const Gap(8), Text( @@ -409,7 +422,9 @@ class _UserScreenState extends State with SingleTickerProviderStateM : 'accountStatusOffline'.tr() : 'loading'.tr(), ), - if (_status != null && !_status!.isOnline && _status!.lastSeenAt != null) + if (_status != null && + !_status!.isOnline && + _status!.lastSeenAt != null) Text( 'accountStatusLastSeen'.tr(args: [ _status!.lastSeenAt != null @@ -429,11 +444,14 @@ class _UserScreenState extends State with SingleTickerProviderStateM (ele) => Tooltip( richMessage: TextSpan( children: [ - TextSpan(text: kBadgesMeta[ele.type]?.$1.tr() ?? 'unknown'.tr()), + TextSpan( + text: kBadgesMeta[ele.type]?.$1.tr() ?? + 'unknown'.tr()), if (ele.metadata['title'] != null) TextSpan( text: '\n${ele.metadata['title']}', - style: const TextStyle(fontWeight: FontWeight.bold), + style: const TextStyle( + fontWeight: FontWeight.bold), ), TextSpan(text: '\n'), TextSpan( @@ -442,7 +460,8 @@ class _UserScreenState extends State with SingleTickerProviderStateM ], ), child: Icon( - kBadgesMeta[ele.type]?.$2 ?? Symbols.question_mark, + kBadgesMeta[ele.type]?.$2 ?? + Symbols.question_mark, color: kBadgesMeta[ele.type]?.$3, fill: 1, ), @@ -458,7 +477,9 @@ class _UserScreenState extends State with SingleTickerProviderStateM children: [ const Icon(Symbols.calendar_add_on), const Gap(8), - Text('publisherJoinedAt').tr(args: [DateFormat('y/M/d').format(_account!.createdAt)]), + Text('publisherJoinedAt').tr(args: [ + DateFormat('y/M/d').format(_account!.createdAt) + ]), ], ), Row( @@ -491,17 +512,24 @@ class _UserScreenState extends State with SingleTickerProviderStateM children: [ const Icon(Symbols.star), const Gap(8), - Text('Lv${getLevelFromExp(_account?.profile?.experience ?? 0)}'), + Text( + 'Lv${getLevelFromExp(_account?.profile?.experience ?? 0)}'), const Gap(8), - Text(calcLevelUpProgressLevel(_account?.profile?.experience ?? 0)).fontSize(11).opacity(0.5), + Text(calcLevelUpProgressLevel( + _account?.profile?.experience ?? 0)) + .fontSize(11) + .opacity(0.5), const Gap(8), Container( width: double.infinity, constraints: const BoxConstraints(maxWidth: 160), child: LinearProgressIndicator( - value: calcLevelUpProgress(_account?.profile?.experience ?? 0), + value: calcLevelUpProgress( + _account?.profile?.experience ?? 0), borderRadius: BorderRadius.circular(8), - backgroundColor: Theme.of(context).colorScheme.surfaceContainer, + backgroundColor: Theme.of(context) + .colorScheme + .surfaceContainer, ).alignment(Alignment.centerLeft), ), ], @@ -515,6 +543,7 @@ class _UserScreenState extends State with SingleTickerProviderStateM const SliverGap(12), SliverToBoxAdapter( child: FutureBuilder>( + key: GlobalKey(), future: _getCheckInRecords(), builder: (context, snapshot) { if (!snapshot.hasData) return const SizedBox.shrink(); @@ -522,7 +551,11 @@ class _UserScreenState extends State with SingleTickerProviderStateM return Text( 'accountCheckInNoRecords', textAlign: TextAlign.center, - ).tr().fontWeight(FontWeight.bold).center().padding(horizontal: 20, vertical: 8); + ) + .tr() + .fontWeight(FontWeight.bold) + .center() + .padding(horizontal: 20, vertical: 8); } final records = snapshot.data!; return SizedBox( @@ -544,7 +577,11 @@ class _UserScreenState extends State with SingleTickerProviderStateM child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('accountBadge').bold().fontSize(17).tr().padding(horizontal: 20, bottom: 4), + Text('accountBadge') + .bold() + .fontSize(17) + .tr() + .padding(horizontal: 20, bottom: 4), SizedBox( height: 80, width: double.infinity, @@ -558,7 +595,8 @@ class _UserScreenState extends State with SingleTickerProviderStateM child: Card( child: ListTile( leading: Icon( - kBadgesMeta[badge.type]?.$2 ?? Symbols.question_mark, + kBadgesMeta[badge.type]?.$2 ?? + Symbols.question_mark, color: kBadgesMeta[badge.type]?.$3, fill: 1, ), @@ -568,7 +606,8 @@ class _UserScreenState extends State with SingleTickerProviderStateM subtitle: badge.metadata['title'] != null ? Text(badge.metadata['title']) : Text( - DateFormat('y/M/d').format(badge.createdAt), + DateFormat('y/M/d') + .format(badge.createdAt), ), ), ), @@ -664,7 +703,8 @@ class CheckInRecordChart extends StatelessWidget { ), ) .toList(), - getTooltipColor: (_) => Theme.of(context).colorScheme.surfaceContainerHigh, + getTooltipColor: (_) => + Theme.of(context).colorScheme.surfaceContainerHigh, ), ), titlesData: FlTitlesData( diff --git a/lib/screens/chat.dart b/lib/screens/chat.dart index b4ade10..ee718e6 100644 --- a/lib/screens/chat.dart +++ b/lib/screens/chat.dart @@ -74,18 +74,20 @@ class _ChatScreenState extends State { if (!mounted) return; final ud = context.read(); + final idSet = {}; for (final channel in channels) { if (channel.type == 1) { - await ud.listAccount( + idSet.addAll( channel.members ?.cast() .map((ele) => ele?.accountId) .where((ele) => ele != null) - .toSet() ?? - {}, + .cast() ?? + [], ); } } + if (idSet.isNotEmpty) await ud.listAccount(idSet); if (mounted) setState(() => _channels = channels); }) diff --git a/macos/Podfile.lock b/macos/Podfile.lock index be821fd..a78a874 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -193,7 +193,7 @@ PODS: - sqlite3_flutter_libs (0.0.1): - Flutter - FlutterMacOS - - sqlite3 (~> 3.49.0) + - sqlite3 (~> 3.49.1) - sqlite3/dbstatvtab - sqlite3/fts5 - sqlite3/perf-threadsafe @@ -378,7 +378,7 @@ SPEC CHECKSUMS: shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d sqlite3: fc1400008a9b3525f5914ed715a5d1af0b8f4983 - sqlite3_flutter_libs: 069c435986dd4b63461aecd68f4b30be4a9e9daa + sqlite3_flutter_libs: cc304edcb8e1d8c595d1b08c7aeb46a47691d9db tray_manager: 9064e219c56d75c476e46b9a21182087930baf90 url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404 video_compress: c896234f100791b5fef7f049afa38f6d2ef7b42f