Skip to content

Commit 8488c74

Browse files
committed
Show create group dialog when no groups exist
Introduces a CreateGroupDialog that prompts users to create a new group if none exist when adding a contact to a group. The dialog integrates with NewGroupChatSheet, allowing pre-selection of the contact to be added. Updates NewGroupChatSheet to support pre-selected contacts and refactors related logic in add_to_group_screen.dart.
1 parent f1cce74 commit 8488c74

File tree

3 files changed

+196
-3
lines changed

3 files changed

+196
-3
lines changed

lib/ui/chat/chat_management/add_to_group_screen.dart

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@ import 'package:flutter/material.dart';
22
import 'package:flutter_riverpod/flutter_riverpod.dart';
33
import 'package:gap/gap.dart';
44
import 'package:whitenoise/config/extensions/toast_extension.dart';
5+
import 'package:whitenoise/config/providers/follows_provider.dart';
56
import 'package:whitenoise/config/providers/group_provider.dart';
7+
import 'package:whitenoise/config/providers/user_profile_data_provider.dart';
8+
import 'package:whitenoise/domain/models/contact_model.dart';
69
import 'package:whitenoise/src/rust/api/groups.dart';
10+
import 'package:whitenoise/ui/chat/chat_management/widgets/create_group_dialog.dart';
11+
import 'package:whitenoise/ui/contact_list/new_group_chat_sheet.dart';
712
import 'package:whitenoise/ui/core/themes/assets.dart';
813
import 'package:whitenoise/ui/core/themes/src/app_theme.dart';
914
import 'package:whitenoise/ui/core/ui/wn_avatar.dart';
@@ -41,6 +46,13 @@ class _AddToGroupScreenState extends ConsumerState<AddToGroupScreen> {
4146

4247
final regularGroups = await ref.read(groupsProvider.notifier).getRegularGroups();
4348
if (regularGroups.isEmpty) {
49+
setState(() {
50+
_isLoading = false;
51+
});
52+
// Show dialog when no groups exist
53+
if (mounted) {
54+
_showCreateGroupDialog();
55+
}
4456
return;
4557
}
4658

@@ -108,6 +120,52 @@ class _AddToGroupScreenState extends ConsumerState<AddToGroupScreen> {
108120
});
109121
}
110122

