This commit is contained in:
2025-06-30 16:24:20 +08:00
commit 68de5eb048
454 changed files with 56921 additions and 0 deletions
@@ -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),
)
],
),
);
}
}