Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 71 additions & 45 deletions apps/client/lib/src/widgets/chat_panel/chat_panel_body.dart
Original file line number Diff line number Diff line change
Expand Up @@ -146,26 +146,83 @@ class ChatPanelBodyParams {
final ValueChanged<String>? onConversationSelected;
}

Widget buildChatContentBox(
/// Column-mode visibility branches on viewport width:
///
/// • >= 900 px → desktop side-rail beside the chat (`useColumn`).
/// • < 900 px → Discord-style edge-swipe drawer (`useColumnDrawer`).
///
/// Both surfaces feed off the same channel state and the same join /
/// text-channel callbacks, so behaviour is consistent between layouts
/// (#prod-column-layout-2026-05-20).
class _ColumnLayoutDecision {
final bool useColumn;
final bool useColumnDrawer;

const _ColumnLayoutDecision({
required this.useColumn,
required this.useColumnDrawer,
});
}

_ColumnLayoutDecision _resolveColumnLayout(
BuildContext context,
WidgetRef ref,
ChatPanelBodyParams p,
) {
final chatGradient = context.chatBgGradient;
// Column-mode visibility branches on viewport width:
//
// • >= 900 px → desktop side-rail beside the chat (`useColumn`).
// • < 900 px → Discord-style edge-swipe drawer
// (`useColumnDrawer`).
//
// Both surfaces feed off the same channel state and the same join /
// text-channel callbacks, so behaviour is consistent between layouts
// (#prod-column-layout-2026-05-20).
final layout = ref.watch(channelLayoutProvider);
final width = MediaQuery.of(context).size.width;
final columnRequested = layout == ChannelLayout.column && p.conv.isGroup;
final useColumn = columnRequested && width >= 900;
final useColumnDrawer = columnRequested && width < 900;
return _ColumnLayoutDecision(
useColumn: columnRequested && width >= 900,
useColumnDrawer: columnRequested && width < 900,
);
}

Widget _wrapForColumnLayout(
Widget chatArea,
ChatPanelBodyParams p,
_ColumnLayoutDecision dec,
) {
if (dec.useColumn) {
return Row(
children: [
ChannelColumn(
conversation: p.conv,
selectedTextChannelId: p.selectedTextChannelId,
onTextChannelChanged: p.onTextChannelChanged,
onShowLounge: p.onShowLounge,
),
Expanded(child: chatArea),
],
);
}
if (dec.useColumnDrawer && p.onConversationSelected != null) {
// Inner Scaffold so the Drawer's built-in edge-swipe gesture works
// without colliding with the outer narrow-layout Scaffold.
return Scaffold(
backgroundColor: Colors.transparent,
drawer: MobileChannelDrawer(
conversation: p.conv,
selectedTextChannelId: p.selectedTextChannelId,
onTextChannelChanged: p.onTextChannelChanged,
onConversationSelected: p.onConversationSelected!,
onShowLounge: p.onShowLounge,
),
body: chatArea,
);
}
return chatArea;
}

Widget buildChatContentBox(
BuildContext context,
WidgetRef ref,
ChatPanelBodyParams p,
) {
final chatGradient = context.chatBgGradient;
final dec = _resolveColumnLayout(context, ref, p);
final useColumn = dec.useColumn;
final useColumnDrawer = dec.useColumnDrawer;
final chatArea = DecoratedBox(
decoration: chatGradient != null
? BoxDecoration(gradient: chatGradient)
Expand Down Expand Up @@ -337,36 +394,5 @@ Widget buildChatContentBox(
),
);

if (useColumn) {
return Row(
children: [
ChannelColumn(
conversation: p.conv,
selectedTextChannelId: p.selectedTextChannelId,
onTextChannelChanged: p.onTextChannelChanged,
onShowLounge: p.onShowLounge,
),
Expanded(child: chatArea),
],
);
}
if (useColumnDrawer && p.onConversationSelected != null) {
// Inner Scaffold so the Drawer's built-in edge-swipe gesture works
// without colliding with the outer narrow-layout Scaffold. The
// outer one already handles the back-to-conversations swipe; in
// column mode that gesture is suppressed by the home screen so
// this one wins.
return Scaffold(
backgroundColor: Colors.transparent,
drawer: MobileChannelDrawer(
conversation: p.conv,
selectedTextChannelId: p.selectedTextChannelId,
onTextChannelChanged: p.onTextChannelChanged,
onConversationSelected: p.onConversationSelected!,
onShowLounge: p.onShowLounge,
),
body: chatArea,
);
}
return chatArea;
return _wrapForColumnLayout(chatArea, p, dec);
}
Loading