import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:mohem_flutter_app/api/chat/chat_api_client.dart'; import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/chat/create_group_request.dart'; import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart'; import 'package:mohem_flutter_app/models/chat/get_user_groups_by_id.dart' as groups; import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; import 'package:mohem_flutter_app/models/worklist/get_favorite_replacements_model.dart'; import 'package:mohem_flutter_app/models/worklist/replacement_list_model.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart'; import 'package:provider/provider.dart'; class CreateGroupBottomSheet extends StatefulWidget { int? notificationID; String title, apiMode; List? actionHistoryList; Function(ReplacementList) onSelectEmployee; bool fromChat; groups.GroupResponse groupDetails; CreateGroupBottomSheet({ Key? key, required this.title, required this.apiMode, this.notificationID, this.actionHistoryList, required this.onSelectEmployee, required this.fromChat, required this.groupDetails, }) : super(key: key); @override State createState() => _CreateGroupBottomSheetState(); } class _CreateGroupBottomSheetState extends State { TextEditingController username = TextEditingController(); ScrollController sc = ScrollController(); bool isAudioCall = true; bool isVideoCall = true; bool isAttachments = true; bool isShareScreen = true; String searchText = ""; String groupName = ""; List? optionsList = [ LocaleKeys.fullName.tr(), LocaleKeys.username.tr(), LocaleKeys.endDate.tr(), ]; List? favUsersList; List? replacementList; List? favouriteUserList; List? nonFavouriteUserList; // Chat Items late ChatProviderModel provider; int _selectedSearchIndex = 0; List selectedUsers = []; void fetchUserByInput({bool isNeedLoading = true}) async { try { Utils.showLoading(context); replacementList = await WorkListApiClient().searchUserByInput( userName: _selectedSearchIndex == 0 ? searchText : "", userId: _selectedSearchIndex == 1 ? searchText : "", email: _selectedSearchIndex == 2 ? searchText : "", ); favouriteUserList = replacementList ?.where((ReplacementList element) => element.isFavorite ?? false) .toList(); nonFavouriteUserList = replacementList ?.where((ReplacementList element) => !(element.isFavorite ?? false)) .toList(); Utils.hideLoading(context); setState(() {}); } catch (e) { Utils.hideLoading(context); Utils.handleException(e, context, null); } if (isNeedLoading) Utils.hideLoading(context); setState(() {}); return null; } void fetchChatUser({bool isNeedLoading = true}) async { if (provider.pageNo == 1) provider.chatUsersList!.clear(); try { Utils.showLoading(context); await ChatApiClient() .getChatMemberFromSearch(searchText, AppState().chatDetails!.response!.id!, provider.pageNo) .then((ChatUserModel value) { if (value.response != null) { if (provider.pageNo == 1) { provider.chatUsersList = value.response; } else { print("--------------------------Added More----------------------"); provider.chatUsersList!.addAll(value.response!); } } }); provider.chatUsersList!.removeWhere((ChatUser element) => element.id == AppState().chatDetails!.response!.id); Utils.hideLoading(context); setState(() {}); } catch (e) { Utils.hideLoading(context); Utils.handleException(e, context, null); } if (isNeedLoading) Utils.hideLoading(context); setState(() {}); return null; } void scrollListener() async { if (sc.position.pixels == sc.position.maxScrollExtent) { provider.pageNo++; logger.w(provider.chatUsersList!.length); logger.w(provider.pageNo); fetchChatUser(); } } @override void initState() { super.initState(); sc.addListener(scrollListener); provider = Provider.of(context, listen: false); if (widget.groupDetails.groupName !=null) { setState(() { groupName = widget.groupDetails.groupName!; isAudioCall = widget.groupDetails.canAudioC!; isVideoCall = widget.groupDetails.canVideoC!; isAttachments = widget.groupDetails.canAttach!; isShareScreen = widget.groupDetails.canShareS!; for (groups.GroupUserList items in widget.groupDetails.groupUserList!) { { selectedUsers.add(ChatUser.fromJson(items.toJson())); } } }); } } @override void dispose() { super.dispose(); provider.chatUsersList = []; provider.pageNo = 1; } @override Widget build(BuildContext context) { return SizedBox( width: double.infinity, height: MediaQuery.of(context).size.height - 100, child: Column( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ widget.title.toText24(isBold: true), 21.height, Row( children: [ DynamicTextFieldWidget( "Group Name", groupName.isEmpty ? "Please enter group name" : groupName, inputAction: TextInputAction.done, onChange: (String text) { groupName = text; setState(() {}); }, ).expanded, ], ), //11.height, Row( children: [ SizedBox( height: 35, child: CheckboxListTile( contentPadding: EdgeInsets.zero, title: "Audio Call".toText10(), checkboxShape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), side: BorderSide( width: 1.5, color: Theme.of(context).unselectedWidgetColor), value: isAudioCall, onChanged: (bool? newValue) { setState(() { isAudioCall = newValue!; }); }, controlAffinity: ListTileControlAffinity .leading, // <-- leading Checkbox )).expanded, SizedBox( height: 35, child: CheckboxListTile( contentPadding: EdgeInsets.zero, title: "Video Call".toText10(), checkboxShape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), value: isVideoCall, onChanged: (bool? newValue) { setState(() { isVideoCall = newValue!; }); }, controlAffinity: ListTileControlAffinity .leading, // <-- leading Checkbox )).expanded ], ), Row( children: [ SizedBox( height: 35, child: CheckboxListTile( contentPadding: EdgeInsets.zero, title: "Attachments".toText10(), checkboxShape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), value: isAttachments, onChanged: (bool? newValue) { setState(() { isAttachments = newValue!; }); }, controlAffinity: ListTileControlAffinity .leading, // <-- leading Checkbox )).expanded, SizedBox( height: 35, child: CheckboxListTile( contentPadding: EdgeInsets.zero, checkboxShape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), title: "Share Screen".toText10(), value: isShareScreen, onChanged: (bool? newValue) { setState(() { isShareScreen = newValue!; }); }, controlAffinity: ListTileControlAffinity .leading, // <-- leading Checkbox )).expanded ], ), 11.height, "User Search".toText16(), 11.height, Row( children: [ radioOption(widget.fromChat ? "UserId" : "Name", 0, _selectedSearchIndex), radioOption("User Name", 1, _selectedSearchIndex), radioOption("Email", 2, _selectedSearchIndex), ], ), 14.height, Row( children: [ DynamicTextFieldWidget( "Search", "Search By Username", inputAction: TextInputAction.done, suffixIconData: Icons.search, onChange: (String text) { searchText = text; setState(() {}); }, ).expanded, IconButton( constraints: const BoxConstraints(), onPressed: () async { await SystemChannels.textInput .invokeMethod('TextInput.hide'); widget.fromChat ? fetchChatUser() : fetchUserByInput(); }, icon: const Icon(Icons.search), ) ], ), if (replacementList != null) replacementList!.isEmpty ? Utils.getNoDataWidget(context).expanded : ListView( physics: const BouncingScrollPhysics(), padding: EdgeInsets.only(top: 21, bottom: 8), children: [ if (favouriteUserList?.isNotEmpty ?? false) ...[ "Favorites".toText16(), 12.height, ListView.separated( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemBuilder: (BuildContext cxt, int index) => employeeItemView(favouriteUserList![index]), separatorBuilder: (BuildContext cxt, int index) => Container( height: 1, color: MyColors.borderE3Color, ), itemCount: favouriteUserList?.length ?? 0), 12.height, ], if (nonFavouriteUserList?.isNotEmpty ?? false) ...[ "Related".toText16(), 12.height, ListView.separated( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemBuilder: (BuildContext cxt, int index) => employeeItemView( nonFavouriteUserList![index]), separatorBuilder: (BuildContext cxt, int index) => Container( height: 1, color: MyColors.borderE3Color, ), itemCount: nonFavouriteUserList?.length ?? 0), ], ], ).expanded, selectedUsers!.isNotEmpty ? SizedBox( height: 95, child: ListView.builder( physics: const ClampingScrollPhysics(), scrollDirection: Axis.horizontal, itemCount: selectedUsers!.length, itemBuilder: (BuildContext context, int index2) { return Stack(children: [ Column( children: [ 12.height, Stack(children: [ Container( padding:const EdgeInsets.all(5), child: SvgPicture.asset( "assets/images/user.svg", height: 48, width: 48, )), Positioned( right: 0, top: 0, child: InkWell( child: SvgPicture.asset( 'assets/icons/close.svg', height:15, width:15 ), onTap: () { setState(() { // provider.chatUsersList![index] // .isChecked = false; List user = provider .chatUsersList! .where((ChatUser value) => value.userName == selectedUsers[index2] .userName) .toList(); if (user.isNotEmpty) { user.first.isChecked = false; } selectedUsers.remove( selectedUsers[index2]); }); }, )) ],), (selectedUsers![index2] .userName! .replaceFirst(".", " ") .capitalizeFirstofEach ?? "") .toText12(color: MyColors.darkTextColor) .paddingOnly(left: 5, top: 5), selectedUsers![index2].isTyping! ? 'Typing...' .toText10( color: MyColors.textMixColor, ) .paddingOnly(left: 5.0) : const SizedBox() ], ), // IconButton(onPressed: (){}, icon: const Icon(Icons.close_outlined, color: Colors.red, size: 20)), ]); })) : 0.height, if (widget.fromChat) if (provider.chatUsersList != null && widget.fromChat) provider.chatUsersList!.isEmpty ? Column( children: [ 20.height, Utils.getNoDataWidget(context), ], ) : ListView.separated( itemCount: provider.chatUsersList!.length, shrinkWrap: true, physics: const ClampingScrollPhysics(), controller: sc, padding: const EdgeInsets.only(bottom: 80.0, top: 20), itemBuilder: (BuildContext context, int index) { return SizedBox( height: 55, child: Row( children: [ Stack( children: [ SvgPicture.asset( "assets/images/user.svg", height: 48, width: 48, ), Positioned( right: 5, bottom: 1, child: Container( width: 10, height: 10, decoration: BoxDecoration( color: provider .chatUsersList![index] .userStatus == 1 ? MyColors.green2DColor : Colors.red, ), ).circle(10), ) ], ), Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ (provider.chatUsersList![index].userName! .replaceFirst(".", " ") .capitalizeFirstofEach ?? "") .toText14( color: MyColors.darkTextColor) .paddingOnly(left: 11, top: 13), provider.chatUsersList![index].isTyping! ? 'Typing...' .toText10( color: MyColors.textMixColor, ) .paddingOnly(left: 11.0) : const SizedBox() ], ).expanded, SizedBox( width: 60, child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.end, mainAxisSize: MainAxisSize.max, children: [ if (provider.chatUsersList![index] .unreadMessageCount! > 0) Container( alignment: Alignment.center, width: 18, height: 18, decoration: const BoxDecoration( color: MyColors.redColor, borderRadius: BorderRadius.all( Radius.circular(20), ), ), child: (provider .chatUsersList![index] .unreadMessageCount! .toString()) .toText10( color: MyColors.white, ) .center, ).paddingOnly(right: 10).center, Checkbox( value: provider .chatUsersList![index].isChecked, shape: CircleBorder(), onChanged: (bool? value) { setState(() { provider.chatUsersList![index] .isChecked = value; if (provider.chatUsersList![index] .isChecked == true) { selectedUsers.add(provider .chatUsersList![index]); } else { selectedUsers.remove(provider .chatUsersList![index]); } }); }, ) ], ), ), ], ), ); }, separatorBuilder: (BuildContext context, int index) => const Divider(color: MyColors.lightGreyE5Color) .paddingOnly(left: 59), ).expanded, ], ).paddingOnly(left: 21, right: 21, bottom: 0, top: 21).expanded, Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ DefaultButton( LocaleKeys.cancel.tr(), () { Navigator.pop(context); provider.chatUsersList = []; provider.pageNo = 1; }, textColor: MyColors.grey3AColor, colors: const [ Color(0xffE6E6E6), Color(0xffE6E6E6), ], ).paddingOnly(left: 14, right: 14, bottom: 15, top: 10).expanded, DefaultButton( LocaleKeys.submit.tr(), () { // Navigator.pop(context); // provider.chatUsersList = []; // provider.pageNo = 1; createGroup(); }, textColor: MyColors.whiteColor, colors: const [ Color(0xff32D892), Color(0xff1AB170), ], ).paddingOnly(left: 15, right: 15, bottom: 15, top: 10).expanded, ], ) ], ), ); } Widget employeeItemView(ReplacementList replacement) { return InkWell( onTap: () { Navigator.pop(context); widget.onSelectEmployee(replacement); }, child: SizedBox( height: 50, child: Row( children: [ CircularAvatar( url: replacement.employeeImage ?? "", height: 30, width: 30, isImageBase64: true, ), 16.width, Expanded( child: (replacement.employeeDisplayName ?? "").toText12(), ), Icon(Icons.star, size: 16, color: replacement.isFavorite! ? MyColors.yellowFavColor : MyColors.borderCEColor), ], ), ), ); } Widget radioOption(String title, int value, int groupValue) { return Row( children: [ Container( width: 24, height: 24, decoration: BoxDecoration( color: Colors.transparent, border: Border.all(color: MyColors.borderColor, width: 1), borderRadius: const BorderRadius.all( Radius.circular(100), ), ), padding: const EdgeInsets.all(4), child: Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( color: value == groupValue ? MyColors.grey3AColor : Colors.transparent, borderRadius: const BorderRadius.all( Radius.circular(100), ), ), ), ), 9.width, title.toText12(color: MyColors.grey57Color) ], ).onPress(() { _selectedSearchIndex = value; setState(() {}); }).expanded; } void createGroup() async { RegExp validCharacters = RegExp(r'^[a-zA-Z0-9_\-=@,\.;]+$'); if (!validCharacters.hasMatch(groupName)) { Utils.showToast("Please enter valid group Name"); } else if (groupName.length < 10) { Utils.showToast("Group name should be minimum 10 character long"); } else { List? mainUsers = []; ChatUser admin = ChatUser.fromJson(AppState().chatDetails!.response!.toJson()); admin.isAdmin = true; admin.userStatus = 2; admin.unreadMessageCount = 0; admin.totalCount = 0; mainUsers.add(admin); CreateGroupRequest request = CreateGroupRequest( groupUserList: [...selectedUsers, ...mainUsers].toList(), canArchive: false, isMeeting: false, canShareS: isShareScreen, canAudioC: isAudioCall, canAttach: isAttachments, canVideoC: isVideoCall, groupName: groupName, adminUserId: AppState().chatDetails!.response!.id); if(widget.groupDetails!.groupId !=null){ request.groupId =widget.groupDetails!.groupId; await provider.updateGroupAndUsers(request); }else { await provider.addGroupAndUsers(request); } Navigator.pop(context); } } }