From 5468fc0748173a95cb1766adab25e62b395c552c Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sun, 23 Feb 2025 11:36:02 +0800 Subject: [PATCH] :sparkles: Two pane chat screen --- lib/screens/chat.dart | 42 ++++++++++++++++++++++-- lib/widgets/navigation/app_scaffold.dart | 25 +++++++------- 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/lib/screens/chat.dart b/lib/screens/chat.dart index 15e0a9e..bc52052 100644 --- a/lib/screens/chat.dart +++ b/lib/screens/chat.dart @@ -5,16 +5,19 @@ import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; import 'package:material_symbols_icons/symbols.dart'; import 'package:provider/provider.dart'; +import 'package:responsive_framework/responsive_framework.dart'; import 'package:surface/providers/channel.dart'; import 'package:surface/providers/sn_network.dart'; import 'package:surface/providers/user_directory.dart'; import 'package:surface/providers/userinfo.dart'; +import 'package:surface/screens/chat/room.dart'; import 'package:surface/types/chat.dart'; import 'package:surface/widgets/account/account_image.dart'; import 'package:surface/widgets/account/account_select.dart'; import 'package:surface/widgets/app_bar_leading.dart'; import 'package:surface/widgets/dialog.dart'; import 'package:surface/widgets/loading_indicator.dart'; +import 'package:surface/widgets/navigation/app_background.dart'; import 'package:surface/widgets/navigation/app_scaffold.dart'; import 'package:surface/widgets/unauthorized_hint.dart'; import 'package:uuid/uuid.dart'; @@ -123,6 +126,8 @@ class _ChatScreenState extends State { } } + SnChannel? _focusChannel; + @override void initState() { super.initState(); @@ -147,7 +152,10 @@ class _ChatScreenState extends State { ); } - return AppScaffold( + final doExpand = ResponsiveBreakpoints.of(context).largerOrEqualTo(DESKTOP); + + final chatList = AppScaffold( + noBackground: doExpand, appBar: AppBar( leading: AutoAppBarLeading(), title: Text('screenChat').tr(), @@ -275,6 +283,10 @@ class _ChatScreenState extends State { ?.avatar, ), onTap: () { + if (doExpand) { + setState(() => _focusChannel = channel); + return; + } GoRouter.of(context).pushNamed( 'chatRoom', pathParameters: { @@ -317,6 +329,10 @@ class _ChatScreenState extends State { fallbackWidget: const Icon(Symbols.chat, size: 20), ), onTap: () { + if (doExpand) { + setState(() => _focusChannel = channel); + return; + } GoRouter.of(context).pushNamed( 'chatRoom', pathParameters: { @@ -324,7 +340,7 @@ class _ChatScreenState extends State { 'alias': channel.alias, }, ).then((value) { - if (value == true) _refreshChannels(); + if (value == true) _refreshChannels(noRemote: true); }); }, ); @@ -336,5 +352,27 @@ class _ChatScreenState extends State { ], ), ); + + if (doExpand) { + return AppBackground( + isRoot: true, + child: Row( + children: [ + SizedBox(width: 340, child: chatList), + const VerticalDivider(width: 1), + if (_focusChannel != null) + Expanded( + child: ChatRoomScreen( + key: ValueKey(_focusChannel!.id), + scope: _focusChannel!.realm?.alias ?? 'global', + alias: _focusChannel!.alias, + ), + ), + ], + ), + ); + } + + return chatList; } } diff --git a/lib/widgets/navigation/app_scaffold.dart b/lib/widgets/navigation/app_scaffold.dart index 38ea820..ace70c0 100644 --- a/lib/widgets/navigation/app_scaffold.dart +++ b/lib/widgets/navigation/app_scaffold.dart @@ -31,6 +31,7 @@ class AppScaffold extends StatelessWidget { final AppBar? appBar; final DrawerCallback? onDrawerChanged; final DrawerCallback? onEndDrawerChanged; + final bool noBackground; const AppScaffold({ super.key, @@ -45,6 +46,7 @@ class AppScaffold extends StatelessWidget { this.endDrawer, this.onDrawerChanged, this.onEndDrawerChanged, + this.noBackground = false, }); @override @@ -52,22 +54,23 @@ class AppScaffold extends StatelessWidget { final appBarHeight = appBar?.preferredSize.height ?? 0; final safeTop = MediaQuery.of(context).padding.top; + final content = Column( + children: [ + IgnorePointer( + child: SizedBox(height: appBar != null ? appBarHeight + safeTop : 0), + ), + if (body != null) Expanded(child: body!), + ], + ); + return Scaffold( extendBody: true, extendBodyBehindAppBar: true, backgroundColor: Theme.of(context).scaffoldBackgroundColor, body: SizedBox.expand( - child: AppBackground( - isRoot: true, - child: Column( - children: [ - IgnorePointer( - child: SizedBox( - height: appBar != null ? appBarHeight + safeTop : 0)), - if (body != null) Expanded(child: body!), - ], - ), - ), + child: noBackground + ? content + : AppBackground(isRoot: true, child: content), ), appBar: appBar, bottomNavigationBar: bottomNavigationBar,