init
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_friend_info.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/contact_list.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
GlobalKey<_AddGroupMemberPageState> addGroupMemberKey = GlobalKey();
|
||||
|
||||
class AddGroupMemberPage extends StatefulWidget {
|
||||
final TUIGroupProfileModel model;
|
||||
final VoidCallback? onClose;
|
||||
|
||||
const AddGroupMemberPage({Key? key, required this.model, this.onClose}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _AddGroupMemberPageState();
|
||||
}
|
||||
|
||||
class _AddGroupMemberPageState extends TIMUIKitState<AddGroupMemberPage> {
|
||||
List<V2TimFriendInfo> selectedContacts = [];
|
||||
|
||||
void submitAdd() async {
|
||||
if (selectedContacts.isNotEmpty) {
|
||||
final userIDs = selectedContacts.map((e) => e.userID).toList();
|
||||
await widget.model.inviteUserToGroup(userIDs);
|
||||
widget.onClose ?? Navigator.pop(context);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
|
||||
return TUIKitScreenUtils.getDeviceWidget(
|
||||
context: context,
|
||||
desktopWidget: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: ContactList(
|
||||
bgColor: theme.wideBackgroundColor,
|
||||
groupMemberList: widget.model.groupMemberList,
|
||||
contactList: widget.model.contactList,
|
||||
isCanSelectMemberItem: true,
|
||||
onSelectedMemberItemChange: (selectedMember) {
|
||||
selectedContacts = selectedMember;
|
||||
},
|
||||
),
|
||||
),
|
||||
defaultWidget: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
TIM_t("添加群成员"),
|
||||
style: TextStyle(color: theme.appbarTextColor, fontSize: 17),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
submitAdd();
|
||||
},
|
||||
child: Text(
|
||||
TIM_t("确定"),
|
||||
style: TextStyle(
|
||||
color: theme.appbarTextColor,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
shadowColor: theme.weakDividerColor,
|
||||
backgroundColor: theme.appbarBgColor ?? theme.primaryColor,
|
||||
iconTheme: IconThemeData(
|
||||
color: theme.appbarTextColor,
|
||||
)),
|
||||
body: ContactList(
|
||||
groupMemberList: widget.model.groupMemberList,
|
||||
contactList: widget.model.contactList,
|
||||
isCanSelectMemberItem: true,
|
||||
onSelectedMemberItemChange: (selectedMember) {
|
||||
selectedContacts = selectedMember;
|
||||
},
|
||||
)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/enum/group_member_role.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_member_full_info.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_search_param.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_member_search_param.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/group_member_list.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
GlobalKey<_DeleteGroupMemberPageState> deleteGroupMemberKey = GlobalKey();
|
||||
|
||||
class DeleteGroupMemberPage extends StatefulWidget {
|
||||
final TUIGroupProfileModel model;
|
||||
final VoidCallback? onClose;
|
||||
|
||||
const DeleteGroupMemberPage({Key? key, required this.model, this.onClose}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _DeleteGroupMemberPageState();
|
||||
}
|
||||
|
||||
class _DeleteGroupMemberPageState extends TIMUIKitState<DeleteGroupMemberPage> {
|
||||
List<V2TimGroupMemberFullInfo> selectedGroupMember = [];
|
||||
List<V2TimGroupMemberFullInfo?>? searchMemberList;
|
||||
|
||||
bool isSearchTextExist(String? searchText) {
|
||||
return searchText != null && searchText != "";
|
||||
}
|
||||
|
||||
handleSearchGroupMembers(String searchText, context) async {
|
||||
searchText = searchText;
|
||||
List<V2TimGroupMemberFullInfo?> currentGroupMember =
|
||||
Provider.of<TUIGroupProfileModel>(context, listen: false).groupMemberList;
|
||||
final res = await widget.model.searchGroupMember(V2TimGroupMemberSearchParam(
|
||||
keywordList: [searchText],
|
||||
groupIDList: [widget.model.groupInfo!.groupID],
|
||||
));
|
||||
|
||||
if (res.code == 0) {
|
||||
List<V2TimGroupMemberFullInfo?> list = [];
|
||||
final searchResult = res.data!.groupMemberSearchResultItems!;
|
||||
searchResult.forEach((key, value) {
|
||||
if (value is List) {
|
||||
for (V2TimGroupMemberFullInfo item in value) {
|
||||
list.add(item);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
currentGroupMember = list;
|
||||
} else {
|
||||
currentGroupMember = [];
|
||||
}
|
||||
setState(() {
|
||||
searchMemberList = isSearchTextExist(searchText) ? currentGroupMember : null;
|
||||
});
|
||||
}
|
||||
|
||||
handleRole(groupMemberList) {
|
||||
return groupMemberList
|
||||
?.where((value) => value?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER)
|
||||
.toList() ??
|
||||
[];
|
||||
}
|
||||
|
||||
void submitDelete() async {
|
||||
if (selectedGroupMember.isNotEmpty) {
|
||||
final userIDs = selectedGroupMember.map((e) => e.userID).toList();
|
||||
widget.model.kickOffMember(userIDs);
|
||||
widget.onClose ?? Navigator.pop(context);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
|
||||
return TUIKitScreenUtils.getDeviceWidget(
|
||||
context: context,
|
||||
desktopWidget: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: GroupProfileMemberList(
|
||||
memberList: handleRole(searchMemberList ?? widget.model.groupMemberList),
|
||||
canSelectMember: true,
|
||||
canSlideDelete: false,
|
||||
onSelectedMemberChange: (selectedMember) {
|
||||
selectedGroupMember = selectedMember;
|
||||
},
|
||||
touchBottomCallBack: () {},
|
||||
),
|
||||
),
|
||||
defaultWidget: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
TIM_t("删除群成员"),
|
||||
style: TextStyle(color: theme.appbarTextColor, fontSize: 17),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: submitDelete,
|
||||
child: Text(
|
||||
TIM_t("确定"),
|
||||
style: TextStyle(
|
||||
color: theme.appbarTextColor,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
shadowColor: theme.weakBackgroundColor,
|
||||
backgroundColor: theme.appbarBgColor ?? theme.primaryColor,
|
||||
iconTheme: IconThemeData(
|
||||
color: theme.appbarTextColor,
|
||||
)),
|
||||
body: GroupProfileMemberList(
|
||||
memberList: handleRole(searchMemberList ?? widget.model.groupMemberList),
|
||||
canSelectMember: true,
|
||||
canSlideDelete: false,
|
||||
onSelectedMemberChange: (selectedMember) {
|
||||
selectedGroupMember = selectedMember;
|
||||
},
|
||||
touchBottomCallBack: () {},
|
||||
)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_member_full_info.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_search_param.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_member_search_param.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_member_search.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/group_member_list.dart';
|
||||
|
||||
import '../../../../theme/tui_theme.dart';
|
||||
|
||||
class GroupProfileMemberListPage extends StatefulWidget {
|
||||
List<V2TimGroupMemberFullInfo?> memberList;
|
||||
TUIGroupProfileModel model;
|
||||
|
||||
GroupProfileMemberListPage({
|
||||
Key? key,
|
||||
required this.memberList,
|
||||
required this.model,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => GroupProfileMemberListPageState();
|
||||
}
|
||||
|
||||
class GroupProfileMemberListPageState extends TIMUIKitState<GroupProfileMemberListPage> {
|
||||
List<V2TimGroupMemberFullInfo?>? searchMemberList;
|
||||
String? searchText;
|
||||
|
||||
_kickedOffMember(String userID) async {
|
||||
widget.model.kickOffMember([userID]);
|
||||
}
|
||||
|
||||
bool isSearchTextExist(String? searchText) {
|
||||
return searchText != null && searchText != "";
|
||||
}
|
||||
|
||||
handleSearchGroupMembers(String searchText, context) async {
|
||||
searchText = searchText;
|
||||
List<V2TimGroupMemberFullInfo?> currentGroupMember =
|
||||
Provider.of<TUIGroupProfileModel>(context, listen: false).groupMemberList;
|
||||
|
||||
if (!isSearchTextExist(searchText)) {
|
||||
setState(() {
|
||||
searchMemberList = null;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
final res = await widget.model.searchGroupMember(V2TimGroupMemberSearchParam(
|
||||
keywordList: [searchText],
|
||||
groupIDList: [widget.model.groupInfo!.groupID],
|
||||
));
|
||||
|
||||
if (res.code == 0) {
|
||||
List<V2TimGroupMemberFullInfo?> list = [];
|
||||
final searchResult = res.data!.groupMemberSearchResultItems!;
|
||||
searchResult.forEach((key, value) {
|
||||
if (value is List) {
|
||||
for (V2TimGroupMemberFullInfo item in value) {
|
||||
list.add(item);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
currentGroupMember = list;
|
||||
} else {
|
||||
currentGroupMember = [];
|
||||
}
|
||||
setState(() {
|
||||
searchMemberList = currentGroupMember;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop;
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: widget.model),
|
||||
],
|
||||
builder: (BuildContext context, Widget? w) {
|
||||
final TUIGroupProfileModel groupProfileModel = Provider.of<TUIGroupProfileModel>(context);
|
||||
String option1 = groupProfileModel.groupInfo?.memberCount.toString() ?? widget.memberList.length.toString();
|
||||
if (isDesktopScreen) {
|
||||
return GroupProfileMemberList(
|
||||
customTopArea: PlatformUtils().isWeb
|
||||
? null
|
||||
: GroupMemberSearchTextField(
|
||||
onTextChange: (text) => handleSearchGroupMembers(text, context),
|
||||
),
|
||||
memberList: searchMemberList ?? groupProfileModel.groupMemberList,
|
||||
removeMember: _kickedOffMember,
|
||||
touchBottomCallBack: () {},
|
||||
onTapMemberItem: (memberInfo, details) {
|
||||
if (widget.model.onClickUser != null) {
|
||||
widget.model.onClickUser!(memberInfo, details);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
TIM_t_para("群成员({{option1}}人)", "群成员($option1人)")(option1: option1),
|
||||
style: TextStyle(color: theme.appbarTextColor, fontSize: 17),
|
||||
),
|
||||
shadowColor: theme.weakBackgroundColor,
|
||||
backgroundColor: theme.appbarBgColor ?? theme.primaryColor,
|
||||
iconTheme: IconThemeData(
|
||||
color: theme.appbarTextColor,
|
||||
)),
|
||||
body: GroupProfileMemberList(
|
||||
customTopArea: PlatformUtils().isWeb
|
||||
? null
|
||||
: GroupMemberSearchTextField(
|
||||
onTextChange: (text) => handleSearchGroupMembers(text, context),
|
||||
),
|
||||
memberList: searchMemberList ?? groupProfileModel.groupMemberList,
|
||||
removeMember: _kickedOffMember,
|
||||
touchBottomCallBack: () {},
|
||||
onTapMemberItem: (memberInfo, details) {
|
||||
if (widget.model.onClickUser != null) {
|
||||
widget.model.onClickUser!(memberInfo, details);
|
||||
}
|
||||
},
|
||||
));
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_info.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_member_full_info.dart';
|
||||
|
||||
enum GroupProfileWidgetEnum {
|
||||
/// The detail card for group.
|
||||
detailCard,
|
||||
|
||||
/// The tile shows the members in the group.
|
||||
memberListTile,
|
||||
|
||||
/// The entrance to the page editing the group notice.
|
||||
groupNotice,
|
||||
|
||||
/// The entrance to the page managing the group.
|
||||
/// Works only for group owner and group admin.
|
||||
groupManage,
|
||||
|
||||
/// The entrance to the search page with conversation ID.
|
||||
searchMessage,
|
||||
|
||||
/// The divider between sets of profile widget.
|
||||
operationDivider,
|
||||
|
||||
/// Shows the group type,
|
||||
/// includes "work group", "public group", "meeting group" and "AVChatRoom".
|
||||
groupTypeBar,
|
||||
|
||||
/// Shows and modify the mode or options users add the group.
|
||||
/// Includes "disallow group joining", "automatic approval" and "admin approval".
|
||||
groupJoiningModeBar,
|
||||
|
||||
/// Shows and modify the nickname for user in a specific group,
|
||||
/// only shows and used in this group, as the name card here.
|
||||
nameCardBar,
|
||||
|
||||
/// The switch of if mute the message notification from a specific group
|
||||
muteGroupMessageBar,
|
||||
|
||||
/// The switch of if pin this group to the top in conversation list.
|
||||
pinedConversationBar,
|
||||
|
||||
/// The button area, includes
|
||||
/// "clear chat history", "transfer group owner", "disband group" and "quit group"
|
||||
/// as default.
|
||||
buttonArea,
|
||||
|
||||
/// Custom area, you may define anything you want here.
|
||||
customBuilderOne,
|
||||
|
||||
/// Custom area, you may define anything you want here.
|
||||
customBuilderTwo,
|
||||
|
||||
/// Custom area, you may define anything you want here.
|
||||
customBuilderThree,
|
||||
|
||||
/// Custom area, you may define anything you want here.
|
||||
customBuilderFour,
|
||||
|
||||
/// Custom area, you may define anything you want here.
|
||||
customBuilderFive
|
||||
}
|
||||
|
||||
class GroupProfileWidgetBuilder {
|
||||
/// The detail card for group.
|
||||
Widget Function(V2TimGroupInfo groupInfo, Function(String updateGroupName)? updateGroupName)? detailCard;
|
||||
|
||||
/// The tile shows the members in the group.
|
||||
Widget Function(List<V2TimGroupMemberFullInfo?> memberList)? memberListTile;
|
||||
|
||||
/// The entrance to the page editing the group notice.
|
||||
Widget Function(String currentNotice, Function() toDefaultNoticeEditPage, Function(String newNotice) setGroupNotice)?
|
||||
groupNotice;
|
||||
|
||||
/// The entrance to the page managing the group.
|
||||
/// Works only for group owner and group admin.
|
||||
Widget Function(Function() toDefaultGroupManagementPage)? groupManage;
|
||||
|
||||
/// The entrance to the search page with conversation ID.
|
||||
Widget Function()? searchMessage;
|
||||
|
||||
/// The divider between sets of profile widget.
|
||||
Widget Function()? operationDivider;
|
||||
|
||||
/// Shows the group type,
|
||||
/// includes "work group", "public group", "meeting group" and "AVChatRoom".
|
||||
Widget Function(String groupType)? groupTypeBar;
|
||||
|
||||
/// Shows and modify the mode or options users add the group.
|
||||
/// Includes "0: disallow group joining", "1: admin approval" and "2: automatic approval".
|
||||
Widget Function(int groupAddOptType, Function(int addOpt) handleActionTap)? groupJoiningModeBar;
|
||||
|
||||
/// Shows and modify the nickname for user in a specific group,
|
||||
/// only shows and used in this group, as the name card here.
|
||||
Widget Function(String nameCard, Function(String newName) setNameCard)? nameCardBar;
|
||||
|
||||
/// The switch of if mute the message notification from a specific group.
|
||||
Widget Function(bool isMute, Function(bool isMute) setMute)? muteGroupMessageBar;
|
||||
|
||||
/// The switch of if pin this group to the top in conversation list.
|
||||
Widget Function(bool isPined, Function(bool isMute) pinedConversation)? pinedConversationBar;
|
||||
|
||||
/// The button area, includes
|
||||
/// "clear chat history", "transfer group owner", "disband group" and "quit group"
|
||||
/// as default.
|
||||
Widget Function(V2TimGroupInfo groupInfo, List<V2TimGroupMemberFullInfo?> groupMemberList)? buttonArea;
|
||||
|
||||
/// Custom area, you may define anything you want here.
|
||||
Widget Function(V2TimGroupInfo groupInfo, List<V2TimGroupMemberFullInfo?> groupMemberList)? customBuilderOne;
|
||||
|
||||
/// Custom area, you may define anything you want here.
|
||||
Widget Function(V2TimGroupInfo groupInfo, List<V2TimGroupMemberFullInfo?> groupMemberList)? customBuilderTwo;
|
||||
|
||||
/// Custom area, you may define anything you want here.
|
||||
Widget Function(V2TimGroupInfo groupInfo, List<V2TimGroupMemberFullInfo?> groupMemberList)? customBuilderThree;
|
||||
|
||||
/// Custom area, you may define anything you want here.
|
||||
Widget Function(V2TimGroupInfo groupInfo, List<V2TimGroupMemberFullInfo?> groupMemberList)? customBuilderFour;
|
||||
|
||||
/// Custom area, you may define anything you want here.
|
||||
Widget Function(V2TimGroupInfo groupInfo, List<V2TimGroupMemberFullInfo?> groupMemberList)? customBuilderFive;
|
||||
|
||||
GroupProfileWidgetBuilder(
|
||||
{this.detailCard,
|
||||
this.memberListTile,
|
||||
this.groupNotice,
|
||||
this.groupManage,
|
||||
this.searchMessage,
|
||||
this.operationDivider,
|
||||
this.groupTypeBar,
|
||||
this.groupJoiningModeBar,
|
||||
this.nameCardBar,
|
||||
this.muteGroupMessageBar,
|
||||
this.pinedConversationBar,
|
||||
this.buttonArea,
|
||||
this.customBuilderOne,
|
||||
this.customBuilderTwo,
|
||||
this.customBuilderThree,
|
||||
this.customBuilderFour,
|
||||
this.customBuilderFive});
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
|
||||
class SharedDataWidget extends InheritedWidget {
|
||||
final TUIGroupProfileModel model;
|
||||
|
||||
const SharedDataWidget({Key? key, required Widget child, required this.model})
|
||||
: super(key: key, child: child);
|
||||
|
||||
// Define a method to get the shared data from sub-tree
|
||||
static SharedDataWidget? of(BuildContext context) {
|
||||
return context.dependOnInheritedWidgetOfExactType<SharedDataWidget>();
|
||||
}
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(covariant SharedDataWidget oldWidget) {
|
||||
return oldWidget.model != model;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:loading_animation_widget/loading_animation_widget.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/enum/group_change_info_type.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/enum/group_member_role.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_info.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_member_full_info.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/group_profile_life_cycle.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/listener_model/tui_group_listener_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/group_profile_widget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_profile_widget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_button_area.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_manage.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_notification.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
export 'package:tencent_cloud_chat_uikit/ui/widgets/transimit_group_owner_select.dart';
|
||||
|
||||
typedef GroupProfileBuilder = Widget Function(
|
||||
BuildContext context, V2TimGroupInfo groupInfo, List<V2TimGroupMemberFullInfo?> groupMemberList);
|
||||
|
||||
class TIMUIKitGroupProfile extends StatefulWidget {
|
||||
/// Group ID
|
||||
final String groupID;
|
||||
final Color? backGroundColor;
|
||||
|
||||
/// [Deprecated:] The builder for custom bottom operation area.
|
||||
/// [operationListBuilder] and [bottomOperationBuilder] merged into [builder], please use it instead.
|
||||
final Widget Function(
|
||||
BuildContext context, V2TimGroupInfo groupInfo, List<V2TimGroupMemberFullInfo?> groupMemberList)?
|
||||
bottomOperationBuilder;
|
||||
|
||||
/// [Deprecated:] The builder for custom bottom operation area.
|
||||
/// [operationListBuilder] and [bottomOperationBuilder] merged into [builder], please use it instead.
|
||||
final Widget Function(
|
||||
BuildContext context, V2TimGroupInfo groupInfo, List<V2TimGroupMemberFullInfo?> groupMemberList)?
|
||||
operationListBuilder;
|
||||
|
||||
/// [If you tend to customize the profile page, use [profileWidgetBuilder] with [profileWidgetsOrder] as priority.]
|
||||
/// The builder for each widgets in profile page,
|
||||
/// you can customize some of it by pass your own widget into here.
|
||||
/// Or, you can add your custom widget to the three custom widgets.
|
||||
final GroupProfileWidgetBuilder? profileWidgetBuilder;
|
||||
|
||||
/// [If you tend to customize the profile page, use [profileWidgetBuilder] with [profileWidgetsOrder] as priority.]
|
||||
/// If the default widget order can not meet you needs,
|
||||
/// you may change the order by this array with widget enum.
|
||||
final List<GroupProfileWidgetEnum>? profileWidgetsOrder;
|
||||
|
||||
/// The builder for the whole group profile page, you can use this to customize all the element here.
|
||||
/// Mentioned: If you use this builder, [profileWidgetBuilder] and [profileWidgetsOrder] will no longer works.
|
||||
final GroupProfileBuilder? builder;
|
||||
|
||||
/// The life cycle hooks for group profile business logic.
|
||||
/// You have better to implement the `didLeaveGroup` in it.
|
||||
final GroupProfileLifeCycle? lifeCycle;
|
||||
|
||||
/// The callback after user clicking a user,
|
||||
/// you may navigating to the specific profile page, or anywhere you want.
|
||||
final Function(V2TimGroupMemberFullInfo groupMemberFullInfo, TapDownDetails? tapDetails)? onClickUser;
|
||||
|
||||
const TIMUIKitGroupProfile(
|
||||
{Key? key,
|
||||
required this.groupID,
|
||||
this.backGroundColor,
|
||||
@Deprecated("[operationListBuilder] and [bottomOperationBuilder] merged into [builder], please use it instead")
|
||||
this.bottomOperationBuilder,
|
||||
@Deprecated("[operationListBuilder] and [bottomOperationBuilder] merged into [builder], please use it instead")
|
||||
this.operationListBuilder,
|
||||
this.builder,
|
||||
this.profileWidgetBuilder,
|
||||
this.onClickUser,
|
||||
this.profileWidgetsOrder,
|
||||
this.lifeCycle})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _TIMUIKitGroupProfileState();
|
||||
}
|
||||
|
||||
class _TIMUIKitGroupProfileState extends TIMUIKitState<TIMUIKitGroupProfile> {
|
||||
bool isSingleUse = false;
|
||||
final model = TUIGroupProfileModel();
|
||||
final TUIGroupListenerModel groupListenerModel = serviceLocator<TUIGroupListenerModel>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
model.loadData(widget.groupID);
|
||||
model.onClickUser = widget.onClickUser;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant TIMUIKitGroupProfile oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (oldWidget.groupID != widget.groupID) {
|
||||
model.loadData(widget.groupID);
|
||||
}
|
||||
}
|
||||
|
||||
final List<GroupProfileWidgetEnum> _defaultWidgetOrder = [
|
||||
GroupProfileWidgetEnum.detailCard,
|
||||
GroupProfileWidgetEnum.operationDivider,
|
||||
GroupProfileWidgetEnum.memberListTile,
|
||||
GroupProfileWidgetEnum.operationDivider,
|
||||
GroupProfileWidgetEnum.searchMessage,
|
||||
GroupProfileWidgetEnum.operationDivider,
|
||||
GroupProfileWidgetEnum.groupNotice,
|
||||
GroupProfileWidgetEnum.groupManage,
|
||||
GroupProfileWidgetEnum.groupJoiningModeBar,
|
||||
GroupProfileWidgetEnum.groupTypeBar,
|
||||
GroupProfileWidgetEnum.operationDivider,
|
||||
GroupProfileWidgetEnum.pinedConversationBar,
|
||||
GroupProfileWidgetEnum.muteGroupMessageBar,
|
||||
GroupProfileWidgetEnum.operationDivider,
|
||||
GroupProfileWidgetEnum.nameCardBar,
|
||||
GroupProfileWidgetEnum.operationDivider,
|
||||
GroupProfileWidgetEnum.buttonArea
|
||||
];
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue buildValue) {
|
||||
final TUITheme theme = buildValue.theme;
|
||||
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: model),
|
||||
ChangeNotifierProvider.value(value: groupListenerModel),
|
||||
],
|
||||
builder: (context, w) {
|
||||
final model = Provider.of<TUIGroupProfileModel>(context);
|
||||
model.lifeCycle = widget.lifeCycle;
|
||||
final V2TimGroupInfo? groupInfo = model.groupInfo;
|
||||
final memberList = model.groupMemberList;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
if (groupInfo == null) {
|
||||
return Center(
|
||||
child: LoadingAnimationWidget.staggeredDotsWave(
|
||||
color: theme.weakTextColor ?? Colors.grey,
|
||||
size: 48,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final TUIGroupListenerModel groupListenerModel = Provider.of<TUIGroupListenerModel>(context);
|
||||
final NeedUpdate? needUpdate = groupListenerModel.needUpdate;
|
||||
if (needUpdate != null && needUpdate.groupID == widget.groupID) {
|
||||
groupListenerModel.needUpdate = null;
|
||||
switch (needUpdate.updateType) {
|
||||
case UpdateType.groupInfo:
|
||||
if (needUpdate.groupInfoSubType == GroupChangeInfoType.V2TIM_GROUP_INFO_CHANGE_TYPE_OWNER) {
|
||||
model.onOwnerChanged(needUpdate.ownerID);
|
||||
}
|
||||
|
||||
model.loadGroupInfo(widget.groupID);
|
||||
break;
|
||||
case UpdateType.memberList:
|
||||
model.loadGroupMemberList(groupID: widget.groupID);
|
||||
model.loadGroupInfo(widget.groupID);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final isGroupOwner = groupInfo.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER;
|
||||
final isAdmin = groupInfo.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN;
|
||||
|
||||
Widget groupProfilePage({required Widget child}) {
|
||||
return SingleChildScrollView(
|
||||
child: Container(
|
||||
color:
|
||||
widget.backGroundColor ?? (isDesktopScreen ? theme.wideBackgroundColor : theme.weakBackgroundColor),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void toDefaultNoticePage() {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
GroupProfileNotificationPage(model: model, notification: groupInfo.notification ?? "")));
|
||||
}
|
||||
|
||||
void toDefaultManagePage() {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => GroupProfileGroupManagePage(
|
||||
model: model,
|
||||
)));
|
||||
}
|
||||
|
||||
List<Widget> _renderWidgetsWithOrder(List<GroupProfileWidgetEnum> order) {
|
||||
final GroupProfileWidgetBuilder? customBuilder = widget.profileWidgetBuilder;
|
||||
return order.map((element) {
|
||||
switch (element) {
|
||||
case GroupProfileWidgetEnum.detailCard:
|
||||
return (customBuilder?.detailCard != null
|
||||
? customBuilder?.detailCard!(groupInfo, model.setGroupName)
|
||||
: TIMUIKitGroupProfileWidget.detailCard(
|
||||
isHavePermission: isAdmin || isGroupOwner, groupInfo: groupInfo))!;
|
||||
case GroupProfileWidgetEnum.memberListTile:
|
||||
return (customBuilder?.memberListTile != null
|
||||
? customBuilder?.memberListTile!(memberList)
|
||||
: TIMUIKitGroupProfileWidget.memberTile())!;
|
||||
case GroupProfileWidgetEnum.groupNotice:
|
||||
return (customBuilder?.groupNotice != null
|
||||
? customBuilder?.groupNotice!(
|
||||
groupInfo.notification ?? "", toDefaultNoticePage, model.setGroupNotification)
|
||||
: TIMUIKitGroupProfileWidget.groupNotification(isHavePermission: isAdmin || isGroupOwner))!;
|
||||
case GroupProfileWidgetEnum.groupManage:
|
||||
if (isAdmin || isGroupOwner) {
|
||||
return (customBuilder?.groupManage != null
|
||||
? customBuilder?.groupManage!(toDefaultManagePage)
|
||||
: TIMUIKitGroupProfileWidget.groupManage())!;
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
case GroupProfileWidgetEnum.searchMessage:
|
||||
return (customBuilder?.searchMessage != null
|
||||
? customBuilder?.searchMessage!()
|
||||
: Text(TIM_t("你必须自定义search bar,并处理点击跳转")))!;
|
||||
case GroupProfileWidgetEnum.operationDivider:
|
||||
return (customBuilder?.operationDivider != null
|
||||
? customBuilder?.operationDivider!()
|
||||
: TIMUIKitGroupProfileWidget.operationDivider(theme))!;
|
||||
case GroupProfileWidgetEnum.groupTypeBar:
|
||||
return (customBuilder?.groupTypeBar != null
|
||||
? customBuilder?.groupTypeBar!(groupInfo.groupType)
|
||||
: TIMUIKitGroupProfileWidget.groupType())!;
|
||||
case GroupProfileWidgetEnum.groupJoiningModeBar:
|
||||
final String groupType = groupInfo.groupType;
|
||||
if (!(isGroupOwner || isAdmin) ||
|
||||
groupType == "Work" ||
|
||||
groupType == "Meeting" ||
|
||||
groupType == "AVChatRoom") {
|
||||
return Container();
|
||||
}
|
||||
return (customBuilder?.groupJoiningModeBar != null
|
||||
? customBuilder?.groupJoiningModeBar!(groupInfo.groupAddOpt ?? 1, model.setGroupAddOpt)
|
||||
: TIMUIKitGroupProfileWidget.groupAddOpt())!;
|
||||
case GroupProfileWidgetEnum.nameCardBar:
|
||||
return (customBuilder?.nameCardBar != null
|
||||
? customBuilder?.nameCardBar!(model.getSelfNameCard(), model.setNameCard)
|
||||
: TIMUIKitGroupProfileWidget.nameCard())!;
|
||||
case GroupProfileWidgetEnum.muteGroupMessageBar:
|
||||
return (customBuilder?.muteGroupMessageBar != null
|
||||
? customBuilder?.muteGroupMessageBar!(model.conversation?.recvOpt != 0, model.setMessageDisturb)
|
||||
: TIMUIKitGroupProfileWidget.messageDisturb())!;
|
||||
case GroupProfileWidgetEnum.pinedConversationBar:
|
||||
return (customBuilder?.pinedConversationBar != null
|
||||
? customBuilder?.pinedConversationBar!(
|
||||
model.conversation?.isPinned ?? false, model.pinedConversation)
|
||||
: TIMUIKitGroupProfileWidget.pinedConversation())!;
|
||||
case GroupProfileWidgetEnum.buttonArea:
|
||||
return (customBuilder?.buttonArea != null
|
||||
? customBuilder?.buttonArea!(groupInfo, memberList)
|
||||
: GroupProfileButtonArea(groupInfo.groupID, model))!;
|
||||
case GroupProfileWidgetEnum.customBuilderOne:
|
||||
return (customBuilder?.customBuilderOne != null
|
||||
? customBuilder?.customBuilderOne!(groupInfo, memberList)
|
||||
// Please define the corresponding custom widget in `profileWidgetBuilder` before using it here.
|
||||
: Text(TIM_t("如使用自定义区域,请在profileWidgetBuilder传入对应组件")))!;
|
||||
case GroupProfileWidgetEnum.customBuilderTwo:
|
||||
return (customBuilder?.customBuilderTwo != null
|
||||
? customBuilder?.customBuilderTwo!(groupInfo, memberList)
|
||||
// Please define the corresponding custom widget in `profileWidgetBuilder` before using it here.
|
||||
: Text(TIM_t("如使用自定义区域,请在profileWidgetBuilder传入对应组件")))!;
|
||||
case GroupProfileWidgetEnum.customBuilderThree:
|
||||
return (customBuilder?.customBuilderThree != null
|
||||
? customBuilder?.customBuilderThree!(groupInfo, memberList)
|
||||
// Please define the corresponding custom widget in `profileWidgetBuilder` before using it here.
|
||||
: Text(TIM_t("如使用自定义区域,请在profileWidgetBuilder传入对应组件")))!;
|
||||
case GroupProfileWidgetEnum.customBuilderFour:
|
||||
return (customBuilder?.customBuilderFour != null
|
||||
? customBuilder?.customBuilderFour!(groupInfo, memberList)
|
||||
// Please define the corresponding custom widget in `profileWidgetBuilder` before using it here.
|
||||
: Text(TIM_t("如使用自定义区域,请在profileWidgetBuilder传入对应组件")))!;
|
||||
case GroupProfileWidgetEnum.customBuilderFive:
|
||||
return (customBuilder?.customBuilderFive != null
|
||||
? customBuilder?.customBuilderFive!(groupInfo, memberList)
|
||||
// Please define the corresponding custom widget in `profileWidgetBuilder` before using it here.
|
||||
: Text(TIM_t("如使用自定义区域,请在profileWidgetBuilder传入对应组件")))!;
|
||||
default:
|
||||
return Container();
|
||||
}
|
||||
}).toList();
|
||||
}
|
||||
|
||||
if (widget.builder != null) {
|
||||
return groupProfilePage(
|
||||
child: widget.builder!(context, groupInfo, memberList),
|
||||
);
|
||||
} else if (widget.profileWidgetsOrder != null) {
|
||||
return groupProfilePage(
|
||||
child: Column(
|
||||
children: [..._renderWidgetsWithOrder(widget.profileWidgetsOrder!)],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return groupProfilePage(
|
||||
child: Column(
|
||||
children: [..._renderWidgetsWithOrder(_defaultWidgetOrder)],
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/optimize_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_input.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class GroupMemberSearchTextField extends TIMUIKitStatelessWidget {
|
||||
final Function(String text) onTextChange;
|
||||
GroupMemberSearchTextField({Key? key, required this.onTextChange})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final FocusNode focusNode = FocusNode();
|
||||
|
||||
var debounceFunc = OptimizeUtils.debounce(
|
||||
(text) => onTextChange(text), const Duration(milliseconds: 300));
|
||||
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: Column(children: [
|
||||
if(!isDesktopScreen) Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(5.0)),
|
||||
border: Border.all(color: theme.weakBackgroundColor!, width: 12)),
|
||||
child: TextField(
|
||||
onChanged: debounceFunc,
|
||||
decoration: InputDecoration(
|
||||
hintText: TIM_t("搜索"),
|
||||
prefixIcon: const Icon(Icons.search),
|
||||
),
|
||||
),
|
||||
),
|
||||
if(isDesktopScreen) TIMUIKitSearchInput(prefixIcon: Icon(
|
||||
Icons.search,
|
||||
size: 16,
|
||||
color: hexToColor("979797"),
|
||||
),
|
||||
onChange: (text){
|
||||
focusNode.requestFocus();
|
||||
debounceFunc(text);
|
||||
}, focusNode: focusNode,
|
||||
),
|
||||
Divider(
|
||||
thickness: 1,
|
||||
indent: 74,
|
||||
endIndent: 0,
|
||||
color: theme.weakBackgroundColor,
|
||||
height: 0)
|
||||
]),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_conversation.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_info.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_search_msg.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_add_opt.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_detail_card.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_manage.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_member_title.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_message_disturb.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_name_card.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_notification.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_pin_conversation.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_type.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class TIMUIKitGroupProfileWidget {
|
||||
static Widget detailCard(
|
||||
{required V2TimGroupInfo groupInfo,
|
||||
bool isHavePermission = false,
|
||||
|
||||
/// You can deal with updating group name manually, or UIKIt do it automatically.
|
||||
Function(String updateGroupName)? updateGroupName}) {
|
||||
return GroupProfileDetailCard(
|
||||
groupInfo: groupInfo,
|
||||
isHavePermission: isHavePermission,
|
||||
updateGroupName: updateGroupName,
|
||||
);
|
||||
}
|
||||
|
||||
static Widget memberTile() {
|
||||
return GroupMemberTitle();
|
||||
}
|
||||
|
||||
static Widget groupNotification({
|
||||
bool isHavePermission = false,
|
||||
}) {
|
||||
return GroupProfileNotification(
|
||||
isHavePermission: isHavePermission,
|
||||
);
|
||||
}
|
||||
|
||||
static Widget groupManage() {
|
||||
return const GroupProfileGroupManage();
|
||||
}
|
||||
|
||||
static Widget searchMessage(Function(V2TimConversation?) onJumpToSearch) {
|
||||
return GroupProfileGroupSearch(onJumpToSearch: onJumpToSearch);
|
||||
}
|
||||
|
||||
static Widget operationDivider(TUITheme theme) {
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop;
|
||||
return Container(
|
||||
color: theme.weakDividerColor,
|
||||
height: isDesktopScreen ? 1 : 10,
|
||||
);
|
||||
}
|
||||
|
||||
static Widget groupType() {
|
||||
return GroupProfileType();
|
||||
}
|
||||
|
||||
static Widget groupAddOpt() {
|
||||
return GroupProfileAddOpt();
|
||||
}
|
||||
|
||||
static Widget nameCard() {
|
||||
return const GroupProfileNameCard();
|
||||
}
|
||||
|
||||
static Widget messageDisturb() {
|
||||
return GroupMessageDisturb();
|
||||
}
|
||||
|
||||
static Widget pinedConversation() {
|
||||
return GroupPinConversation();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// ignore_for_file: unused_import
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_conversation.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitSearch/tim_uikit_search.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/conversation/conversation_services.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/shared_data_widget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class GroupProfileGroupSearch extends TIMUIKitStatelessWidget {
|
||||
GroupProfileGroupSearch({Key? key, required this.onJumpToSearch}) : super(key: key);
|
||||
final ConversationService _conversationService = serviceLocator<ConversationService>();
|
||||
|
||||
final Function(V2TimConversation?) onJumpToSearch;
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
|
||||
final model = Provider.of<TUIGroupProfileModel>(context);
|
||||
|
||||
return InkWell(
|
||||
onTap: () async {
|
||||
V2TimConversation? conversation =
|
||||
await _conversationService.getConversation(conversationID: "group_${model.groupInfo!.groupID}");
|
||||
if (conversation != null) {
|
||||
onJumpToSearch(conversation);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 14, horizontal: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
TIM_t("查找聊天内容"),
|
||||
style: TextStyle(fontSize: 16, color: theme.darkTextColor),
|
||||
),
|
||||
Icon(Icons.keyboard_arrow_right, color: theme.weakTextColor)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/enum/group_add_opt_type.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/column_menu.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
|
||||
|
||||
class GroupProfileAddOpt extends TIMUIKitStatelessWidget {
|
||||
GroupProfileAddOpt({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
final model = Provider.of<TUIGroupProfileModel>(context);
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
String addOpt = TIM_t("未知");
|
||||
|
||||
final groupAddOpt = model.groupInfo?.groupAddOpt;
|
||||
switch (groupAddOpt) {
|
||||
case GroupAddOptType.V2TIM_GROUP_ADD_ANY:
|
||||
addOpt = TIM_t("自动审批");
|
||||
break;
|
||||
case GroupAddOptType.V2TIM_GROUP_ADD_AUTH:
|
||||
addOpt = TIM_t("管理员审批");
|
||||
break;
|
||||
case GroupAddOptType.V2TIM_GROUP_ADD_FORBID:
|
||||
addOpt = TIM_t("禁止加群");
|
||||
break;
|
||||
}
|
||||
|
||||
final actionList = [
|
||||
{"label": TIM_t("禁止加群"), "id": GroupAddOptType.V2TIM_GROUP_ADD_FORBID},
|
||||
{"label": TIM_t("自动审批"), "id": GroupAddOptType.V2TIM_GROUP_ADD_ANY},
|
||||
{"label": TIM_t("管理员审批"), "id": GroupAddOptType.V2TIM_GROUP_ADD_AUTH}
|
||||
];
|
||||
|
||||
_handleActionTap(int addOpt) async {
|
||||
model.setGroupAddOpt(addOpt).then((res) {});
|
||||
}
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: isDesktopScreen ? null : Border(
|
||||
bottom: BorderSide(
|
||||
color:
|
||||
theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: InkWell(
|
||||
onTapDown: (details) async {
|
||||
if(isDesktopScreen){
|
||||
TUIKitWidePopup.showPopupWindow(
|
||||
operationKey: TUIKitWideModalOperationKey.groupAddOpt,
|
||||
isDarkBackground: false,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4)),
|
||||
context: context,
|
||||
offset: Offset(min(details.globalPosition.dx,
|
||||
MediaQuery.of(context).size.width - 186), details.globalPosition.dy),
|
||||
child: (onClose) => TUIKitColumnMenu(
|
||||
data: [
|
||||
...actionList
|
||||
.map((e){
|
||||
return ColumnMenuItem(label: e["label"] as String, onClick: (){
|
||||
_handleActionTap(e["id"] as int);
|
||||
onClose();
|
||||
});
|
||||
}),
|
||||
],
|
||||
)
|
||||
);
|
||||
}else{
|
||||
showCupertinoModalPopup<String>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoActionSheet(
|
||||
title: Text(TIM_t("加群方式")),
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
onPressed: () {
|
||||
Navigator.pop(
|
||||
context,
|
||||
"cancel",
|
||||
);
|
||||
},
|
||||
child: Text(TIM_t("取消")),
|
||||
isDefaultAction: false,
|
||||
),
|
||||
actions: actionList
|
||||
.map((e) => CupertinoActionSheetAction(
|
||||
onPressed: () {
|
||||
_handleActionTap(e["id"] as int);
|
||||
Navigator.pop(
|
||||
context,
|
||||
"cancel",
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
e["label"] as String,
|
||||
style: TextStyle(color: theme.primaryColor),
|
||||
),
|
||||
isDefaultAction: false,
|
||||
))
|
||||
.toList(),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
TIM_t("加群方式"),
|
||||
style: TextStyle(fontSize: isDesktopScreen ? 14 : 16, color: theme.darkTextColor),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
addOpt,
|
||||
style: TextStyle(fontSize: isDesktopScreen ? 14 : 16, color: Colors.black),
|
||||
),
|
||||
Icon(Icons.keyboard_arrow_right, color: theme.weakTextColor)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,355 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_member_full_info.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/controller/tim_uikit_chat_controller.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
|
||||
import '/theme/tui_theme.dart';
|
||||
|
||||
class GroupProfileButtonArea extends TIMUIKitStatelessWidget {
|
||||
final String groupID;
|
||||
final TUIGroupProfileModel model;
|
||||
final sdkInstance = TIMUIKitCore.getSDKInstance();
|
||||
final coreInstance = TIMUIKitCore.getInstance();
|
||||
final TIMUIKitChatController _timuiKitChatController = TIMUIKitChatController();
|
||||
|
||||
GroupProfileButtonArea(this.groupID, this.model, {Key? key}) : super(key: key);
|
||||
|
||||
final _operationList = [
|
||||
{"label": TIM_t("清空消息"), "id": "clearHistory"},
|
||||
{"label": TIM_t("转让群主"), "id": "transimitOwner"},
|
||||
{"label": TIM_t("退出群组"), "id": "quitGroup"},
|
||||
{"label": TIM_t("解散群组"), "id": "dismissGroup"}
|
||||
];
|
||||
|
||||
_clearHistory(BuildContext context, theme) async {
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
if (isDesktopScreen) {
|
||||
TUIKitWidePopup.showSecondaryConfirmDialog(
|
||||
operationKey: TUIKitWideModalOperationKey.confirmClearChatHistory,
|
||||
context: context,
|
||||
text: TIM_t("清空聊天记录"),
|
||||
theme: theme,
|
||||
onCancel: () {},
|
||||
onConfirm: () async {
|
||||
if (PlatformUtils().isWeb) {
|
||||
final res =
|
||||
await sdkInstance.getConversationManager().deleteConversation(conversationID: "group_$groupID");
|
||||
if (res.code == 0) {
|
||||
_timuiKitChatController.clearHistory(groupID);
|
||||
}
|
||||
} else {
|
||||
final res = await sdkInstance.getMessageManager().clearGroupHistoryMessage(groupID: groupID);
|
||||
if (res.code == 0) {
|
||||
_timuiKitChatController.clearHistory(groupID);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
showCupertinoModalPopup<String>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoActionSheet(
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
onPressed: () {
|
||||
Navigator.pop(
|
||||
context,
|
||||
);
|
||||
},
|
||||
child: Text(TIM_t("取消")),
|
||||
isDefaultAction: false,
|
||||
),
|
||||
actions: [
|
||||
CupertinoActionSheetAction(
|
||||
onPressed: () async {
|
||||
Navigator.pop(
|
||||
context,
|
||||
);
|
||||
if (PlatformUtils().isWeb) {
|
||||
final res =
|
||||
await sdkInstance.getConversationManager().deleteConversation(conversationID: "group_$groupID");
|
||||
if (res.code == 0) {
|
||||
_timuiKitChatController.clearHistory(groupID);
|
||||
}
|
||||
} else {
|
||||
final res = await sdkInstance.getMessageManager().clearGroupHistoryMessage(groupID: groupID);
|
||||
if (res.code == 0) {
|
||||
_timuiKitChatController.clearHistory(groupID);
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
TIM_t("确定"),
|
||||
style: TextStyle(color: theme.cautionColor),
|
||||
),
|
||||
isDefaultAction: false,
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_quitGroup(BuildContext context, TUITheme theme) async {
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
if (isDesktopScreen) {
|
||||
TUIKitWidePopup.showSecondaryConfirmDialog(
|
||||
operationKey: TUIKitWideModalOperationKey.confirmExitGroup,
|
||||
context: context,
|
||||
text: TIM_t("退出后不会接收到此群聊消息"),
|
||||
theme: theme,
|
||||
onCancel: () {},
|
||||
onConfirm: () async {
|
||||
final res = await sdkInstance.quitGroup(groupID: groupID);
|
||||
if (res.code == 0) {
|
||||
final deleteConvRes =
|
||||
await sdkInstance.getConversationManager().deleteConversation(conversationID: "group_$groupID");
|
||||
if (deleteConvRes.code == 0) {
|
||||
model.lifeCycle?.didLeaveGroup();
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
showCupertinoModalPopup<String>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoActionSheet(
|
||||
title: Text(TIM_t("退出后不会接收到此群聊消息")),
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
onPressed: () {
|
||||
Navigator.pop(
|
||||
context,
|
||||
);
|
||||
},
|
||||
child: Text(TIM_t("取消")),
|
||||
isDefaultAction: false,
|
||||
),
|
||||
actions: [
|
||||
CupertinoActionSheetAction(
|
||||
onPressed: () async {
|
||||
Navigator.pop(
|
||||
context,
|
||||
);
|
||||
final res = await sdkInstance.quitGroup(groupID: groupID);
|
||||
if (res.code == 0) {
|
||||
final deleteConvRes =
|
||||
await sdkInstance.getConversationManager().deleteConversation(conversationID: "group_$groupID");
|
||||
if (deleteConvRes.code == 0) {
|
||||
model.lifeCycle?.didLeaveGroup();
|
||||
}
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: "${TIM_t("您已退出")}${model.groupInfo?.groupName}",
|
||||
infoCode: 6661402));
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
TIM_t("确定"),
|
||||
style: TextStyle(color: theme.cautionColor),
|
||||
),
|
||||
isDefaultAction: false,
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_dismissGroup(BuildContext context, theme) async {
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
if (isDesktopScreen) {
|
||||
TUIKitWidePopup.showSecondaryConfirmDialog(
|
||||
operationKey: TUIKitWideModalOperationKey.confirmDisbandGroup,
|
||||
context: context,
|
||||
text: TIM_t("解散后不会接收到此群聊消息"),
|
||||
theme: theme,
|
||||
onCancel: () {},
|
||||
onConfirm: () async {
|
||||
final res = await sdkInstance.dismissGroup(groupID: groupID);
|
||||
if (res.code == 0) {
|
||||
await sdkInstance.getConversationManager().deleteConversation(conversationID: "group_$groupID");
|
||||
model.lifeCycle?.didLeaveGroup();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
showCupertinoModalPopup<String>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoActionSheet(
|
||||
title: Text(TIM_t("解散后不会接收到此群聊消息")),
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
onPressed: () {
|
||||
Navigator.pop(
|
||||
context,
|
||||
);
|
||||
},
|
||||
child: Text(TIM_t("取消")),
|
||||
isDefaultAction: false,
|
||||
),
|
||||
actions: [
|
||||
CupertinoActionSheetAction(
|
||||
onPressed: () async {
|
||||
final res = await sdkInstance.dismissGroup(groupID: groupID);
|
||||
if (res.code == 0) {
|
||||
await sdkInstance.getConversationManager().deleteConversation(conversationID: "group_$groupID");
|
||||
model.lifeCycle?.didLeaveGroup();
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
TIM_t("确定"),
|
||||
style: TextStyle(color: theme.cautionColor),
|
||||
),
|
||||
isDefaultAction: false,
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_transmitOwner(BuildContext context, String groupID) async {
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
if (isDesktopScreen) {
|
||||
TUIKitWidePopup.showPopupWindow(
|
||||
operationKey: TUIKitWideModalOperationKey.setAdmins,
|
||||
context: context,
|
||||
title: TIM_t("转让群主"),
|
||||
width: MediaQuery.of(context).size.width * 0.5,
|
||||
height: MediaQuery.of(context).size.height * 0.8,
|
||||
onSubmit: () {
|
||||
selectNewGroupOwnerKey.currentState?.onSubmit();
|
||||
},
|
||||
child: (onClose) => SelectNewGroupOwner(
|
||||
model: model,
|
||||
key: selectNewGroupOwnerKey,
|
||||
groupID: groupID,
|
||||
onSelectedMember: (selectedMember) async {
|
||||
if (selectedMember.isNotEmpty) {
|
||||
final userID = selectedMember.first.userID;
|
||||
await sdkInstance.getGroupManager().transferGroupOwner(groupID: groupID, userID: userID);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
} else {
|
||||
List<V2TimGroupMemberFullInfo>? selectedMember = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SelectNewGroupOwner(
|
||||
model: model,
|
||||
groupID: groupID,
|
||||
),
|
||||
),
|
||||
);
|
||||
if (selectedMember != null) {
|
||||
final userID = selectedMember.first.userID;
|
||||
await sdkInstance.getGroupManager().transferGroupOwner(groupID: groupID, userID: userID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Widget> _renderGroupOperation(BuildContext context, TUITheme theme, bool isOwner, String groupType) {
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
return _operationList
|
||||
.where((element) {
|
||||
if (!isOwner) {
|
||||
return ["quitGroup", "clearHistory"].contains(element["id"]);
|
||||
} else {
|
||||
if (groupType == "Work") {
|
||||
return ["clearHistory", "quitGroup", "transimitOwner"].contains(element["id"]);
|
||||
}
|
||||
if (groupType != "Work") {
|
||||
return ["clearHistory", "dismissGroup", "transimitOwner"].contains(element["id"]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
})
|
||||
.map((e) => isDesktopScreen
|
||||
? OutlinedButton(
|
||||
onPressed: () {
|
||||
if (e["id"]! == "clearHistory") {
|
||||
_clearHistory(context, theme);
|
||||
} else if (e["id"] == "quitGroup") {
|
||||
_quitGroup(context, theme);
|
||||
} else if (e["id"] == "dismissGroup") {
|
||||
_dismissGroup(context, theme);
|
||||
} else if (e["id"] == "transimitOwner") {
|
||||
_transmitOwner(context, groupID);
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
e["label"]!,
|
||||
style: TextStyle(color: theme.cautionColor),
|
||||
))
|
||||
: InkWell(
|
||||
onTap: () {
|
||||
if (e["id"]! == "clearHistory") {
|
||||
_clearHistory(context, theme);
|
||||
} else if (e["id"] == "quitGroup") {
|
||||
_quitGroup(context, theme);
|
||||
} else if (e["id"] == "dismissGroup") {
|
||||
_dismissGroup(context, theme);
|
||||
} else if (e["id"] == "transimitOwner") {
|
||||
_transmitOwner(context, groupID);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
padding: const EdgeInsets.symmetric(vertical: 15),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border:
|
||||
Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: Text(
|
||||
e["label"]!,
|
||||
style: TextStyle(color: theme.cautionColor, fontSize: 17),
|
||||
),
|
||||
),
|
||||
))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final theme = value.theme;
|
||||
final groupInfo = model.groupInfo;
|
||||
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
if (isDesktopScreen) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Wrap(
|
||||
spacing: 28,
|
||||
children: [
|
||||
..._renderGroupOperation(
|
||||
context, theme, groupInfo?.owner == coreInstance.loginUserInfo?.userID, groupInfo?.groupType ?? "")
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
..._renderGroupOperation(
|
||||
context, theme, groupInfo?.owner == coreInstance.loginUserInfo?.userID, groupInfo?.groupType ?? "")
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_info.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/text_input_bottom_sheet.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class GroupProfileDetailCard extends TIMUIKitStatelessWidget {
|
||||
final V2TimGroupInfo groupInfo;
|
||||
final void Function(String groupName)? updateGroupName;
|
||||
final TextEditingController controller = TextEditingController();
|
||||
final bool isHavePermission;
|
||||
|
||||
GroupProfileDetailCard({Key? key, required this.groupInfo, this.isHavePermission = false, this.updateGroupName})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
final model = Provider.of<TUIGroupProfileModel>(context);
|
||||
final faceUrl = groupInfo.faceUrl ?? "";
|
||||
final groupID = groupInfo.groupID;
|
||||
final showName = groupInfo.groupName ?? groupID;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
return InkWell(
|
||||
onTapDown: !isHavePermission
|
||||
? null
|
||||
: ((details) {
|
||||
if (isDesktopScreen) {
|
||||
TextInputBottomSheet.showTextInputBottomSheet(
|
||||
context: context,
|
||||
title: TIM_t("修改群名称"),
|
||||
initText: showName,
|
||||
initOffset: Offset(min(details.globalPosition.dx, MediaQuery.of(context).size.width - 350),
|
||||
min(details.globalPosition.dy + 20, MediaQuery.of(context).size.height - 470)),
|
||||
onSubmitted: (String newText) async {
|
||||
final text = newText.trim();
|
||||
if (updateGroupName != null) {
|
||||
updateGroupName!(text);
|
||||
} else {
|
||||
model.setGroupName(text);
|
||||
}
|
||||
},
|
||||
theme: theme);
|
||||
} else {
|
||||
showCupertinoModalPopup<String>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoActionSheet(
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
onPressed: () {
|
||||
Navigator.pop(
|
||||
context,
|
||||
);
|
||||
},
|
||||
child: Text(TIM_t("取消")),
|
||||
isDefaultAction: false,
|
||||
),
|
||||
actions: [
|
||||
CupertinoActionSheetAction(
|
||||
onPressed: () {
|
||||
controller.text = groupInfo.groupName ?? "";
|
||||
showModalBottomSheet(
|
||||
isScrollControlled: true,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0))),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
child: Text(TIM_t("修改群名称")),
|
||||
),
|
||||
Divider(height: 2, color: theme.weakDividerColor),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextField(
|
||||
controller: controller,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
fillColor: theme.weakBackgroundColor,
|
||||
filled: true,
|
||||
isDense: true,
|
||||
hintText: ''),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Text(
|
||||
TIM_t("修改群名称"),
|
||||
style: TextStyle(fontSize: 13, color: theme.weakTextColor),
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
final text = controller.text.trim();
|
||||
if (updateGroupName != null) {
|
||||
updateGroupName!(text);
|
||||
} else {
|
||||
model.setGroupName(text);
|
||||
}
|
||||
Navigator.pop(context);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(TIM_t("确定")),
|
||||
)),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
child: Text(
|
||||
TIM_t("修改群名称"),
|
||||
style: TextStyle(color: theme.primaryColor),
|
||||
),
|
||||
isDefaultAction: false,
|
||||
)
|
||||
]);
|
||||
},
|
||||
);
|
||||
}
|
||||
}),
|
||||
child: Container(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.only(
|
||||
top: isDesktopScreen ? 20 : 12,
|
||||
bottom: isDesktopScreen ? 20 : 12,
|
||||
right: isDesktopScreen ? 16 : 0,
|
||||
left: 16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: isDesktopScreen ? 40 : 48,
|
||||
height: isDesktopScreen ? 40 : 48,
|
||||
child: Avatar(
|
||||
faceUrl: faceUrl,
|
||||
showName: showName,
|
||||
type: 2,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(left: 16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SelectableText(
|
||||
showName,
|
||||
style: TextStyle(fontSize: isDesktopScreen ? 15 : 18, fontWeight: FontWeight.w600),
|
||||
),
|
||||
SizedBox(
|
||||
height: isDesktopScreen ? 4 : 8,
|
||||
),
|
||||
SelectableText("ID: $groupID",
|
||||
style: TextStyle(fontSize: isDesktopScreen ? 13 : 13, color: theme.weakTextColor))
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isHavePermission)
|
||||
Icon(
|
||||
Icons.keyboard_arrow_right,
|
||||
color: theme.weakTextColor,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,817 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_slidable_plus_plus/flutter_slidable_plus_plus.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/enum/group_member_role.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/enum/group_type.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_member_full_info.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitProfile/widget/tim_uikit_operation_item.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/column_menu.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/radio_button.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_callback.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme_view_model.dart';
|
||||
|
||||
GlobalKey<_GroupProfileAddAdminState> groupProfileAddAdminKey = GlobalKey();
|
||||
|
||||
class GroupProfileGroupManage extends StatefulWidget {
|
||||
const GroupProfileGroupManage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => GroupProfileGroupManageState();
|
||||
}
|
||||
|
||||
class GroupProfileGroupManageState extends TIMUIKitState<GroupProfileGroupManage> {
|
||||
bool isShowManageBox = false;
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final model = Provider.of<TUIGroupProfileModel>(context);
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: isDesktopScreen
|
||||
? null
|
||||
: Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
if (!isDesktopScreen) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => GroupProfileGroupManagePage(
|
||||
model: model,
|
||||
)));
|
||||
} else {
|
||||
setState(() {
|
||||
isShowManageBox = !isShowManageBox;
|
||||
});
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
TIM_t("群管理"),
|
||||
style: TextStyle(fontSize: isDesktopScreen ? 14 : 16, color: theme.darkTextColor),
|
||||
),
|
||||
AnimatedRotation(
|
||||
turns: isShowManageBox ? 0.25 : 0,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Icon(Icons.keyboard_arrow_right, color: theme.weakTextColor),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
if (isShowManageBox)
|
||||
GroupProfileGroupManagePage(
|
||||
model: model,
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 管理员设置页面
|
||||
class GroupProfileGroupManagePage extends StatefulWidget {
|
||||
final TUIGroupProfileModel model;
|
||||
|
||||
const GroupProfileGroupManagePage({
|
||||
Key? key,
|
||||
required this.model,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _GroupProfileGroupManagePageState();
|
||||
}
|
||||
|
||||
class _GroupProfileGroupManagePageState extends TIMUIKitState<GroupProfileGroupManagePage> {
|
||||
int? serverTime;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
getServerTime();
|
||||
}
|
||||
|
||||
void getServerTime() async {
|
||||
final res = await TencentImSDKPlugin.v2TIMManager.getServerTime();
|
||||
setState(() {
|
||||
serverTime = res.data;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: widget.model),
|
||||
ChangeNotifierProvider.value(value: serviceLocator<TUIThemeViewModel>())
|
||||
],
|
||||
builder: (context, w) {
|
||||
final memberList = Provider.of<TUIGroupProfileModel>(context).groupMemberList;
|
||||
final theme = Provider.of<TUIThemeViewModel>(context).theme;
|
||||
final isAllMuted = widget.model.groupInfo?.isAllMuted ?? false;
|
||||
final bool isAllowMuteMember = (widget.model.groupInfo?.groupType ?? "") != GroupType.Work;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
Widget managePage() {
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(
|
||||
top: 12,
|
||||
left: isDesktopScreen ? 0 : 16,
|
||||
bottom: isDesktopScreen ? 0 : 12,
|
||||
right: isDesktopScreen ? 0 : 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: isDesktopScreen
|
||||
? null
|
||||
: Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: InkWell(
|
||||
onTap: isDesktopScreen
|
||||
? null
|
||||
: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => GroupProfileSetManagerPage(
|
||||
model: widget.model,
|
||||
),
|
||||
));
|
||||
},
|
||||
child: isDesktopScreen
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(TIM_t("群管理员"), style: TextStyle(fontSize: 14, color: theme.darkTextColor)),
|
||||
],
|
||||
)
|
||||
: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(TIM_t("设置管理员"),
|
||||
style: TextStyle(fontSize: isDesktopScreen ? 14 : 16, color: theme.darkTextColor)),
|
||||
Icon(Icons.keyboard_arrow_right, color: theme.weakTextColor)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isDesktopScreen)
|
||||
GroupProfileSetManagerPage(
|
||||
model: widget.model,
|
||||
),
|
||||
if (!isDesktopScreen)
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 12, left: 16, bottom: 12, right: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border:
|
||||
Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
TIM_t("全员禁言"),
|
||||
style: TextStyle(fontSize: 16, color: theme.darkTextColor),
|
||||
),
|
||||
CupertinoSwitch(
|
||||
value: isAllMuted,
|
||||
onChanged: (value) async {
|
||||
widget.model.setMuteAll(value);
|
||||
},
|
||||
activeColor: theme.primaryColor)
|
||||
],
|
||||
),
|
||||
),
|
||||
if (isDesktopScreen && isAllowMuteMember)
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(TIM_t("禁言"), style: TextStyle(fontSize: 14, color: theme.darkTextColor)),
|
||||
],
|
||||
),
|
||||
if (isDesktopScreen)
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: TIMUIKitOperationItem(
|
||||
isEmpty: false,
|
||||
operationName: TIM_t("全员禁言"),
|
||||
type: "switch",
|
||||
isUseCheckedBoxOnWide: true,
|
||||
operationDescription: TIM_t("全员禁言开启后,只允许群主和管理员发言。"),
|
||||
operationValue: isAllMuted,
|
||||
onSwitchChange: (value) {
|
||||
widget.model.setMuteAll(value);
|
||||
},
|
||||
),
|
||||
),
|
||||
if (!isDesktopScreen)
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
|
||||
color: theme.weakBackgroundColor,
|
||||
alignment: Alignment.topLeft,
|
||||
child: Text(
|
||||
TIM_t("全员禁言开启后,只允许群主和管理员发言。"),
|
||||
style: TextStyle(fontSize: 12, color: theme.weakTextColor),
|
||||
),
|
||||
),
|
||||
if (!isAllMuted && isAllowMuteMember)
|
||||
InkWell(
|
||||
child: Container(
|
||||
color: Colors.white,
|
||||
padding: const EdgeInsets.only(left: 16),
|
||||
child: Container(
|
||||
padding: !isDesktopScreen
|
||||
? const EdgeInsets.symmetric(
|
||||
vertical: 12,
|
||||
)
|
||||
: const EdgeInsets.only(
|
||||
bottom: 4,
|
||||
),
|
||||
decoration: isDesktopScreen
|
||||
? null
|
||||
: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom:
|
||||
BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.add_circle_outline,
|
||||
color: theme.primaryColor,
|
||||
size: 20,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Text(TIM_t("添加需要禁言的群成员"))
|
||||
],
|
||||
),
|
||||
)),
|
||||
onTap: () async {
|
||||
Widget muteMember() {
|
||||
return GroupProfileAddAdmin(
|
||||
key: groupProfileAddAdminKey,
|
||||
appbarTitle: TIM_t("设置禁言"),
|
||||
memberList: memberList.where((element) {
|
||||
final isMute = (serverTime != null ? (element?.muteUntil ?? 0) > serverTime! : false);
|
||||
final isMember = element!.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER;
|
||||
return !isMute && isMember;
|
||||
}).toList(),
|
||||
selectCompletedHandler: (context, selectedMember) async {
|
||||
if (selectedMember.isNotEmpty) {
|
||||
for (var member in selectedMember) {
|
||||
final userID = member!.userID;
|
||||
widget.model.muteGroupMember(userID, true, serverTime);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (isDesktopScreen) {
|
||||
TUIKitWidePopup.showPopupWindow(
|
||||
operationKey: TUIKitWideModalOperationKey.setMute,
|
||||
context: context,
|
||||
title: TIM_t("设置禁言"),
|
||||
width: MediaQuery.of(context).size.width * 0.5,
|
||||
height: MediaQuery.of(context).size.height * 0.8,
|
||||
onSubmit: () {
|
||||
groupProfileAddAdminKey.currentState?.onSubmit();
|
||||
},
|
||||
child: (onClose) => muteMember());
|
||||
} else {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => muteMember()));
|
||||
}
|
||||
},
|
||||
),
|
||||
if (!isAllMuted && isAllowMuteMember)
|
||||
...memberList
|
||||
.where((element) => (serverTime != null ? (element?.muteUntil ?? 0) > serverTime! : false))
|
||||
.map((e) => Container(
|
||||
padding: isDesktopScreen ? const EdgeInsets.only(left: 16) : null,
|
||||
child: GestureDetector(
|
||||
onSecondaryTapDown: (details) {
|
||||
TUIKitWidePopup.showPopupWindow(
|
||||
operationKey: TUIKitWideModalOperationKey.setUnmute,
|
||||
isDarkBackground: false,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4)),
|
||||
context: context,
|
||||
offset: Offset(
|
||||
min(details.globalPosition.dx, MediaQuery.of(context).size.width - 80),
|
||||
details.globalPosition.dy),
|
||||
child: (onClose) => TUIKitColumnMenu(data: [
|
||||
ColumnMenuItem(
|
||||
label: TIM_t("删除"),
|
||||
icon: const Icon(Icons.remove_circle_outline, size: 16),
|
||||
onClick: () {
|
||||
widget.model.muteGroupMember(e.userID, false, serverTime);
|
||||
onClose();
|
||||
}),
|
||||
]));
|
||||
},
|
||||
child: _buildListItem(
|
||||
context,
|
||||
e!,
|
||||
ActionPane(motion: const DrawerMotion(), children: [
|
||||
SlidableAction(
|
||||
onPressed: (_) {
|
||||
widget.model.muteGroupMember(e.userID, false, serverTime);
|
||||
},
|
||||
flex: 1,
|
||||
backgroundColor: theme.cautionColor ?? CommonColor.cautionColor,
|
||||
autoClose: true,
|
||||
label: TIM_t("删除"),
|
||||
)
|
||||
])),
|
||||
),
|
||||
))
|
||||
.toList()
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return TUIKitScreenUtils.getDeviceWidget(
|
||||
context: context,
|
||||
desktopWidget: managePage(),
|
||||
defaultWidget: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
TIM_t("群管理"),
|
||||
style: TextStyle(color: theme.appbarTextColor, fontSize: 17),
|
||||
),
|
||||
backgroundColor: theme.appbarBgColor ?? theme.primaryColor,
|
||||
shadowColor: theme.weakDividerColor,
|
||||
iconTheme: IconThemeData(
|
||||
color: theme.appbarTextColor,
|
||||
),
|
||||
leading: IconButton(
|
||||
padding: const EdgeInsets.only(left: 16),
|
||||
constraints: const BoxConstraints(),
|
||||
icon: Image.asset(
|
||||
'images/arrow_back.png',
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
height: 34,
|
||||
width: 34,
|
||||
color: theme.appbarTextColor,
|
||||
),
|
||||
onPressed: () async {
|
||||
if (isAllMuted != widget.model.groupInfo?.isAllMuted) {
|
||||
widget.model.setMuteAll(isAllMuted);
|
||||
}
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
body: managePage(),
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_getShowName(V2TimGroupMemberFullInfo? item) {
|
||||
final friendRemark = item?.friendRemark ?? "";
|
||||
final nameCard = item?.nameCard ?? "";
|
||||
final nickName = item?.nickName ?? "";
|
||||
final userID = item?.userID ?? "";
|
||||
return friendRemark.isNotEmpty
|
||||
? friendRemark
|
||||
: nameCard.isNotEmpty
|
||||
? nameCard
|
||||
: nickName.isNotEmpty
|
||||
? nickName
|
||||
: userID;
|
||||
}
|
||||
|
||||
Widget _buildListItem(BuildContext context, V2TimGroupMemberFullInfo memberInfo, ActionPane? endActionPane) {
|
||||
final theme = Provider.of<TUIThemeViewModel>(context).theme;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
Widget nameItem() {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: Column(children: [
|
||||
ListTile(
|
||||
tileColor: Colors.black,
|
||||
leading: SizedBox(
|
||||
width: isDesktopScreen ? 30 : 36,
|
||||
height: isDesktopScreen ? 30 : 36,
|
||||
child: Avatar(
|
||||
faceUrl: memberInfo.faceUrl ?? "",
|
||||
showName: _getShowName(memberInfo),
|
||||
type: 2,
|
||||
),
|
||||
),
|
||||
title: Row(
|
||||
children: [
|
||||
Text(_getShowName(memberInfo), style: TextStyle(fontSize: isDesktopScreen ? 14 : 16)),
|
||||
],
|
||||
),
|
||||
onTap: () {},
|
||||
),
|
||||
if (!isDesktopScreen) Divider(thickness: 1, indent: 74, endIndent: 0, color: theme.weakDividerColor, height: 0)
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
return TUIKitScreenUtils.getDeviceWidget(
|
||||
context: context,
|
||||
desktopWidget: nameItem(),
|
||||
defaultWidget: SingleChildScrollView(child: Slidable(endActionPane: endActionPane, child: nameItem())));
|
||||
}
|
||||
|
||||
/// 选择管理员
|
||||
class GroupProfileSetManagerPage extends StatefulWidget {
|
||||
final TUIGroupProfileModel model;
|
||||
|
||||
const GroupProfileSetManagerPage({Key? key, required this.model}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _GroupProfileSetManagerPageState();
|
||||
}
|
||||
|
||||
class _GroupProfileSetManagerPageState extends TIMUIKitState<GroupProfileSetManagerPage> {
|
||||
List<V2TimGroupMemberFullInfo?> _getAdminMemberList(List<V2TimGroupMemberFullInfo?> memberList) {
|
||||
return memberList.where((member) => member?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN).toList();
|
||||
}
|
||||
|
||||
List<V2TimGroupMemberFullInfo?> _getOwnerList(List<V2TimGroupMemberFullInfo?> memberList) {
|
||||
return memberList.where((member) => member?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER).toList();
|
||||
}
|
||||
|
||||
_removeAdmin(BuildContext context, V2TimGroupMemberFullInfo memberFullInfo) async {
|
||||
final res = await widget.model.setMemberToNormal(memberFullInfo.userID);
|
||||
if (res.code == 0) {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("成功取消管理员身份"), infoCode: 6661003));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
|
||||
return MultiProvider(
|
||||
providers: [ChangeNotifierProvider.value(value: widget.model)],
|
||||
builder: (context, w) {
|
||||
final model = Provider.of<TUIGroupProfileModel>(context);
|
||||
final memberList = model.groupMemberList;
|
||||
final adminList = _getAdminMemberList(memberList);
|
||||
final ownerList = _getOwnerList(memberList);
|
||||
final String option2 = adminList.length.toString();
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
Widget adminPage() {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
if (!isDesktopScreen)
|
||||
Container(
|
||||
alignment: Alignment.topLeft,
|
||||
color: theme.weakDividerColor,
|
||||
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
||||
child: Text(
|
||||
TIM_t("群主"),
|
||||
style: TextStyle(fontSize: 14, color: theme.weakTextColor),
|
||||
),
|
||||
),
|
||||
if (isDesktopScreen)
|
||||
Container(
|
||||
alignment: Alignment.topLeft,
|
||||
padding: const EdgeInsets.only(top: 10, bottom: 4, left: 16),
|
||||
child: Text(
|
||||
TIM_t("群主"),
|
||||
style: TextStyle(fontSize: 14, color: theme.primaryColor),
|
||||
),
|
||||
),
|
||||
...ownerList
|
||||
.map(
|
||||
(e) => Container(
|
||||
padding: isDesktopScreen ? const EdgeInsets.only(left: 16) : null,
|
||||
child: _buildListItem(context, e!, null),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
if (!isDesktopScreen)
|
||||
Container(
|
||||
alignment: Alignment.topLeft,
|
||||
color: theme.weakDividerColor,
|
||||
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
||||
child: Text(
|
||||
TIM_t_para("管理员 ({{option2}}/10)", "管理员 ($option2/10)")(option2: option2),
|
||||
style: TextStyle(fontSize: 14, color: theme.weakTextColor),
|
||||
),
|
||||
),
|
||||
if (isDesktopScreen)
|
||||
Container(
|
||||
alignment: Alignment.topLeft,
|
||||
padding: const EdgeInsets.only(top: 10, bottom: 4, left: 16),
|
||||
child: Text(
|
||||
TIM_t_para("管理员 ({{option2}}/10)", "管理员 ($option2/10)")(option2: option2),
|
||||
style: TextStyle(fontSize: 14, color: theme.primaryColor),
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
child: Container(
|
||||
color: Colors.white,
|
||||
padding: const EdgeInsets.only(left: 16),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 12,
|
||||
),
|
||||
decoration: isDesktopScreen
|
||||
? null
|
||||
: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.add_circle_outline,
|
||||
color: theme.primaryColor,
|
||||
size: 20,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Text(TIM_t("添加管理员"))
|
||||
],
|
||||
),
|
||||
)),
|
||||
onTap: () async {
|
||||
if (isDesktopScreen) {
|
||||
TUIKitWidePopup.showPopupWindow(
|
||||
operationKey: TUIKitWideModalOperationKey.setAdmins,
|
||||
context: context,
|
||||
title: TIM_t("设置管理员"),
|
||||
width: MediaQuery.of(context).size.width * 0.5,
|
||||
height: MediaQuery.of(context).size.height * 0.8,
|
||||
onSubmit: () {
|
||||
groupProfileAddAdminKey.currentState?.onSubmit();
|
||||
},
|
||||
child: (onClose) => GroupProfileAddAdmin(
|
||||
key: groupProfileAddAdminKey,
|
||||
memberList: memberList
|
||||
.where(
|
||||
(element) => element?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER)
|
||||
.toList(),
|
||||
appbarTitle: TIM_t("设置管理员"),
|
||||
selectCompletedHandler: (context, selectedMember) async {
|
||||
if (selectedMember.isNotEmpty) {
|
||||
for (var member in selectedMember) {
|
||||
final userID = member!.userID;
|
||||
widget.model.setMemberToAdmin(userID);
|
||||
}
|
||||
}
|
||||
},
|
||||
));
|
||||
} else {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => GroupProfileAddAdmin(
|
||||
key: groupProfileAddAdminKey,
|
||||
memberList: memberList
|
||||
.where((element) =>
|
||||
element?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER)
|
||||
.toList(),
|
||||
appbarTitle: TIM_t("设置管理员"),
|
||||
selectCompletedHandler: (context, selectedMember) async {
|
||||
if (selectedMember.isNotEmpty) {
|
||||
for (var member in selectedMember) {
|
||||
final userID = member!.userID;
|
||||
widget.model.setMemberToAdmin(userID);
|
||||
}
|
||||
}
|
||||
},
|
||||
)));
|
||||
}
|
||||
},
|
||||
),
|
||||
...adminList
|
||||
.map((e) => GestureDetector(
|
||||
onSecondaryTapDown: (details) {
|
||||
TUIKitWidePopup.showPopupWindow(
|
||||
operationKey: TUIKitWideModalOperationKey.deleteAdmin,
|
||||
isDarkBackground: false,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4)),
|
||||
context: context,
|
||||
offset: Offset(min(details.globalPosition.dx, MediaQuery.of(context).size.width - 80),
|
||||
details.globalPosition.dy),
|
||||
child: (onClose) => TUIKitColumnMenu(data: [
|
||||
ColumnMenuItem(
|
||||
label: TIM_t("删除"),
|
||||
icon: const Icon(Icons.remove_circle_outline, size: 16),
|
||||
onClick: () {
|
||||
_removeAdmin(context, e);
|
||||
onClose();
|
||||
}),
|
||||
]));
|
||||
},
|
||||
child: Container(
|
||||
padding: isDesktopScreen ? const EdgeInsets.only(left: 16) : null,
|
||||
child: _buildListItem(
|
||||
context,
|
||||
e!,
|
||||
ActionPane(motion: const DrawerMotion(), children: [
|
||||
SlidableAction(
|
||||
onPressed: (_) {
|
||||
_removeAdmin(context, e);
|
||||
},
|
||||
flex: 1,
|
||||
backgroundColor: theme.cautionColor ?? CommonColor.cautionColor,
|
||||
autoClose: true,
|
||||
label: TIM_t("删除"),
|
||||
)
|
||||
])),
|
||||
),
|
||||
))
|
||||
.toList(),
|
||||
],
|
||||
));
|
||||
}
|
||||
|
||||
return TUIKitScreenUtils.getDeviceWidget(
|
||||
context: context,
|
||||
desktopWidget: adminPage(),
|
||||
defaultWidget: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
TIM_t("设置管理员"),
|
||||
style: TextStyle(color: theme.appbarTextColor, fontSize: 17),
|
||||
),
|
||||
shadowColor: theme.weakDividerColor,
|
||||
backgroundColor: theme.appbarBgColor ?? theme.primaryColor,
|
||||
iconTheme: IconThemeData(
|
||||
color: theme.appbarTextColor,
|
||||
),
|
||||
),
|
||||
body: adminPage(),
|
||||
));
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 添加管理员
|
||||
class GroupProfileAddAdmin extends StatefulWidget {
|
||||
final List<V2TimGroupMemberFullInfo?> memberList;
|
||||
final String appbarTitle;
|
||||
final void Function(BuildContext context, List<V2TimGroupMemberFullInfo?> selectedMemberList)? selectCompletedHandler;
|
||||
|
||||
const GroupProfileAddAdmin(
|
||||
{Key? key, required this.memberList, this.selectCompletedHandler, required this.appbarTitle})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _GroupProfileAddAdminState();
|
||||
}
|
||||
|
||||
class _GroupProfileAddAdminState extends TIMUIKitState<GroupProfileAddAdmin> {
|
||||
List<V2TimGroupMemberFullInfo?> selectedMemberList = [];
|
||||
|
||||
void onSubmit() {
|
||||
if (widget.selectCompletedHandler != null) {
|
||||
widget.selectCompletedHandler!(context, selectedMemberList);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
|
||||
Widget addAdminPage() {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
alignment: Alignment.topLeft,
|
||||
color: theme.weakDividerColor,
|
||||
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
||||
child: Text(
|
||||
TIM_t("群成员"),
|
||||
style: TextStyle(fontSize: 14, color: theme.weakTextColor),
|
||||
),
|
||||
),
|
||||
...widget.memberList
|
||||
.map((e) => Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border:
|
||||
Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
final isChecked = selectedMemberList.contains(e);
|
||||
if (isChecked) {
|
||||
selectedMemberList.remove(e);
|
||||
} else {
|
||||
selectedMemberList.add(e);
|
||||
}
|
||||
setState(() {});
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
CheckBoxButton(
|
||||
onlyShow: true,
|
||||
isChecked: selectedMemberList.contains(e),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
SizedBox(
|
||||
width: 36,
|
||||
height: 36,
|
||||
child: Avatar(
|
||||
faceUrl: e?.faceUrl ?? "",
|
||||
showName: _getShowName(e),
|
||||
type: 2,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text(_getShowName(e), style: const TextStyle(fontSize: 16))
|
||||
],
|
||||
),
|
||||
),
|
||||
))
|
||||
.toList(),
|
||||
],
|
||||
));
|
||||
}
|
||||
|
||||
return TUIKitScreenUtils.getDeviceWidget(
|
||||
context: context,
|
||||
desktopWidget: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: addAdminPage(),
|
||||
),
|
||||
defaultWidget: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
widget.appbarTitle,
|
||||
style: TextStyle(color: theme.appbarTextColor, fontSize: 17),
|
||||
),
|
||||
shadowColor: theme.weakDividerColor,
|
||||
backgroundColor: theme.appbarBgColor ?? theme.primaryColor,
|
||||
iconTheme: IconThemeData(
|
||||
color: theme.appbarTextColor,
|
||||
),
|
||||
leadingWidth: 80,
|
||||
leading: TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
TIM_t("取消"),
|
||||
style: TextStyle(
|
||||
color: theme.appbarTextColor,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
onSubmit();
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
TIM_t("完成"),
|
||||
style: TextStyle(
|
||||
color: theme.appbarTextColor,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
body: addAdminPage()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
// ignore_for_file: unused_element
|
||||
|
||||
import 'package:dotted_border/dotted_border.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_member_full_info.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/group_member/tui_add_group_member.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/group_member/tui_delete_group_member.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/group_member/tui_group_member_list.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class GroupMemberTitle extends TIMUIKitStatelessWidget {
|
||||
GroupMemberTitle({
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
List<V2TimGroupMemberFullInfo?> _getMemberList(memberList, int showRange) {
|
||||
if (memberList.length > showRange) {
|
||||
return memberList.getRange(0, showRange).toList();
|
||||
} else {
|
||||
return memberList;
|
||||
}
|
||||
}
|
||||
|
||||
_getShowName(V2TimGroupMemberFullInfo? item) {
|
||||
final friendRemark = item?.friendRemark ?? "";
|
||||
final nickName = item?.nickName ?? "";
|
||||
final userID = item?.userID;
|
||||
final showName = nickName != "" ? nickName : userID;
|
||||
return friendRemark != "" ? friendRemark : showName;
|
||||
}
|
||||
|
||||
List<Widget> _groupMemberListBuilder(List memberList, TUITheme theme, TUIGroupProfileModel model, int showRange) {
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop;
|
||||
return _getMemberList(memberList, showRange).map((element) {
|
||||
final faceUrl = element?.faceUrl ?? "";
|
||||
final showName = _getShowName(element);
|
||||
return InkWell(
|
||||
onTapDown: (details) {
|
||||
if (model.onClickUser != null && element?.userID != null) {
|
||||
model.onClickUser!(element!, details);
|
||||
}
|
||||
},
|
||||
child: SizedBox(
|
||||
width: isDesktopScreen ? 36 : 60,
|
||||
height: isDesktopScreen ? 36 : 76,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: isDesktopScreen ? 36 : 50,
|
||||
height: isDesktopScreen ? 36 : 50,
|
||||
child: Avatar(
|
||||
borderRadius: isDesktopScreen ? BorderRadius.circular(18) : null,
|
||||
faceUrl: faceUrl,
|
||||
showName: showName,
|
||||
type: 1,
|
||||
),
|
||||
),
|
||||
if (!isDesktopScreen)
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
if (!isDesktopScreen)
|
||||
Text(
|
||||
showName,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(overflow: TextOverflow.ellipsis, color: theme.weakTextColor, fontSize: 10),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
List<Widget> _inviteMemberBuilder(bool isCanInviteMember, bool isCanKickOffMember, theme, BuildContext context) {
|
||||
return [];
|
||||
}
|
||||
|
||||
void navigateToMemberList(
|
||||
BuildContext context, TUIGroupProfileModel model, List<V2TimGroupMemberFullInfo?> memberList) {
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
if (!isDesktopScreen) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => GroupProfileMemberListPage(model: model, memberList: memberList),
|
||||
));
|
||||
} else {
|
||||
final option1 = memberList.length.toString();
|
||||
TUIKitWidePopup.showPopupWindow(
|
||||
operationKey: TUIKitWideModalOperationKey.groupMembersList,
|
||||
context: context,
|
||||
width: MediaQuery.of(context).size.width * 0.5,
|
||||
height: MediaQuery.of(context).size.height * 0.8,
|
||||
title: TIM_t_para("群成员({{option1}}人)", "群成员($option1人)")(option1: option1),
|
||||
child: (onClose) => GroupProfileMemberListPage(model: model, memberList: memberList));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final model = Provider.of<TUIGroupProfileModel>(context);
|
||||
final memberAmount = model.groupInfo?.memberCount ?? 0;
|
||||
final option1 = memberAmount.toString();
|
||||
final memberList = model.groupMemberList;
|
||||
final isCanInviteMember = model.canInviteMember();
|
||||
final isCanKickOffMember = model.canKickOffMember();
|
||||
|
||||
int showRange = isDesktopScreen ? 7 : 8;
|
||||
if (isDesktopScreen && isCanInviteMember) {
|
||||
showRange--;
|
||||
}
|
||||
if (isDesktopScreen && isCanKickOffMember) {
|
||||
showRange--;
|
||||
}
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
decoration: isDesktopScreen
|
||||
? null
|
||||
: BoxDecoration(
|
||||
border: Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
navigateToMemberList(context, model, memberList);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(TIM_t("群成员"), style: TextStyle(color: theme.darkTextColor, fontSize: isDesktopScreen ? 14 : 16)),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
TIM_t_para("{{option1}}人", "$option1人")(option1: option1),
|
||||
style: TextStyle(color: theme.darkTextColor, fontSize: isDesktopScreen ? 14 : 16),
|
||||
),
|
||||
Icon(
|
||||
Icons.keyboard_arrow_right,
|
||||
color: theme.weakTextColor,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isDesktopScreen)
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
navigateToMemberList(context, model, memberList);
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(width: 1, color: theme.weakDividerColor ?? CommonColor.weakDividerColor),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4)),
|
||||
),
|
||||
// height: 30,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.search,
|
||||
color: hexToColor("979797"),
|
||||
size: 16,
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(TIM_t("搜索"),
|
||||
style: TextStyle(
|
||||
color: theme.weakTextColor,
|
||||
fontSize: 12,
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
// height: 90,
|
||||
padding: const EdgeInsets.only(top: 12),
|
||||
child: Wrap(
|
||||
spacing: isDesktopScreen ? 10 : 20,
|
||||
runSpacing: 10,
|
||||
alignment: WrapAlignment.start,
|
||||
children: [
|
||||
..._groupMemberListBuilder(memberList, theme, model, showRange),
|
||||
if (isCanInviteMember)
|
||||
DottedBorder(
|
||||
borderType: BorderType.RRect,
|
||||
radius: Radius.circular(isDesktopScreen ? 18 : 4.5),
|
||||
color: theme.weakTextColor!,
|
||||
dashPattern: const [6, 3],
|
||||
child: SizedBox(
|
||||
width: isDesktopScreen ? 32 : 48,
|
||||
height: isDesktopScreen ? 32 : 48,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
if (isDesktopScreen) {
|
||||
TUIKitWidePopup.showPopupWindow(
|
||||
context: context,
|
||||
operationKey: TUIKitWideModalOperationKey.addGroupMembers,
|
||||
width: 350,
|
||||
title: TIM_t("添加群成员"),
|
||||
height: 460,
|
||||
onSubmit: () {
|
||||
addGroupMemberKey.currentState?.submitAdd();
|
||||
},
|
||||
child: (onClose) => AddGroupMemberPage(
|
||||
model: model,
|
||||
onClose: onClose,
|
||||
key: addGroupMemberKey,
|
||||
));
|
||||
} else {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => AddGroupMemberPage(
|
||||
model: model,
|
||||
),
|
||||
));
|
||||
}
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.add,
|
||||
size: isDesktopScreen ? 16 : 18,
|
||||
),
|
||||
color: theme.weakTextColor,
|
||||
),
|
||||
)),
|
||||
if (isCanKickOffMember)
|
||||
DottedBorder(
|
||||
borderType: BorderType.RRect,
|
||||
radius: Radius.circular(isDesktopScreen ? 18 : 4.5),
|
||||
color: theme.weakTextColor!,
|
||||
dashPattern: const [6, 3],
|
||||
child: SizedBox(
|
||||
width: isDesktopScreen ? 32 : 48,
|
||||
height: isDesktopScreen ? 32 : 48,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
if (isDesktopScreen) {
|
||||
TUIKitWidePopup.showPopupWindow(
|
||||
operationKey: TUIKitWideModalOperationKey.kickOffGroupMembers,
|
||||
context: context,
|
||||
width: 350,
|
||||
title: TIM_t("删除群成员"),
|
||||
height: 460,
|
||||
onSubmit: () {
|
||||
deleteGroupMemberKey.currentState?.submitDelete();
|
||||
},
|
||||
child: (onClose) => DeleteGroupMemberPage(
|
||||
model: model,
|
||||
onClose: onClose,
|
||||
key: deleteGroupMemberKey,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DeleteGroupMemberPage(model: model),
|
||||
));
|
||||
}
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.remove,
|
||||
size: isDesktopScreen ? 16 : 18,
|
||||
),
|
||||
color: theme.weakTextColor,
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (memberList.length > showRange)
|
||||
InkWell(
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
margin: EdgeInsets.only(top: isDesktopScreen ? 12 : 16),
|
||||
child: Text(
|
||||
TIM_t("查看更多群成员"),
|
||||
style: TextStyle(color: theme.weakTextColor, fontSize: isDesktopScreen ? 12 : 14),
|
||||
),
|
||||
),
|
||||
onTap: () async {
|
||||
navigateToMemberList(context, model, memberList);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitProfile/widget/tim_uikit_operation_item.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
|
||||
class GroupMessageDisturb extends TIMUIKitStatelessWidget {
|
||||
GroupMessageDisturb({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final model = Provider.of<TUIGroupProfileModel>(context);
|
||||
final isShowDisturb = model.groupInfo?.groupType == "Meeting" ? false : true;
|
||||
final isDisturb = model.conversation?.recvOpt != 0;
|
||||
if (!isShowDisturb) {
|
||||
return Container();
|
||||
}
|
||||
return TIMUIKitOperationItem(
|
||||
isEmpty: false,
|
||||
operationName: TIM_t("消息免打扰"),
|
||||
type: "switch",
|
||||
isUseCheckedBoxOnWide: true,
|
||||
operationValue: isDisturb,
|
||||
onSwitchChange: (value) {
|
||||
model.setMessageDisturb(value);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
// ignore_for_file: unnecessary_null_comparison
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/text_input_bottom_sheet.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class GroupProfileNameCard extends StatefulWidget {
|
||||
const GroupProfileNameCard({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => GroupProfileNameCardState();
|
||||
|
||||
}
|
||||
|
||||
class GroupProfileNameCardState extends TIMUIKitState<GroupProfileNameCard>{
|
||||
final TextEditingController controller = TextEditingController();
|
||||
String? nameCard;
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final model = Provider.of<TUIGroupProfileModel>(context);
|
||||
if (model == null) {
|
||||
return Container();
|
||||
}
|
||||
nameCard = model.getSelfNameCard();
|
||||
controller.text = nameCard ?? "";
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: isDesktopScreen ? null : Border(
|
||||
bottom: BorderSide(
|
||||
color:
|
||||
theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
if (!isDesktopScreen) {
|
||||
TextInputBottomSheet.showTextInputBottomSheet(
|
||||
context: context,
|
||||
title: TIM_t("修改我的群昵称"),
|
||||
tips: TIM_t("仅限中文、字母、数字和下划线,2-20个字"),
|
||||
onSubmitted: (String nameCard) async {
|
||||
final text = nameCard.trim();
|
||||
model.setNameCard(text);
|
||||
},
|
||||
theme: theme);
|
||||
}
|
||||
},
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Container(
|
||||
margin: const EdgeInsets.only(right: 10),
|
||||
child: Text(
|
||||
TIM_t("我的群昵称"),
|
||||
style: TextStyle(
|
||||
fontSize: isDesktopScreen ? 14 : 16,
|
||||
color: theme.darkTextColor),
|
||||
),
|
||||
),
|
||||
if (!isDesktopScreen)
|
||||
Expanded(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
nameCard ?? "",
|
||||
style: TextStyle(
|
||||
fontSize: isDesktopScreen ? 14 : 16,
|
||||
color: theme.darkTextColor),
|
||||
)),
|
||||
Icon(Icons.keyboard_arrow_right,
|
||||
color: theme.weakTextColor)
|
||||
],
|
||||
)),
|
||||
],
|
||||
),
|
||||
if (isDesktopScreen)
|
||||
Text(
|
||||
TIM_t("仅限中文、字母、数字和下划线,2-20个字"),
|
||||
style: TextStyle(color: theme.weakTextColor, fontSize: 12),
|
||||
),
|
||||
if (isDesktopScreen)
|
||||
Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 10),
|
||||
height: 30,
|
||||
child: TextField(
|
||||
minLines: 1,
|
||||
controller: controller,
|
||||
maxLines: 1,
|
||||
onSubmitted: (text) {
|
||||
model.setNameCard(text.trim());
|
||||
},
|
||||
keyboardType: TextInputType.multiline,
|
||||
autofocus: true,
|
||||
textAlignVertical: TextAlignVertical.center,
|
||||
textAlign: TextAlign.start,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 10, vertical: 10),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5.0),
|
||||
borderSide: BorderSide(
|
||||
color: theme.weakDividerColor ?? Colors.grey,
|
||||
)),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5.0),
|
||||
borderSide: BorderSide(
|
||||
color: theme.weakDividerColor ?? Colors.grey,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
//选中时外边框颜色
|
||||
borderRadius: BorderRadius.circular(5.0),
|
||||
borderSide: BorderSide(
|
||||
color: theme.weakTextColor ?? Colors.grey,
|
||||
),
|
||||
),
|
||||
hintStyle: const TextStyle(
|
||||
color: Color(0xFFAEA4A3),
|
||||
),
|
||||
hintText: TIM_t("修改我的群昵称"))),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class GroupProfileNotification extends StatefulWidget {
|
||||
final bool isHavePermission;
|
||||
|
||||
const GroupProfileNotification({Key? key, this.isHavePermission = false}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => GroupProfileNotificationState();
|
||||
}
|
||||
|
||||
class GroupProfileNotificationState extends TIMUIKitState<GroupProfileNotification> {
|
||||
bool isShowEditBox = false;
|
||||
final TextEditingController _controller = TextEditingController();
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
final model = Provider.of<TUIGroupProfileModel>(context);
|
||||
final String notification = (model.groupInfo?.notification != null && model.groupInfo!.notification!.isNotEmpty)
|
||||
? model.groupInfo!.notification!
|
||||
: TIM_t("暂无群公告");
|
||||
|
||||
_setGroupNotification() async {
|
||||
setState(() {
|
||||
isShowEditBox = false;
|
||||
});
|
||||
final notification = _controller.text;
|
||||
await model.setGroupNotification(notification);
|
||||
}
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: isDesktopScreen
|
||||
? null
|
||||
: Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: InkWell(
|
||||
onTap: !widget.isHavePermission
|
||||
? null
|
||||
: (() {
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
if (!isDesktopScreen) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
GroupProfileNotificationPage(model: model, notification: notification)));
|
||||
} else {
|
||||
setState(() {
|
||||
isShowEditBox = !isShowEditBox;
|
||||
if (isShowEditBox) {
|
||||
_controller.text = notification;
|
||||
}
|
||||
});
|
||||
}
|
||||
}),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
TIM_t("群公告"),
|
||||
style: TextStyle(color: theme.darkTextColor, fontSize: isDesktopScreen ? 14 : 16),
|
||||
),
|
||||
),
|
||||
if (widget.isHavePermission)
|
||||
AnimatedRotation(
|
||||
turns: isShowEditBox ? 0.25 : 0,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Icon(Icons.keyboard_arrow_right, color: theme.weakTextColor),
|
||||
)
|
||||
],
|
||||
),
|
||||
if (!isShowEditBox)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: isDesktopScreen ? 4 : 0),
|
||||
child: SelectableText(notification,
|
||||
// overflow: isDesktopScreen ? null : TextOverflow.ellipsis,
|
||||
// softWrap: true,
|
||||
style: TextStyle(color: theme.weakTextColor, fontSize: 12)),
|
||||
),
|
||||
if (isShowEditBox)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 10, bottom: 10),
|
||||
// height: 150,
|
||||
child: TextField(
|
||||
minLines: 1,
|
||||
maxLines: 6,
|
||||
controller: _controller,
|
||||
keyboardType: TextInputType.multiline,
|
||||
autofocus: true,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
decoration: InputDecoration(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5.0),
|
||||
borderSide: BorderSide(
|
||||
color: theme.weakDividerColor ?? Colors.grey,
|
||||
)),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5.0),
|
||||
borderSide: BorderSide(
|
||||
color: theme.weakDividerColor ?? Colors.grey,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
//选中时外边框颜色
|
||||
borderRadius: BorderRadius.circular(5.0),
|
||||
borderSide: BorderSide(
|
||||
color: theme.weakTextColor ?? Colors.grey,
|
||||
),
|
||||
),
|
||||
hintStyle: const TextStyle(
|
||||
color: Color(0xFFAEA4A3),
|
||||
),
|
||||
hintText: '')),
|
||||
),
|
||||
if (isShowEditBox)
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
OutlinedButton(
|
||||
onPressed: _setGroupNotification,
|
||||
child: Text(
|
||||
TIM_t("保存"),
|
||||
style: TextStyle(fontSize: 13, color: theme.primaryColor),
|
||||
))
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GroupProfileNotificationPage extends StatefulWidget {
|
||||
final String notification;
|
||||
final TUIGroupProfileModel model;
|
||||
|
||||
const GroupProfileNotificationPage({Key? key, required this.notification, required this.model}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _GroupProfileNotificationPageState();
|
||||
}
|
||||
|
||||
class _GroupProfileNotificationPageState extends TIMUIKitState<GroupProfileNotificationPage> {
|
||||
final TextEditingController _controller = TextEditingController();
|
||||
bool isUpdated = false;
|
||||
|
||||
_setGroupNotification() async {
|
||||
final notification = _controller.text;
|
||||
await widget.model.setGroupNotification(notification);
|
||||
setState(() {
|
||||
isUpdated = true;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_controller.text = widget.notification;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
TIM_t("群公告"),
|
||||
style: TextStyle(color: theme.appbarTextColor, fontSize: 17),
|
||||
),
|
||||
backgroundColor: theme.appbarBgColor ?? theme.primaryColor,
|
||||
shadowColor: theme.weakDividerColor,
|
||||
iconTheme: IconThemeData(
|
||||
color: theme.appbarTextColor,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
if (isUpdated) {
|
||||
setState(() {
|
||||
isUpdated = false;
|
||||
});
|
||||
} else {
|
||||
_setGroupNotification();
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
isUpdated ? TIM_t("编辑") : TIM_t("完成"),
|
||||
style: TextStyle(
|
||||
color: theme.appbarTextColor,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: TextField(
|
||||
readOnly: isUpdated,
|
||||
controller: _controller,
|
||||
keyboardType: TextInputType.multiline,
|
||||
maxLines: null,
|
||||
expands: true,
|
||||
autofocus: true,
|
||||
decoration: const InputDecoration(
|
||||
border: InputBorder.none,
|
||||
hintStyle: TextStyle(
|
||||
// fontSize: 10,
|
||||
color: Color(0xFFAEA4A3),
|
||||
),
|
||||
hintText: '')),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitProfile/widget/tim_uikit_operation_item.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
|
||||
class GroupPinConversation extends TIMUIKitStatelessWidget {
|
||||
GroupPinConversation({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final model = Provider.of<TUIGroupProfileModel>(context);
|
||||
final isPined = model.conversation?.isPinned ?? false;
|
||||
return TIMUIKitOperationItem(
|
||||
isEmpty: false,
|
||||
operationName: TIM_t("置顶聊天"),
|
||||
type: "switch",
|
||||
isUseCheckedBoxOnWide: true,
|
||||
operationValue: isPined,
|
||||
onSwitchChange: (value) {
|
||||
model.pinedConversation(value);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/enum/group_type.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
|
||||
|
||||
class GroupProfileType extends TIMUIKitStatelessWidget {
|
||||
GroupProfileType({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
|
||||
String groupType;
|
||||
final model = Provider.of<TUIGroupProfileModel>(context);
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
final type = model.groupInfo?.groupType;
|
||||
switch (type) {
|
||||
case GroupType.AVChatRoom:
|
||||
groupType = TIM_t("聊天室");
|
||||
break;
|
||||
case GroupType.Meeting:
|
||||
groupType = TIM_t("会议群");
|
||||
break;
|
||||
case GroupType.Public:
|
||||
groupType = TIM_t("公开群");
|
||||
break;
|
||||
case GroupType.Work:
|
||||
groupType = TIM_t("工作群");
|
||||
break;
|
||||
case GroupType.Community:
|
||||
groupType = TIM_t("社群");
|
||||
break;
|
||||
default:
|
||||
groupType = TIM_t("未知群");
|
||||
break;
|
||||
}
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: isDesktopScreen ? null : Border(
|
||||
bottom: BorderSide(
|
||||
color:
|
||||
theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
TIM_t("群类型"),
|
||||
style: TextStyle(
|
||||
fontSize: isDesktopScreen ? 14 : 16, color: theme.darkTextColor),
|
||||
),
|
||||
Text(
|
||||
groupType,
|
||||
style: TextStyle(
|
||||
fontSize: isDesktopScreen ? 14 : 16, color: theme.weakTextColor),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user