From c1d3bac0c80cc4e04d3d3c5f1e1d9a4ba020a894 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Wed, 8 May 2024 22:01:06 +0800 Subject: [PATCH] :bug: Fix several known bugs --- lib/providers/chat.dart | 1 + lib/screens/account.dart | 3 +- lib/screens/account/friend.dart | 3 +- lib/screens/account/personalize.dart | 2 +- lib/screens/auth/signin.dart | 2 +- lib/screens/auth/signup.dart | 2 +- lib/screens/chat/call.dart | 2 +- lib/screens/chat/channel/channel_editor.dart | 3 +- lib/screens/chat/channel/channel_member.dart | 4 +-- lib/screens/chat/chat.dart | 6 ++-- lib/screens/chat/chat_detail.dart | 10 +++--- lib/screens/chat/chat_list.dart | 2 +- lib/screens/explore.dart | 3 +- lib/screens/notification.dart | 3 +- lib/screens/posts/comment_editor.dart | 3 +- lib/screens/posts/moment_editor.dart | 4 ++- lib/screens/posts/screen.dart | 3 +- lib/screens/realms/realm.dart | 21 +++++------- lib/screens/realms/realm_editor.dart | 3 +- lib/screens/realms/realm_list.dart | 2 +- lib/screens/realms/realm_manage.dart | 3 +- lib/screens/realms/realm_member.dart | 3 +- lib/screens/users/userinfo.dart | 3 +- lib/widgets/chat/message_action.dart | 3 ++ lib/widgets/chat/message_deletion.dart | 9 ++--- lib/widgets/realms/realm_shortcuts.dart | 10 +++--- lib/widgets/scaffold.dart | 36 ++++++++++++++++---- 27 files changed, 88 insertions(+), 61 deletions(-) diff --git a/lib/providers/chat.dart b/lib/providers/chat.dart index 58adcbf..b95dae8 100644 --- a/lib/providers/chat.dart +++ b/lib/providers/chat.dart @@ -205,6 +205,7 @@ class ChatProvider extends ChangeNotifier { void unFocus() { currentCall = null; focusChannel = null; + historyPagingController?.dispose(); historyPagingController = null; notifyListeners(); } diff --git a/lib/screens/account.dart b/lib/screens/account.dart index 00fca02..05be951 100644 --- a/lib/screens/account.dart +++ b/lib/screens/account.dart @@ -14,9 +14,8 @@ class AccountScreen extends StatelessWidget { Widget build(BuildContext context) { return IndentScaffold( title: AppLocalizations.of(context)!.account, - noSafeArea: true, fixedAppBarColor: SolianTheme.isLargeScreen(context), - child: AccountScreenWidget( + body: AccountScreenWidget( onSelect: (item) { SolianRouter.router.pushNamed(item); }, diff --git a/lib/screens/account/friend.dart b/lib/screens/account/friend.dart index c6af012..9d64cbe 100644 --- a/lib/screens/account/friend.dart +++ b/lib/screens/account/friend.dart @@ -18,9 +18,8 @@ class FriendScreen extends StatelessWidget { Widget build(BuildContext context) { return IndentScaffold( title: AppLocalizations.of(context)!.friend, - noSafeArea: true, hideDrawer: true, - child: const FriendScreenWidget(), + body: const FriendScreenWidget(), ); } } diff --git a/lib/screens/account/personalize.dart b/lib/screens/account/personalize.dart index 5aee0e2..c0fd578 100644 --- a/lib/screens/account/personalize.dart +++ b/lib/screens/account/personalize.dart @@ -22,7 +22,7 @@ class PersonalizeScreen extends StatelessWidget { return IndentScaffold( title: AppLocalizations.of(context)!.personalize, hideDrawer: true, - child: const PersonalizeScreenWidget(), + body: const PersonalizeScreenWidget(), ); } } diff --git a/lib/screens/auth/signin.dart b/lib/screens/auth/signin.dart index d2e12ac..bb7b755 100644 --- a/lib/screens/auth/signin.dart +++ b/lib/screens/auth/signin.dart @@ -64,7 +64,7 @@ class SignInScreen extends StatelessWidget { return IndentScaffold( title: AppLocalizations.of(context)!.signIn, hideDrawer: true, - child: Center( + body: Center( child: Container( width: MediaQuery.of(context).size.width * 0.6, constraints: const BoxConstraints(maxWidth: 360), diff --git a/lib/screens/auth/signup.dart b/lib/screens/auth/signup.dart index 9fbce17..142f831 100644 --- a/lib/screens/auth/signup.dart +++ b/lib/screens/auth/signup.dart @@ -71,7 +71,7 @@ class SignUpScreen extends StatelessWidget { return IndentScaffold( title: AppLocalizations.of(context)!.signUp, hideDrawer: true, - child: Center( + body: Center( child: Container( width: MediaQuery.of(context).size.width * 0.6, constraints: const BoxConstraints(maxWidth: 360), diff --git a/lib/screens/chat/call.dart b/lib/screens/chat/call.dart index 2d8f387..ddb3e23 100644 --- a/lib/screens/chat/call.dart +++ b/lib/screens/chat/call.dart @@ -132,7 +132,7 @@ class _ChatCallState extends State { title: AppLocalizations.of(context)!.chatCall, fixedAppBarColor: SolianTheme.isLargeScreen(context), hideDrawer: true, - child: content, + body: content, ); } diff --git a/lib/screens/chat/channel/channel_editor.dart b/lib/screens/chat/channel/channel_editor.dart index 0bb71b7..1535541 100644 --- a/lib/screens/chat/channel/channel_editor.dart +++ b/lib/screens/chat/channel/channel_editor.dart @@ -102,6 +102,7 @@ class _ChannelEditorScreenState extends State { return IndentScaffold( hideDrawer: true, + showSafeArea: true, title: AppLocalizations.of(context)!.chatChannelOrganize, appBarActions: [ TextButton( @@ -109,7 +110,7 @@ class _ChannelEditorScreenState extends State { child: Text(AppLocalizations.of(context)!.apply.toUpperCase()), ), ], - child: Column( + body: Column( children: [ _isSubmitting ? const LinearProgressIndicator().animate().scaleX() : Container(), widget.editing != null ? editingBanner : Container(), diff --git a/lib/screens/chat/channel/channel_member.dart b/lib/screens/chat/channel/channel_member.dart index d1a502f..24df8e3 100644 --- a/lib/screens/chat/channel/channel_member.dart +++ b/lib/screens/chat/channel/channel_member.dart @@ -38,6 +38,7 @@ class _ChatMemberScreenState extends State { _selfId = prof['id']; var uri = getRequestUri('messaging', '/api/channels/${widget.realm}/${widget.channel.alias}/members'); + print(uri); var res = await auth.client!.get(uri); if (res.statusCode == 200) { @@ -141,7 +142,6 @@ class _ChatMemberScreenState extends State { Widget build(BuildContext context) { return IndentScaffold( title: AppLocalizations.of(context)!.chatMember, - noSafeArea: true, hideDrawer: true, appBarActions: [ IconButton( @@ -149,7 +149,7 @@ class _ChatMemberScreenState extends State { onPressed: () => promptAddMember(), ), ], - child: RefreshIndicator( + body: RefreshIndicator( onRefresh: () => fetchMemberships(), child: CustomScrollView( slivers: [ diff --git a/lib/screens/chat/chat.dart b/lib/screens/chat/chat.dart index c354a66..3905cba 100644 --- a/lib/screens/chat/chat.dart +++ b/lib/screens/chat/chat.dart @@ -32,6 +32,7 @@ class ChatScreen extends StatelessWidget { return IndentScaffold( title: chat.focusChannel?.name ?? 'Loading...', hideDrawer: true, + showSafeArea: true, fixedAppBarColor: SolianTheme.isLargeScreen(context), appBarActions: chat.focusChannel != null ? [ @@ -48,7 +49,7 @@ class ChatScreen extends StatelessWidget { ), ] : [], - child: ChatWidget( + body: ChatWidget( alias: alias, realm: realm, ), @@ -96,7 +97,7 @@ class _ChatWidgetState extends State { if (a?.replyTo != null) return false; if (a == null || b == null) return false; if (a.senderId != b.senderId) return false; - return a.createdAt.difference(b.createdAt).inMinutes <= 5; + return a.createdAt.difference(b.createdAt).inMinutes <= 3; } Message? _editingItem; @@ -107,6 +108,7 @@ class _ChatWidgetState extends State { context: context, builder: (context) => ChatMessageAction( channel: widget.alias, + realm: widget.realm, item: item, onEdit: () => setState(() { _editingItem = item; diff --git a/lib/screens/chat/chat_detail.dart b/lib/screens/chat/chat_detail.dart index d24f27d..2c55c71 100644 --- a/lib/screens/chat/chat_detail.dart +++ b/lib/screens/chat/chat_detail.dart @@ -67,8 +67,7 @@ class _ChatDetailScreenState extends State { return IndentScaffold( title: AppLocalizations.of(context)!.chatDetail, hideDrawer: true, - noSafeArea: true, - child: Column( + body: Column( children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), @@ -103,9 +102,12 @@ class _ChatDetailScreenState extends State { title: Text(AppLocalizations.of(context)!.chatMember), onTap: () { SolianRouter.router.pushNamed( - 'chat.channel.member', + widget.realm == 'global' ? 'chat.channel.member' : 'realms.chat.channel.member', extra: widget.channel, - pathParameters: {'channel': widget.channel.alias}, + pathParameters: { + 'channel': widget.channel.alias, + ...(widget.realm == 'global' ? {} : {'realm': widget.realm}), + }, ); }, ), diff --git a/lib/screens/chat/chat_list.dart b/lib/screens/chat/chat_list.dart index c1b779c..e4be153 100644 --- a/lib/screens/chat/chat_list.dart +++ b/lib/screens/chat/chat_list.dart @@ -24,7 +24,7 @@ class ChatListScreen extends StatelessWidget { title: AppLocalizations.of(context)!.chat, appBarActions: const [NotificationButton()], fixedAppBarColor: SolianTheme.isLargeScreen(context), - child: const ChatListWidget(), + body: const ChatListWidget(), ); } } diff --git a/lib/screens/explore.dart b/lib/screens/explore.dart index 006b9eb..43a9b09 100644 --- a/lib/screens/explore.dart +++ b/lib/screens/explore.dart @@ -23,11 +23,10 @@ class ExplorePostScreen extends StatelessWidget { @override Widget build(BuildContext context) { return IndentScaffold( - noSafeArea: true, fixedAppBarColor: SolianTheme.isLargeScreen(context), appBarActions: const [NotificationButton()], title: AppLocalizations.of(context)!.explore, - child: const ExplorePostWidget(showRealmShortcuts: true), + body: const ExplorePostWidget(showRealmShortcuts: true), ); } } diff --git a/lib/screens/notification.dart b/lib/screens/notification.dart index 60a9cc4..eb49f4d 100644 --- a/lib/screens/notification.dart +++ b/lib/screens/notification.dart @@ -73,10 +73,9 @@ class _NotificationScreenState extends State { final nty = context.watch(); return IndentScaffold( - noSafeArea: true, hideDrawer: true, title: AppLocalizations.of(context)!.notification, - child: RefreshIndicator( + body: RefreshIndicator( onRefresh: () => nty.fetch(auth), child: CustomScrollView( slivers: [ diff --git a/lib/screens/posts/comment_editor.dart b/lib/screens/posts/comment_editor.dart index a52a508..8fe7567 100644 --- a/lib/screens/posts/comment_editor.dart +++ b/lib/screens/posts/comment_editor.dart @@ -122,6 +122,7 @@ class _CommentEditorScreenState extends State { return IndentScaffold( hideDrawer: true, + showSafeArea: true, title: AppLocalizations.of(context)!.newComment, appBarActions: [ TextButton( @@ -129,7 +130,7 @@ class _CommentEditorScreenState extends State { child: Text(AppLocalizations.of(context)!.postVerb.toUpperCase()), ), ], - child: Column( + body: Column( children: [ _isSubmitting ? const LinearProgressIndicator().animate().scaleX() diff --git a/lib/screens/posts/moment_editor.dart b/lib/screens/posts/moment_editor.dart index f2049b6..66cc28f 100644 --- a/lib/screens/posts/moment_editor.dart +++ b/lib/screens/posts/moment_editor.dart @@ -55,6 +55,7 @@ class _MomentEditorScreenState extends State { final uri = widget.editing == null ? getRequestUri('interactive', '/api/p/moments') : getRequestUri('interactive', '/api/p/moments/${widget.editing!.id}'); + print(uri); final req = Request(widget.editing == null ? 'POST' : 'PUT', uri); req.headers['Content-Type'] = 'application/json'; @@ -113,6 +114,7 @@ class _MomentEditorScreenState extends State { ); return IndentScaffold( + showSafeArea: true, hideDrawer: true, title: AppLocalizations.of(context)!.newMoment, appBarActions: [ @@ -121,7 +123,7 @@ class _MomentEditorScreenState extends State { child: Text(AppLocalizations.of(context)!.postVerb.toUpperCase()), ), ], - child: Column( + body: Column( children: [ _isSubmitting ? const LinearProgressIndicator().animate().scaleX() : Container(), FutureBuilder( diff --git a/lib/screens/posts/screen.dart b/lib/screens/posts/screen.dart index 831ea34..4437e9b 100644 --- a/lib/screens/posts/screen.dart +++ b/lib/screens/posts/screen.dart @@ -21,9 +21,8 @@ class PostScreen extends StatelessWidget { Widget build(BuildContext context) { return IndentScaffold( title: AppLocalizations.of(context)!.post, - noSafeArea: true, hideDrawer: true, - child: PostScreenWidget( + body: PostScreenWidget( dataset: dataset, alias: alias, ), diff --git a/lib/screens/realms/realm.dart b/lib/screens/realms/realm.dart index 8fe941d..416160a 100644 --- a/lib/screens/realms/realm.dart +++ b/lib/screens/realms/realm.dart @@ -21,7 +21,6 @@ class RealmScreen extends StatelessWidget { return IndentScaffold( title: realm.focusRealm?.name ?? 'Loading...', - noSafeArea: true, hideDrawer: true, fixedAppBarColor: SolianTheme.isLargeScreen(context), appBarActions: realm.focusRealm != null @@ -32,17 +31,15 @@ class RealmScreen extends StatelessWidget { ), ] : [], - appBarLeading: IconButton( - icon: const Icon(Icons.arrow_back), - onPressed: () { - if (SolianTheme.isLargeScreen(context)) { - realm.clearFocus(); - } else if (SolianRouter.router.canPop()) { - SolianRouter.router.pop(); - } - }, - ), - child: RealmWidget( + appBarLeading: SolianTheme.isLargeScreen(context) + ? IconButton( + icon: const Icon(Icons.arrow_back), + onPressed: () { + realm.clearFocus(); + }, + ) + : null, + body: RealmWidget( alias: alias, ), ); diff --git a/lib/screens/realms/realm_editor.dart b/lib/screens/realms/realm_editor.dart index f10d7dd..0bbf79c 100644 --- a/lib/screens/realms/realm_editor.dart +++ b/lib/screens/realms/realm_editor.dart @@ -111,6 +111,7 @@ class _RealmEditorScreenState extends State { return IndentScaffold( hideDrawer: true, + showSafeArea: true, title: AppLocalizations.of(context)!.realmEstablish, appBarActions: [ TextButton( @@ -119,7 +120,7 @@ class _RealmEditorScreenState extends State { ), ], fixedAppBarColor: SolianTheme.isLargeScreen(context), - child: Column( + body: Column( children: [ _isSubmitting ? const LinearProgressIndicator().animate().scaleX() : Container(), widget.editing != null ? editingBanner : Container(), diff --git a/lib/screens/realms/realm_list.dart b/lib/screens/realms/realm_list.dart index 94d41d0..24abe7f 100644 --- a/lib/screens/realms/realm_list.dart +++ b/lib/screens/realms/realm_list.dart @@ -23,7 +23,7 @@ class RealmListScreen extends StatelessWidget { title: AppLocalizations.of(context)!.realm, appBarActions: const [NotificationButton()], fixedAppBarColor: SolianTheme.isLargeScreen(context), - child: const RealmListWidget(), + body: const RealmListWidget(), ) : RealmScreen(alias: realm.focusRealm!.alias); } diff --git a/lib/screens/realms/realm_manage.dart b/lib/screens/realms/realm_manage.dart index 11039d3..94ff845 100644 --- a/lib/screens/realms/realm_manage.dart +++ b/lib/screens/realms/realm_manage.dart @@ -65,8 +65,7 @@ class _RealmManageScreenState extends State { return IndentScaffold( title: AppLocalizations.of(context)!.realmManage, hideDrawer: true, - noSafeArea: true, - child: Column( + body: Column( children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), diff --git a/lib/screens/realms/realm_member.dart b/lib/screens/realms/realm_member.dart index 217ed24..3c6fee5 100644 --- a/lib/screens/realms/realm_member.dart +++ b/lib/screens/realms/realm_member.dart @@ -142,7 +142,6 @@ class _RealmMemberScreenState extends State { return IndentScaffold( title: AppLocalizations.of(context)!.realmMember, fixedAppBarColor: SolianTheme.isLargeScreen(context), - noSafeArea: true, hideDrawer: true, appBarActions: [ IconButton( @@ -150,7 +149,7 @@ class _RealmMemberScreenState extends State { onPressed: () => promptAddMember(), ), ], - child: RefreshIndicator( + body: RefreshIndicator( onRefresh: () => fetchMemberships(), child: CustomScrollView( slivers: [ diff --git a/lib/screens/users/userinfo.dart b/lib/screens/users/userinfo.dart index 7d88dd5..e38053f 100644 --- a/lib/screens/users/userinfo.dart +++ b/lib/screens/users/userinfo.dart @@ -65,8 +65,7 @@ class _UserInfoScreenState extends State { title: _userinfo?.nick ?? 'Loading...', fixedAppBarColor: SolianTheme.isLargeScreen(context), hideDrawer: true, - noSafeArea: true, - child: FutureBuilder( + body: FutureBuilder( future: fetchUserinfo(), builder: (context, snapshot) { if (!snapshot.hasData || snapshot.data == null) { diff --git a/lib/widgets/chat/message_action.dart b/lib/widgets/chat/message_action.dart index 378efb5..e1fae80 100644 --- a/lib/widgets/chat/message_action.dart +++ b/lib/widgets/chat/message_action.dart @@ -7,6 +7,7 @@ import 'package:solian/widgets/chat/message_deletion.dart'; class ChatMessageAction extends StatelessWidget { final String channel; + final String realm; final Message item; final Function? onEdit; final Function? onReply; @@ -15,6 +16,7 @@ class ChatMessageAction extends StatelessWidget { super.key, required this.channel, required this.item, + this.realm = 'global', this.onEdit, this.onReply, }); @@ -67,6 +69,7 @@ class ChatMessageAction extends StatelessWidget { builder: (context) => ChatMessageDeletionDialog( item: item, channel: channel, + realm: realm, ), ).then((did) { if (did == true && Navigator.canPop(context)) { diff --git a/lib/widgets/chat/message_deletion.dart b/lib/widgets/chat/message_deletion.dart index dc66954..a6e28ab 100644 --- a/lib/widgets/chat/message_deletion.dart +++ b/lib/widgets/chat/message_deletion.dart @@ -10,17 +10,18 @@ import 'package:solian/widgets/exts.dart'; class ChatMessageDeletionDialog extends StatefulWidget { final String channel; + final String realm; final Message item; const ChatMessageDeletionDialog({ super.key, required this.item, required this.channel, + this.realm = 'global' }); @override - State createState() => - _ChatMessageDeletionDialogState(); + State createState() => _ChatMessageDeletionDialogState(); } class _ChatMessageDeletionDialogState extends State { @@ -30,8 +31,8 @@ class _ChatMessageDeletionDialogState extends State { final auth = context.read(); if (!await auth.isAuthorized()) return; - final uri = getRequestUri('messaging', - '/api/channels/global/${widget.channel}/messages/${widget.item.id}'); + final uri = + getRequestUri('messaging', '/api/channels/${widget.realm}/${widget.channel}/messages/${widget.item.id}'); setState(() => _isSubmitting = true); final res = await auth.client!.delete(uri); diff --git a/lib/widgets/realms/realm_shortcuts.dart b/lib/widgets/realms/realm_shortcuts.dart index 495631f..fe67060 100644 --- a/lib/widgets/realms/realm_shortcuts.dart +++ b/lib/widgets/realms/realm_shortcuts.dart @@ -57,11 +57,13 @@ class RealmShortcuts extends StatelessWidget { onTap: () async { if (SolianTheme.isLargeScreen(context)) { await realm.fetchSingle(auth, element.alias); + SolianRouter.router.pushNamed('realms'); + } else { + SolianRouter.router.pushNamed( + 'realms.details', + pathParameters: {'realm': element.alias}, + ); } - SolianRouter.router.pushNamed( - 'realms.details', - pathParameters: {'realm': element.alias}, - ); }, ); }, diff --git a/lib/widgets/scaffold.dart b/lib/widgets/scaffold.dart index ed6a224..b2a976f 100644 --- a/lib/widgets/scaffold.dart +++ b/lib/widgets/scaffold.dart @@ -1,45 +1,67 @@ import 'package:flutter/material.dart'; +import 'package:solian/router.dart'; import 'package:solian/utils/theme.dart'; import 'package:solian/widgets/navigation_drawer.dart'; class IndentScaffold extends StatelessWidget { - final Widget? child; + final Widget? body; final Widget? floatingActionButton; final Widget? appBarLeading; final List? appBarActions; - final bool noSafeArea; final bool hideDrawer; + final bool showSafeArea; final bool fixedAppBarColor; final String title; const IndentScaffold({ super.key, - this.child, + this.body, required this.title, this.floatingActionButton, this.appBarLeading, this.appBarActions, this.hideDrawer = false, + this.showSafeArea = false, this.fixedAppBarColor = false, - this.noSafeArea = false, }); @override Widget build(BuildContext context) { - final content = child ?? Container(); + final backButton = IconButton( + icon: const Icon(Icons.arrow_back), + tooltip: MaterialLocalizations.of(context).backButtonTooltip, + onPressed: () { + if (SolianRouter.router.canPop()) { + SolianRouter.router.pop(); + } + }, + ); + + final drawerButton = Builder( + builder: (context) { + return IconButton( + icon: const Icon(Icons.menu), + tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip, + onPressed: () { + Scaffold.of(context).openDrawer(); + }, + ); + } + ); return Scaffold( appBar: AppBar( title: Text(title), - leading: appBarLeading, + leading: appBarLeading ?? (hideDrawer ? backButton : drawerButton), actions: appBarActions, centerTitle: false, elevation: fixedAppBarColor ? 4 : null, + automaticallyImplyLeading: false, ), floatingActionButton: floatingActionButton, drawer: !hideDrawer ? const SolianNavigationDrawer() : null, drawerScrimColor: SolianTheme.isLargeScreen(context) ? Colors.transparent : null, - body: noSafeArea ? content : SafeArea(child: content), + body: showSafeArea ? SafeArea(child: body ?? Container()) : body, ); } }