11import 'dart:async' ;
22import 'package:flutter/material.dart' ;
33import 'package:mobile/controllers/chat.dart' ;
4+ import 'package:mobile/pages/chat_page.dart' ;
5+ import 'package:mobile/providers/group_controller_provider.dart' ;
46import 'package:provider/provider.dart' ;
57
68class SelectContactPage extends StatefulWidget {
@@ -15,7 +17,9 @@ class _SelectContactPageState extends State<SelectContactPage> {
1517
1618 Timer ? _debounceTimer;
1719 bool _isSearchOpen = false ;
20+
1821 final _searchController = TextEditingController ();
22+ final _groupNameController = TextEditingController ();
1923
2024 void _onSearchChanged (String value, ChatController chatState) {
2125 if (_debounceTimer? .isActive ?? false ) _debounceTimer! .cancel ();
@@ -42,6 +46,7 @@ class _SelectContactPageState extends State<SelectContactPage> {
4246 void dispose () {
4347 _debounceTimer? .cancel ();
4448 _searchController.dispose ();
49+ _groupNameController.dispose ();
4550 super .dispose ();
4651 }
4752
@@ -270,7 +275,6 @@ class _SelectContactPageState extends State<SelectContactPage> {
270275 ),
271276 ),
272277 ],
273-
274278 const Padding (
275279 padding: EdgeInsets .only (left: 16 , top: 20 , bottom: 8 ),
276280 child: Text (
@@ -282,7 +286,6 @@ class _SelectContactPageState extends State<SelectContactPage> {
282286 ),
283287 ),
284288 ),
285-
286289 if (chatState.inbox.isNotEmpty)
287290 ...chatState.inbox
288291 .where (
@@ -304,10 +307,136 @@ class _SelectContactPageState extends State<SelectContactPage> {
304307 ),
305308 floatingActionButton: _selectedContacts.isNotEmpty
306309 ? FloatingActionButton (
307- onPressed: () {},
308310 backgroundColor: Colors .blue,
309311 elevation: 4 ,
310312 child: const Icon (Icons .arrow_forward, color: Colors .white),
313+ onPressed: () {
314+ context.read <GroupController >().addContacts (_selectedContacts);
315+
316+ showModalBottomSheet (
317+ context: context,
318+ isScrollControlled: true ,
319+ shape: const RoundedRectangleBorder (
320+ borderRadius: BorderRadius .vertical (
321+ top: Radius .circular (16 ),
322+ ),
323+ ),
324+ builder: (BuildContext bottomSheetContext) {
325+ return Consumer <GroupController >(
326+ builder: (context, groupState, child) {
327+ return Padding (
328+ padding: EdgeInsets .only (
329+ bottom: MediaQuery .of (
330+ bottomSheetContext,
331+ ).viewInsets.bottom,
332+ left: 16 ,
333+ right: 16 ,
334+ top: 24 ,
335+ ),
336+ child: Column (
337+ mainAxisSize: MainAxisSize .min,
338+ children: [
339+ const Text (
340+ 'New Group' ,
341+ style: TextStyle (
342+ fontSize: 18 ,
343+ fontWeight: FontWeight .bold,
344+ ),
345+ ),
346+ const SizedBox (height: 16 ),
347+ TextField (
348+ controller: _groupNameController,
349+ autofocus: true ,
350+ decoration: const InputDecoration (
351+ hintText: 'Enter group name' ,
352+ border: OutlineInputBorder (),
353+ ),
354+ ),
355+ const SizedBox (height: 16 ),
356+ Row (
357+ mainAxisAlignment: MainAxisAlignment .end,
358+ children: [
359+ FilledButton (
360+ onPressed: groupState.isLoading
361+ ? null
362+ : () async {
363+ final groupName =
364+ _groupNameController.text
365+ .trim ();
366+ if (groupName.isEmpty) return ;
367+
368+ final memberIds = _selectedContacts
369+ .keys
370+ .toList ();
371+
372+ final newGroup = await context
373+ .read <GroupController >()
374+ .createGroup (
375+ groupName: groupName,
376+ memberIds: memberIds,
377+ );
378+
379+ if (newGroup != null ) {
380+ if (! context.mounted) return ;
381+
382+ context
383+ .read <ChatController >()
384+ .loadInbox ();
385+
386+ Navigator .of (
387+ bottomSheetContext,
388+ ).pop ();
389+ Navigator .of (
390+ context,
391+ ).pushReplacement (
392+ MaterialPageRoute (
393+ builder: (context) => ChatPage (
394+ chatUserId: newGroup
395+ .id,
396+ displayName: newGroup
397+ .name,
398+ ),
399+ ),
400+ );
401+
402+ context
403+ .read <ChatController >()
404+ .openChat (newGroup.id);
405+ } else {
406+ if (! context.mounted) return ;
407+ ScaffoldMessenger .of (
408+ context,
409+ ).showSnackBar (
410+ const SnackBar (
411+ content: Text (
412+ 'Failed to create group' ,
413+ ),
414+ ),
415+ );
416+ }
417+ },
418+ child: groupState.isLoading
419+ ? const SizedBox (
420+ height: 20 ,
421+ width: 20 ,
422+ child: CircularProgressIndicator (
423+ color: Colors .white,
424+ strokeWidth: 2 ,
425+ ),
426+ )
427+ : const Text ('Create' ),
428+ ),
429+ ],
430+ ),
431+ const SizedBox (height: 16 ),
432+ ],
433+ ),
434+ );
435+ },
436+ );
437+ },
438+ );
439+ },
311440 )
312441 : null ,
313442 );
0 commit comments