From 6bc9fbd5b01276ad5a9970e7d7d0fa6653321822 Mon Sep 17 00:00:00 2001 From: Grafcube Date: Tue, 24 Feb 2026 19:49:45 +0530 Subject: [PATCH] Combine direct message and room creation --- .../home_screen/home_screen_view.dart | 13 ---- .../invitation_view/send_invitation.dart | 16 ++--- .../get_or_create_room.dart | 62 ++++++++++++++++++- .../ui/pages/main/main_page_view_desktop.dart | 12 ++-- .../ui/pages/main/main_page_view_mobile.dart | 13 ++-- 5 files changed, 86 insertions(+), 30 deletions(-) diff --git a/commet/lib/ui/organisms/home_screen/home_screen_view.dart b/commet/lib/ui/organisms/home_screen/home_screen_view.dart index f6def7809..3908699f9 100644 --- a/commet/lib/ui/organisms/home_screen/home_screen_view.dart +++ b/commet/lib/ui/organisms/home_screen/home_screen_view.dart @@ -1,16 +1,13 @@ import 'package:commet/client/client.dart'; import 'package:commet/client/client_manager.dart'; import 'package:commet/client/components/invitation/invitation.dart'; -import 'package:commet/config/build_config.dart'; import 'package:commet/ui/atoms/room_panel.dart'; import 'package:commet/ui/molecules/alert_view.dart'; import 'package:commet/ui/molecules/invitation_display.dart'; -import 'package:commet/ui/pages/get_or_create_room/get_or_create_room.dart'; import 'package:flutter/material.dart'; import 'package:implicitly_animated_list/implicitly_animated_list.dart'; import 'package:intl/intl.dart'; import 'package:tiamat/tiamat.dart'; -import 'package:tiamat/tiamat.dart' as tiamat; class HomeScreenView extends StatelessWidget { final ClientManager clientManager; @@ -168,11 +165,6 @@ class HomeScreenView extends StatelessWidget { ); }, ), - tiamat.CircleButton( - radius: BuildConfig.MOBILE ? 24 : 16, - icon: Icons.add, - onPressed: () => addRoomDialog(context), - ), ], )); } @@ -196,9 +188,4 @@ class HomeScreenView extends StatelessWidget { }, )); } - - void addRoomDialog(BuildContext context) { - GetOrCreateRoom.show(null, context, - pickExisting: false, showAllRoomTypes: true); - } } diff --git a/commet/lib/ui/organisms/invitation_view/send_invitation.dart b/commet/lib/ui/organisms/invitation_view/send_invitation.dart index 115cd3610..da9b13750 100644 --- a/commet/lib/ui/organisms/invitation_view/send_invitation.dart +++ b/commet/lib/ui/organisms/invitation_view/send_invitation.dart @@ -17,9 +17,11 @@ class SendInvitationWidget extends StatefulWidget { this.displayName, this.onUserPicked, this.showSuggestions = true, - this.existingMembers}); + this.existingMembers, + this.embedded = false}); final Client client; final bool showSuggestions; + final bool embedded; final Iterable? existingMembers; final Future Function(String userId)? onUserPicked; @@ -67,8 +69,8 @@ class _SendInvitationWidgetState extends State { child: IgnorePointer( ignoring: loading, child: ScaledSafeArea( - child: SizedBox( - width: 500, + child: Container( + width: widget.embedded ? null : 500, child: Column(children: [ tiamat.TextInput( controller: controller, @@ -77,8 +79,8 @@ class _SendInvitationWidgetState extends State { onChanged: onSearchTextChanged, ), if (isSearching || searchResults?.isNotEmpty == true) - SizedBox( - height: 300, + Container( + height: widget.embedded ? null : 300, child: isSearching ? const Center(child: CircularProgressIndicator()) : ListView.builder( @@ -159,7 +161,7 @@ class _SendInvitationWidgetState extends State { if (widget.onUserPicked != null) { await widget.onUserPicked?.call(userId); - if (mounted) Navigator.pop(context); + if (mounted && !widget.embedded) Navigator.pop(context); return; } @@ -173,6 +175,6 @@ class _SendInvitationWidgetState extends State { widget.component.inviteUserToRoom(userId: userId, roomId: widget.roomId!); - if (mounted) Navigator.pop(context); + if (mounted && !widget.embedded) Navigator.pop(context); } } diff --git a/commet/lib/ui/pages/get_or_create_room/get_or_create_room.dart b/commet/lib/ui/pages/get_or_create_room/get_or_create_room.dart index 58d164553..3438b9b48 100644 --- a/commet/lib/ui/pages/get_or_create_room/get_or_create_room.dart +++ b/commet/lib/ui/pages/get_or_create_room/get_or_create_room.dart @@ -1,8 +1,11 @@ import 'package:commet/client/client.dart'; +import 'package:commet/client/components/direct_messages/direct_message_component.dart'; +import 'package:commet/client/components/invitation/invitation_component.dart'; import 'package:commet/client/space_child.dart'; import 'package:commet/config/layout_config.dart'; import 'package:commet/debug/log.dart'; import 'package:commet/ui/navigation/adaptive_dialog.dart'; +import 'package:commet/ui/organisms/invitation_view/send_invitation.dart'; import 'package:commet/ui/pages/get_or_create_room/calendar_views.dart'; import 'package:commet/ui/pages/get_or_create_room/existing_room_picker.dart'; import 'package:commet/ui/pages/get_or_create_room/join_room_view.dart'; @@ -34,19 +37,21 @@ class RoomGetter { }); } -enum _RoomSourceOptions { create, existing, join } +enum _RoomSourceOptions { create, existing, startdm, join } class GetOrCreateRoom extends StatefulWidget { const GetOrCreateRoom( - {super.key, required this.creators, this.existing, this.join}); + {super.key, required this.creators, this.existing, this.dm, this.join}); final List creators; final RoomGetter? existing; + final RoomGetter? dm; final RoomGetter? join; static Future show( Client? client, BuildContext context, { + bool startdm = false, bool joinRoom = true, bool pickExisting = true, bool showAllRoomTypes = false, @@ -175,6 +180,40 @@ class GetOrCreateRoom extends StatefulWidget { ) : null; + final dm = startdm + ? RoomGetter( + label: "Start Direct Message", + hero: true, + icon: Icons.message, + descriptionBuilder: (_) => Placeholder(), + formBuilder: (context, {onPicked}) { + final invitation = client?.getComponent(); + if (invitation == null) return Placeholder(); + + return SendInvitationWidget( + client!, + invitation, + showSuggestions: false, + embedded: true, + onUserPicked: (userId) async { + final confirm = await AdaptiveDialog.confirmation(context, + prompt: + "Are you sure you want to invite $userId to chat?", + title: "Invitation"); + if (confirm != true) { + return; + } + + var comp = client!.getComponent(); + var room = await comp?.createDirectMessage(userId); + + if (room != null) onPicked!(SpaceChildRoom(room)); + }, + ); + }, + ) + : null; + final join = joinRoom ? RoomGetter( label: "Join Room", @@ -199,6 +238,7 @@ class GetOrCreateRoom extends StatefulWidget { items: [ _RoomSourceOptions.create, if (existing != null) _RoomSourceOptions.existing, + if (dm != null) _RoomSourceOptions.startdm, if (join != null) _RoomSourceOptions.join, ], itemBuilder: (context, item, callback) => SizedBox( @@ -214,6 +254,11 @@ class GetOrCreateRoom extends StatefulWidget { icon: Icons.tag, onTap: callback, ), + _RoomSourceOptions.startdm => tiamat.TextButton( + "Start Direct Message", + icon: Icons.message, + onTap: callback, + ), _RoomSourceOptions.join => tiamat.TextButton( "Join Room", icon: Icons.alternate_email, @@ -235,6 +280,17 @@ class GetOrCreateRoom extends StatefulWidget { ); } + if (source == _RoomSourceOptions.startdm) { + return AdaptiveDialog.show( + context, + scrollable: false, + builder: (context) { + return dm!.formBuilder(context, + onPicked: (i) => Navigator.of(context).pop(i)); + }, + ); + } + if (source == _RoomSourceOptions.join) { return AdaptiveDialog.show( context, @@ -269,6 +325,7 @@ class GetOrCreateRoom extends StatefulWidget { return GetOrCreateRoom( creators: creators, existing: existing, + dm: dm, join: join, ); }, @@ -355,6 +412,7 @@ class _GetOrCreateRoomState extends State { children: [ if (widget.existing != null) createEntry(widget.existing!), + if (widget.dm != null) createEntry(widget.dm!), if (widget.join != null) createEntry(widget.join!), if (widget.creators.isNotEmpty) tiamat.Text.labelLow("Create Room:"), diff --git a/commet/lib/ui/pages/main/main_page_view_desktop.dart b/commet/lib/ui/pages/main/main_page_view_desktop.dart index dcb1fb691..f7d689567 100644 --- a/commet/lib/ui/pages/main/main_page_view_desktop.dart +++ b/commet/lib/ui/pages/main/main_page_view_desktop.dart @@ -1,4 +1,5 @@ import 'package:commet/client/components/profile/profile_component.dart'; +import 'package:commet/config/build_config.dart'; import 'package:commet/config/layout_config.dart'; import 'package:commet/main.dart'; import 'package:commet/ui/atoms/adaptive_context_menu.dart'; @@ -17,6 +18,7 @@ import 'package:commet/ui/organisms/room_side_panel/room_side_panel.dart'; import 'package:commet/ui/organisms/side_navigation_bar/side_navigation_bar.dart'; import 'package:commet/ui/organisms/sidebar_call_icon/sidebar_calls_list.dart'; import 'package:commet/ui/organisms/space_summary/space_summary.dart'; +import 'package:commet/ui/pages/get_or_create_room/get_or_create_room.dart'; import 'package:commet/ui/pages/main/main_page.dart'; import 'package:commet/ui/pages/main/room_primary_view.dart'; import 'package:commet/ui/pages/settings/app_settings_page.dart'; @@ -414,11 +416,13 @@ class MainPageViewDesktop extends StatelessWidget { ), Padding( padding: const EdgeInsets.all(8.0), - child: tiamat.IconButton( + child: tiamat.CircleButton( + radius: BuildConfig.MOBILE ? 24 : 16, icon: Icons.add, - onPressed: () { - state.searchUserToDm(); - }, + onPressed: () => GetOrCreateRoom.show(null, context, + pickExisting: false, + showAllRoomTypes: true, + startdm: true), ), ), ], diff --git a/commet/lib/ui/pages/main/main_page_view_mobile.dart b/commet/lib/ui/pages/main/main_page_view_mobile.dart index f3923ea2b..5d2ddfec0 100644 --- a/commet/lib/ui/pages/main/main_page_view_mobile.dart +++ b/commet/lib/ui/pages/main/main_page_view_mobile.dart @@ -13,6 +13,7 @@ import 'package:commet/ui/organisms/room_side_panel/room_side_panel.dart'; import 'package:commet/ui/organisms/side_navigation_bar/side_navigation_bar.dart'; import 'package:commet/ui/organisms/sidebar_call_icon/sidebar_calls_list.dart'; import 'package:commet/ui/organisms/space_summary/space_summary.dart'; +import 'package:commet/ui/pages/get_or_create_room/get_or_create_room.dart'; import 'package:commet/ui/pages/main/main_page.dart'; import 'package:commet/ui/pages/main/main_page_view_desktop.dart'; import 'package:commet/ui/pages/main/room_primary_view.dart'; @@ -364,10 +365,14 @@ class _MainPageViewMobileState extends State { ), Padding( padding: const EdgeInsets.fromLTRB(8, 12, 8, 8), - child: tiamat.IconButton( - size: 18, - icon: Icons.add, - onPressed: widget.state.searchUserToDm), + child: tiamat.CircleButton( + radius: 18, + icon: Icons.add, + onPressed: () => GetOrCreateRoom.show(null, context, + pickExisting: false, + showAllRoomTypes: true, + startdm: true), + ), ), ], ),