init
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
import 'package:azlistview_all_platforms/azlistview_all_platforms.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lpinyin/lpinyin.dart';
|
||||
import 'package:provider/provider.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_sdk/tencent_im_sdk_plugin.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/listener_model/tui_group_listener_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_friendship_view_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/az_list_view.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_view_model.dart';
|
||||
|
||||
typedef GroupItemBuilder = Widget Function(BuildContext context, V2TimGroupInfo groupInfo);
|
||||
|
||||
class TIMUIKitGroup extends StatefulWidget {
|
||||
final void Function(V2TimGroupInfo groupInfo, V2TimConversation conversation)? onTapItem;
|
||||
final Widget Function(BuildContext context)? emptyBuilder;
|
||||
final GroupItemBuilder? itemBuilder;
|
||||
|
||||
/// the filter for group conversation
|
||||
final bool Function(V2TimGroupInfo? groupInfo)? groupCollector;
|
||||
|
||||
const TIMUIKitGroup({Key? key, this.onTapItem, this.emptyBuilder, this.itemBuilder, this.groupCollector})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _TIMUIKitGroupState();
|
||||
}
|
||||
|
||||
class _TIMUIKitGroupState extends TIMUIKitState<TIMUIKitGroup> {
|
||||
final TUIFriendShipViewModel _friendshipViewModel = serviceLocator<TUIFriendShipViewModel>();
|
||||
final TUIGroupListenerModel _groupListenerModel = serviceLocator<TUIGroupListenerModel>();
|
||||
|
||||
List<ISuspensionBeanImpl<V2TimGroupInfo>> _getShowList(List<V2TimGroupInfo> groupList) {
|
||||
final List<ISuspensionBeanImpl<V2TimGroupInfo>> showList = List.empty(growable: true);
|
||||
for (var i = 0; i < groupList.length; i++) {
|
||||
final item = groupList[i];
|
||||
|
||||
final showName = item.groupName ?? item.groupID;
|
||||
String pinyin = PinyinHelper.getPinyinE(showName);
|
||||
String tag = pinyin.substring(0, 1).toUpperCase();
|
||||
if (RegExp("[A-Z]").hasMatch(tag)) {
|
||||
showList.add(ISuspensionBeanImpl(memberInfo: item, tagIndex: tag));
|
||||
} else {
|
||||
showList.add(ISuspensionBeanImpl(memberInfo: item, tagIndex: "#"));
|
||||
}
|
||||
}
|
||||
|
||||
SuspensionUtil.sortListBySuspensionTag(showList);
|
||||
|
||||
return showList;
|
||||
}
|
||||
|
||||
Widget _itemBuilder(BuildContext context, V2TimGroupInfo groupInfo) {
|
||||
final theme = Provider.of<TUIThemeViewModel>(context).theme;
|
||||
final showName = groupInfo.groupName ?? groupInfo.groupID;
|
||||
final faceUrl = groupInfo.faceUrl ?? "";
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: Material(
|
||||
color: isDesktopScreen ? theme.wideBackgroundColor : null,
|
||||
child: InkWell(
|
||||
onTap: (() async {
|
||||
if (widget.onTapItem != null) {
|
||||
V2TimConversation conversation = V2TimConversation(
|
||||
conversationID: "group_${groupInfo.groupID}",
|
||||
groupID: groupInfo.groupID,
|
||||
type: 2,
|
||||
showName: groupInfo.groupName,
|
||||
groupType: groupInfo.groupType,
|
||||
faceUrl: groupInfo.faceUrl,
|
||||
);
|
||||
final res = await TencentImSDKPlugin.v2TIMManager
|
||||
.getConversationManager()
|
||||
.getConversation(conversationID: "group_${groupInfo.groupID}");
|
||||
if (res.code == 0 && res.data != null) {
|
||||
conversation = res.data!;
|
||||
}
|
||||
widget.onTapItem!(groupInfo, conversation);
|
||||
}
|
||||
}),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(top: 10, left: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
margin: const EdgeInsets.only(right: 12),
|
||||
child: SizedBox(
|
||||
height: isDesktopScreen ? 30 : 40,
|
||||
width: isDesktopScreen ? 30 : 40,
|
||||
child: Avatar(
|
||||
faceUrl: faceUrl,
|
||||
showName: showName,
|
||||
type: 2,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: const EdgeInsets.only(top: 10, bottom: 20),
|
||||
child: Text(
|
||||
showName,
|
||||
style: TextStyle(color: Colors.black, fontSize: isDesktopScreen ? 14 : 18),
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
GroupItemBuilder _getItemBuilder() {
|
||||
return widget.itemBuilder ?? _itemBuilder;
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_friendshipViewModel.loadGroupListData();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: _friendshipViewModel),
|
||||
ChangeNotifierProvider.value(value: _groupListenerModel),
|
||||
ChangeNotifierProvider.value(value: serviceLocator<TUIThemeViewModel>()),
|
||||
],
|
||||
builder: (BuildContext context, Widget? w) {
|
||||
final NeedUpdate? needUpdate = Provider.of<TUIGroupListenerModel>(context).needUpdate;
|
||||
if (needUpdate != null) {
|
||||
_groupListenerModel.needUpdate = null;
|
||||
switch (needUpdate.updateType) {
|
||||
case UpdateType.groupInfo:
|
||||
Provider.of<TUIFriendShipViewModel>(context).loadGroupListData();
|
||||
break;
|
||||
case UpdateType.memberList:
|
||||
Provider.of<TUIFriendShipViewModel>(context).loadGroupListData();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
List<V2TimGroupInfo> groupList = Provider.of<TUIFriendShipViewModel>(context).groupList;
|
||||
if (widget.groupCollector != null) {
|
||||
groupList = groupList.where(widget.groupCollector!).toList();
|
||||
}
|
||||
if (groupList.isNotEmpty) {
|
||||
final showList = _getShowList(groupList);
|
||||
return AZListViewContainer(
|
||||
isShowIndexBar: false,
|
||||
memberList: showList,
|
||||
itemBuilder: (context, index) {
|
||||
final groupInfo = showList[index].memberInfo;
|
||||
final itemBuilder = _getItemBuilder();
|
||||
return itemBuilder(context, groupInfo);
|
||||
});
|
||||
}
|
||||
|
||||
if (widget.emptyBuilder != null) {
|
||||
return widget.emptyBuilder!(context);
|
||||
}
|
||||
|
||||
return Container();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
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_application_type_enum.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_application.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_application.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/view_models/tui_chat_global_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/group/group_services.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/widgets/avatar.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';
|
||||
|
||||
typedef GroupApplicationItemBuilder = Widget Function(
|
||||
BuildContext context, V2TimGroupApplication applicationInfo, int index);
|
||||
|
||||
enum ApplicationStatus {
|
||||
none,
|
||||
accept,
|
||||
reject,
|
||||
}
|
||||
|
||||
class TIMUIKitGroupApplicationList extends StatefulWidget {
|
||||
/// the builder for the request item
|
||||
final GroupApplicationItemBuilder? itemBuilder;
|
||||
|
||||
/// group ID
|
||||
final String groupID;
|
||||
|
||||
const TIMUIKitGroupApplicationList({Key? key, this.itemBuilder, required this.groupID}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => TIMUIKitGroupApplicationListState();
|
||||
}
|
||||
|
||||
class TIMUIKitGroupApplicationListState extends TIMUIKitState<TIMUIKitGroupApplicationList> {
|
||||
final TUIChatGlobalModel model = serviceLocator<TUIChatGlobalModel>();
|
||||
final GroupServices _groupServices = serviceLocator<GroupServices>();
|
||||
List<V2TimGroupApplication> groupApplicationList = [];
|
||||
List<ApplicationStatus> applicationStatusList = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
groupApplicationList = model.groupApplicationList.where((item) => (item.groupID == widget.groupID)).toList();
|
||||
applicationStatusList = groupApplicationList.map((item) => ApplicationStatus.none).toList();
|
||||
}
|
||||
|
||||
GroupApplicationItemBuilder _getItemBuilder() {
|
||||
return widget.itemBuilder ?? _defaultItemBuilder;
|
||||
}
|
||||
|
||||
Widget _defaultItemBuilder(BuildContext context, V2TimGroupApplication applicationInfo, int index) {
|
||||
final theme = Provider.of<TUIThemeViewModel>(context).theme;
|
||||
final ApplicationStatus currentStatus = applicationStatusList[index];
|
||||
|
||||
String _getUserName() {
|
||||
if (applicationInfo.fromUserNickName != null &&
|
||||
applicationInfo.fromUserNickName!.isNotEmpty &&
|
||||
applicationInfo.fromUserNickName != applicationInfo.fromUser) {
|
||||
return "${applicationInfo.fromUserNickName} (${applicationInfo.fromUser})";
|
||||
} else {
|
||||
return "${applicationInfo.fromUser}";
|
||||
}
|
||||
}
|
||||
|
||||
String _getRequestMessage() {
|
||||
String option2 = applicationInfo.requestMsg ?? "";
|
||||
return TIM_t_para("验证消息: {{option2}}", "验证消息: $option2")(option2: option2);
|
||||
}
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(bottom: BorderSide(color: theme.weakDividerColor ?? const Color(0xFFDBDBDB))),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
margin: const EdgeInsets.only(right: 12),
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
width: 40,
|
||||
child: Avatar(
|
||||
faceUrl: applicationInfo.fromUserFaceUrl ?? "",
|
||||
showName: applicationInfo.fromUserNickName ?? applicationInfo.fromUser ?? ""),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
_getUserName(),
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: theme.darkTextColor),
|
||||
),
|
||||
Text(
|
||||
_getRequestMessage(),
|
||||
style: TextStyle(fontSize: 15, color: theme.weakTextColor),
|
||||
),
|
||||
],
|
||||
)),
|
||||
if (currentStatus == ApplicationStatus.none && applicationInfo.handleStatus == 0)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 8, right: 8),
|
||||
child: InkWell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
color: theme.primaryColor,
|
||||
border: Border.all(width: 1, color: theme.weakTextColor ?? CommonColor.weakTextColor)),
|
||||
child: Text(
|
||||
TIM_t("同意"), // agree
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () async {
|
||||
final res = await _groupServices.acceptGroupApplication(
|
||||
groupID: applicationInfo.groupID,
|
||||
fromUser: applicationInfo.fromUser!,
|
||||
toUser: applicationInfo.toUser!,
|
||||
type: applicationInfo.type,
|
||||
addTime: applicationInfo.addTime ?? 0,
|
||||
);
|
||||
if (res.code == 0) {
|
||||
setState(() {
|
||||
applicationStatusList[index] = ApplicationStatus.accept;
|
||||
});
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
model.refreshGroupApplicationList();
|
||||
});
|
||||
}
|
||||
}),
|
||||
),
|
||||
if (currentStatus == ApplicationStatus.none && applicationInfo.handleStatus == 0)
|
||||
InkWell(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
color: Colors.white,
|
||||
border: Border.all(width: 1, color: theme.weakTextColor ?? CommonColor.weakTextColor)),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
child: Text(
|
||||
TIM_t("拒绝"), // reject
|
||||
style: TextStyle(
|
||||
color: theme.primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () async {
|
||||
final res = await _groupServices.refuseGroupApplication(
|
||||
addTime: applicationInfo.addTime!,
|
||||
groupID: applicationInfo.groupID,
|
||||
fromUser: applicationInfo.fromUser!,
|
||||
toUser: applicationInfo.toUser!,
|
||||
type: GroupApplicationTypeEnum.values[applicationInfo.type]);
|
||||
if (res.code == 0) {
|
||||
setState(() {
|
||||
applicationStatusList[index] = ApplicationStatus.reject;
|
||||
});
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
model.refreshGroupApplicationList();
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
if (currentStatus == ApplicationStatus.accept || applicationInfo.handleResult == 1)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 8),
|
||||
child: Text(
|
||||
TIM_t("已同意"),
|
||||
style: TextStyle(fontSize: 15, color: theme.weakTextColor),
|
||||
),
|
||||
),
|
||||
if (currentStatus == ApplicationStatus.reject || applicationInfo.handleResult == 2)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 8),
|
||||
child: Text(
|
||||
TIM_t("已拒绝"),
|
||||
style: TextStyle(fontSize: 15, color: theme.weakTextColor),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
|
||||
return MultiProvider(
|
||||
providers: [ChangeNotifierProvider.value(value: model)],
|
||||
builder: (context, w) {
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
return Container(
|
||||
decoration: isDesktopScreen ? null : BoxDecoration(color: theme.weakBackgroundColor),
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: groupApplicationList.length,
|
||||
itemBuilder: (context, index) {
|
||||
final applicationInfo = groupApplicationList[index];
|
||||
final itemBuilder = _getItemBuilder();
|
||||
return itemBuilder(context, applicationInfo, index);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_application.dart'
|
||||
if (dart.library.html) 'package:tencent_cloud_chat_sdk/web/compatible_models/v2_tim_group_application.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.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';
|
||||
|
||||
enum ApplicationStatus {
|
||||
none,
|
||||
accept,
|
||||
refuse,
|
||||
}
|
||||
|
||||
class TIMUIKitGroupApplicationListItem extends StatefulWidget {
|
||||
final V2TimGroupApplication applicationInfo;
|
||||
|
||||
const TIMUIKitGroupApplicationListItem({Key? key, required this.applicationInfo}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => TIMUIKitGroupApplicationListItemState();
|
||||
}
|
||||
|
||||
class TIMUIKitGroupApplicationListItemState extends TIMUIKitState<TIMUIKitGroupApplicationListItem> {
|
||||
ApplicationStatus applicationStatus = ApplicationStatus.none;
|
||||
|
||||
String _getUserName() {
|
||||
if (widget.applicationInfo.fromUserNickName != null &&
|
||||
widget.applicationInfo.fromUserNickName!.isNotEmpty &&
|
||||
widget.applicationInfo.fromUserNickName != widget.applicationInfo.fromUser) {
|
||||
return "${widget.applicationInfo.fromUserNickName} (${widget.applicationInfo.fromUser})";
|
||||
} else {
|
||||
return "${widget.applicationInfo.fromUser}";
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: const BoxDecoration(color: Colors.white),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
margin: const EdgeInsets.only(right: 12),
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
width: 40,
|
||||
child: Avatar(
|
||||
faceUrl: widget.applicationInfo.fromUserFaceUrl ?? "",
|
||||
showName: widget.applicationInfo.fromUserNickName ?? widget.applicationInfo.fromUser ?? ""),
|
||||
),
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
Text(
|
||||
_getUserName(),
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: theme.darkTextColor),
|
||||
),
|
||||
Text(
|
||||
_getUserName(),
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: theme.darkTextColor),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user