123+
void _showCreateGroupDialog() {
124+
CreateGroupDialog.show(
125+
context,
126+
onCreateGroup: () async {
127+
Navigator.of(context).pop();
128+
Navigator.of(context).pop();
129+
130+
// Get contact information for the user to be added
131+
ContactModel? contactToAdd;
132+
try {
133+
// First try to get from follows (cached contacts)
134+
final followsNotifier = ref.read(followsProvider.notifier);
135+
final existingFollow = followsNotifier.findFollowByPubkey(widget.contactNpub);
136+
137+
if (existingFollow != null) {
138+
contactToAdd = ContactModel.fromMetadata(
139+
pubkey: existingFollow.pubkey,
140+
metadata: existingFollow.metadata,
141+
);
142+
} else {
143+
// If not in follows, fetch directly from user profile data provider
144+
final userProfileDataNotifier = ref.read(userProfileDataProvider.notifier);
145+
contactToAdd = await userProfileDataNotifier.getUserProfileData(widget.contactNpub);
146+
}
147+
} catch (e) {
148+
// Create a basic contact model with just the public key
149+
contactToAdd = ContactModel(
150+
displayName: 'Unknown User',
151+
publicKey: widget.contactNpub,
152+
);
153+
}
154+
155+
if (mounted) {
156+
NewGroupChatSheet.show(
157+
context,
158+
preSelectedContacts: contactToAdd != null ? [contactToAdd] : null,
159+
);
160+
}
161+
},
162+
onCancel: () {
163+
Navigator.of(context).pop();
164+
Navigator.of(context).pop();
165+
},
166+
);
167+
}
168+
111169
@override
112170
Widget build(BuildContext context) {
113171
return Scaffold(
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import 'dart:ui';
2+
import 'package:flutter/material.dart';
3+
import 'package:flutter_screenutil/flutter_screenutil.dart';
4+
import 'package:gap/gap.dart';
5+
import 'package:whitenoise/domain/models/contact_model.dart';
6+
import 'package:whitenoise/ui/core/themes/src/extensions.dart';
7+
import 'package:whitenoise/ui/core/ui/wn_button.dart';
8+
9+
class CreateGroupDialog extends StatelessWidget {
10+
final VoidCallback? onCreateGroup;
11+
final VoidCallback? onCancel;
12+
final ContactModel? contactToAdd;
13+
14+
const CreateGroupDialog({
15+
super.key,
16+
this.onCreateGroup,
17+
this.onCancel,
18+
this.contactToAdd,
19+
});
20+
21+
@override
22+
Widget build(BuildContext context) {
23+
return BackdropFilter(
24+
filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0),
25+
child: AlertDialog(
26+
backgroundColor: context.colors.surface,
27+
shape: const RoundedRectangleBorder(
28+
borderRadius: BorderRadius.zero,
29+
),
30+
insetPadding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 24.h),
31+
contentPadding: EdgeInsets.zero,
32+
content: SizedBox(
33+
width: MediaQuery.of(context).size.width,
34+
child: Container(
35+
padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 20.h),
36+
child: Column(
37+
mainAxisSize: MainAxisSize.min,
38+
children: [
39+
Row(
40+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
41+
children: [
42+
Text(
43+
'Create a Group to Continue',
44+
style: context.textTheme.bodyLarge?.copyWith(
45+
color: context.colors.primary,
46+
fontSize: 18.sp,
47+
fontWeight: FontWeight.w600,
48+
),
49+
),
50+
GestureDetector(
51+
onTap: onCancel ?? () => Navigator.of(context).pop(),
52+
child: Icon(
53+
Icons.close,
54+
size: 16.w,
55+
color: context.colors.mutedForeground,
56+
),
57+
),
58+
],
59+
),
60+
Gap(8.h),
61+
62+
Text(
63+
'You are not a member of any groups. Make a new group to add someone.',
64+
style: context.textTheme.bodyMedium?.copyWith(
65+
color: context.colors.mutedForeground,
66+
fontSize: 14.sp,
67+
height: 1.4,
68+
),
69+
textAlign: TextAlign.left,
70+
),
71+
Gap(16.h),
72+
73+
Column(
74+
children: [
75+
WnFilledButton(
76+
onPressed: onCancel ?? () => Navigator.of(context).pop(),
77+
label: 'Cancel',
78+
visualState: WnButtonVisualState.secondary,
79+
size: WnButtonSize.small,
80+
labelTextStyle: TextStyle(
81+
fontSize: 16.sp,
82+
fontWeight: FontWeight.w600,
83+
),
84+
),
85+
Gap(12.h),
86+
WnFilledButton(
87+
onPressed: onCreateGroup,
88+
label: 'New Group Chat',
89+
size: WnButtonSize.small,
90+
labelTextStyle: TextStyle(
91+
fontSize: 16.sp,
92+
fontWeight: FontWeight.w600,
93+
),
94+
),
95+
],
96+
),
97+
],
98+
),
99+
),
100+
),
101+
),
102+
);
103+
}
104+
105+
static Future<bool?> show(
106+
BuildContext context, {
107+
VoidCallback? onCreateGroup,
108+
VoidCallback? onCancel,
109+
ContactModel? contactToAdd,
110+
}) {
111+
return showDialog<bool>(
112+
context: context,
113+
barrierDismissible: true,
114+
builder:
115+
(context) => CreateGroupDialog(
116+
onCreateGroup: onCreateGroup,
117+
onCancel: onCancel,
118+
contactToAdd: contactToAdd,
119+
),
120+
);
121+
}
122+
}

lib/ui/contact_list/new_group_chat_sheet.dart

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,28 @@ import 'package:whitenoise/ui/core/ui/wn_text_field.dart';
1515

1616
class NewGroupChatSheet extends ConsumerStatefulWidget {
1717
final ValueChanged<Group?>? onGroupCreated;
18+
final List<ContactModel>? preSelectedContacts;
1819

19-
const NewGroupChatSheet({super.key, this.onGroupCreated});
20+
const NewGroupChatSheet({super.key, this.onGroupCreated, this.preSelectedContacts});
2021

2122
@override
2223
ConsumerState<NewGroupChatSheet> createState() => _NewGroupChatSheetState();
2324

24-
static Future<void> show(BuildContext context, {ValueChanged<Group?>? onGroupCreated}) {
25+
static Future<void> show(
26+
BuildContext context, {
27+
ValueChanged<Group?>? onGroupCreated,
28+
List<ContactModel>? preSelectedContacts,
29+
}) {
2530
return WnBottomSheet.show(
2631
context: context,
2732
title: 'New group chat',
2833
blurSigma: 8.0,
2934
transitionDuration: const Duration(milliseconds: 400),
30-
builder: (context) => NewGroupChatSheet(onGroupCreated: onGroupCreated),
35+
builder:
36+
(context) => NewGroupChatSheet(
37+
onGroupCreated: onGroupCreated,
38+
preSelectedContacts: preSelectedContacts,
39+
),
3140
);
3241
}
3342
}
@@ -41,6 +50,10 @@ class _NewGroupChatSheetState extends ConsumerState<NewGroupChatSheet> {
4150
void initState() {
4251
super.initState();
4352
_searchController.addListener(_onSearchChanged);
53+
// Add pre-selected contacts to the selection
54+
if (widget.preSelectedContacts != null) {
55+
_selectedContacts.addAll(widget.preSelectedContacts!);
56+
}
4457
}
4558

4659
@override

0 commit comments

Comments
 (0)