基础页面
This commit is contained in:
50
lib/services/tim/apply_service.dart
Normal file
50
lib/services/tim/apply_service.dart
Normal file
@@ -0,0 +1,50 @@
|
||||
import 'package:chat/services/tim_service.dart';
|
||||
import 'package:chat/utils/ui_tools.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tencent_im_sdk_plugin/enum/friend_application_type_enum.dart';
|
||||
import 'package:tencent_im_sdk_plugin/enum/friend_response_type_enum.dart';
|
||||
import 'package:tencent_im_sdk_plugin/manager/v2_tim_friendship_manager.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_friend_application.dart';
|
||||
|
||||
class TimApplyService extends GetxService {
|
||||
static TimApplyService get to => Get.find<TimApplyService>();
|
||||
|
||||
/// 好友申请
|
||||
RxList<V2TimFriendApplication?> applies =
|
||||
List<V2TimFriendApplication?>.empty(growable: true).obs;
|
||||
|
||||
/// 好友关系
|
||||
V2TIMFriendshipManager get friendshipManager =>
|
||||
TimService.to.instance.v2TIMFriendshipManager;
|
||||
|
||||
@override
|
||||
void onInit() async {
|
||||
super.onInit();
|
||||
await fetchList();
|
||||
}
|
||||
|
||||
/// 获取申请列表
|
||||
Future<void> fetchList() async {
|
||||
var applyList = await friendshipManager.getFriendApplicationList();
|
||||
if (applyList.code == 0) {
|
||||
applies.value = applyList.data!.friendApplicationList!;
|
||||
}
|
||||
}
|
||||
|
||||
/// 接受好友请求
|
||||
Future<bool> accept(String userID) async {
|
||||
var result = await friendshipManager.acceptFriendApplication(
|
||||
responseType: FriendResponseTypeEnum.V2TIM_FRIEND_ACCEPT_AGREE_AND_ADD,
|
||||
type: FriendApplicationTypeEnum.V2TIM_FRIEND_APPLICATION_COME_IN,
|
||||
userID: userID,
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
await fetchList();
|
||||
return true;
|
||||
} else {
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
56
lib/services/tim/block_service.dart
Normal file
56
lib/services/tim/block_service.dart
Normal file
@@ -0,0 +1,56 @@
|
||||
import 'package:chat/services/tim_service.dart';
|
||||
import 'package:chat/utils/ui_tools.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tencent_im_sdk_plugin/manager/v2_tim_friendship_manager.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_friend_info.dart';
|
||||
|
||||
class TimBlockService extends GetxService {
|
||||
static TimBlockService get to => Get.find<TimBlockService>();
|
||||
|
||||
/// 好友关系
|
||||
V2TIMFriendshipManager get friendshipManager =>
|
||||
TimService.to.instance.v2TIMFriendshipManager;
|
||||
|
||||
@override
|
||||
void onInit() async {
|
||||
super.onInit();
|
||||
await fetchList();
|
||||
}
|
||||
|
||||
/// 黑名单列表
|
||||
RxList<V2TimFriendInfo> blocks =
|
||||
List<V2TimFriendInfo>.empty(growable: true).obs;
|
||||
|
||||
/// 拉取黑名单列表
|
||||
Future<void> fetchList() async {
|
||||
var blacklist = await friendshipManager.getBlackList();
|
||||
if (blacklist.code == 0) {
|
||||
blocks.value = blacklist.data!;
|
||||
}
|
||||
}
|
||||
|
||||
/// 拉黑某人
|
||||
Future<bool> add(String userID) async {
|
||||
var result = await friendshipManager.addToBlackList(userIDList: [userID]);
|
||||
|
||||
if (result.code == 0) {
|
||||
return result.data!.first.resultCode == 0;
|
||||
} else {
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 解除拉黑
|
||||
Future<bool> remove(String userID) async {
|
||||
var result =
|
||||
await friendshipManager.deleteFromBlackList(userIDList: [userID]);
|
||||
|
||||
if (result.code == 0) {
|
||||
return result.data!.first.resultCode == 0;
|
||||
} else {
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
379
lib/services/tim/conversation_service.dart
Normal file
379
lib/services/tim/conversation_service.dart
Normal file
@@ -0,0 +1,379 @@
|
||||
import 'package:chat/models/im/custom_message_model.dart';
|
||||
import 'package:chat/models/im/location_model.dart';
|
||||
import 'package:chat/services/tim_service.dart';
|
||||
import 'package:chat/utils/ui_tools.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tencent_im_sdk_plugin/enum/V2TimConversationListener.dart';
|
||||
import 'package:tencent_im_sdk_plugin/enum/conversation_type.dart';
|
||||
import 'package:tencent_im_sdk_plugin/enum/receive_message_opt_enum.dart';
|
||||
import 'package:tencent_im_sdk_plugin/manager/v2_tim_conversation_manager.dart';
|
||||
import 'package:tencent_im_sdk_plugin/manager/v2_tim_message_manager.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_callback.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_conversation.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_msg_create_info_result.dart';
|
||||
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
|
||||
|
||||
class TimConversationService extends GetxService {
|
||||
static TimConversationService get to => Get.find<TimConversationService>();
|
||||
|
||||
/// 消息管理实例
|
||||
V2TIMMessageManager get messageManager =>
|
||||
TimService.to.instance.v2TIMMessageManager;
|
||||
|
||||
/// 会话管理
|
||||
V2TIMConversationManager get conversationManager =>
|
||||
TimService.to.instance.v2ConversationManager;
|
||||
|
||||
@override
|
||||
void onInit() async {
|
||||
super.onInit();
|
||||
await fetchList();
|
||||
_addListener();
|
||||
}
|
||||
|
||||
_addListener() {
|
||||
conversationManager.addConversationListener(
|
||||
listener: V2TimConversationListener(
|
||||
|
||||
/// 未读消息总数监听
|
||||
onTotalUnreadMessageCountChanged: (_) {
|
||||
unreadCount.value = _;
|
||||
}));
|
||||
}
|
||||
|
||||
/// 会话列表
|
||||
RxList<V2TimConversation?> conversationList =
|
||||
List<V2TimConversation?>.empty(growable: true).obs;
|
||||
|
||||
/// 未读消息总数
|
||||
var unreadCount = 0.obs;
|
||||
|
||||
Future<void> fetchList() async {
|
||||
var data = await conversationManager.getConversationList(
|
||||
count: 100,
|
||||
nextSeq: '0',
|
||||
);
|
||||
|
||||
if (data.code == 0) {
|
||||
conversationList.value = data.data!.conversationList!;
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取未读消息数
|
||||
Future<void> getUnreadCount() async {
|
||||
var result = await conversationManager.getTotalUnreadMessageCount();
|
||||
unreadCount.value = result.data ?? 0;
|
||||
}
|
||||
|
||||
/// 获取会话信息
|
||||
Future<V2TimConversation> getById(
|
||||
String conversationID,
|
||||
) async {
|
||||
var result = await conversationManager.getConversation(
|
||||
conversationID: conversationID,
|
||||
);
|
||||
return result.data!;
|
||||
}
|
||||
|
||||
/// 标记会话已读
|
||||
Future<void> markAsRead(V2TimConversation conversation) async {
|
||||
/// 标记会话内消息已读
|
||||
if (conversation.type == ConversationType.V2TIM_GROUP) {
|
||||
await messageManager.markGroupMessageAsRead(
|
||||
groupID: conversation.groupID!,
|
||||
);
|
||||
} else {
|
||||
await messageManager.markC2CMessageAsRead(
|
||||
userID: conversation.userID!,
|
||||
);
|
||||
}
|
||||
fetchList();
|
||||
}
|
||||
|
||||
/// 从会话列表移除会话
|
||||
Future<void> delete(V2TimConversation conversation) async {
|
||||
await deleteById(conversation.conversationID);
|
||||
fetchList();
|
||||
}
|
||||
|
||||
Future<void> deleteById(String conversationID) async {
|
||||
await conversationManager.deleteConversation(
|
||||
conversationID: conversationID,
|
||||
);
|
||||
fetchList();
|
||||
}
|
||||
|
||||
/// 清空会话历史消息
|
||||
Future<void> clearHistoryMessage(V2TimConversation conversation) async {
|
||||
if (conversation.type == ConversationType.V2TIM_GROUP) {
|
||||
await messageManager.clearGroupHistoryMessage(
|
||||
groupID: conversation.groupID!,
|
||||
);
|
||||
} else {
|
||||
await messageManager.clearC2CHistoryMessage(
|
||||
userID: conversation.userID!,
|
||||
);
|
||||
}
|
||||
fetchList();
|
||||
}
|
||||
|
||||
/// 设置会话置顶/取消置顶
|
||||
Future<bool> setOnTop(V2TimConversation conversation) async {
|
||||
var result = await conversationManager.pinConversation(
|
||||
conversationID: conversation.conversationID,
|
||||
isPinned: !conversation.isPinned!,
|
||||
);
|
||||
fetchList();
|
||||
|
||||
if (result.code != 0) {
|
||||
UiTools.toast(result.desc);
|
||||
}
|
||||
|
||||
return result.code == 0;
|
||||
}
|
||||
|
||||
/// 开启/关闭消息免打扰
|
||||
Future<bool> setReceiveOpt(
|
||||
V2TimConversation conversation,
|
||||
) async {
|
||||
V2TimCallback result;
|
||||
|
||||
if (conversation.type == ConversationType.V2TIM_GROUP) {
|
||||
result = await messageManager.setGroupReceiveMessageOpt(
|
||||
groupID: conversation.groupID!,
|
||||
opt: (conversation.recvOpt == 0)
|
||||
? ReceiveMsgOptEnum.V2TIM_NOT_RECEIVE_MESSAGE
|
||||
: ReceiveMsgOptEnum.V2TIM_RECEIVE_MESSAGE,
|
||||
);
|
||||
} else {
|
||||
result = await messageManager.setC2CReceiveMessageOpt(
|
||||
userIDList: [
|
||||
conversation.userID!,
|
||||
],
|
||||
opt: (conversation.recvOpt == 0)
|
||||
? ReceiveMsgOptEnum.V2TIM_NOT_RECEIVE_MESSAGE
|
||||
: ReceiveMsgOptEnum.V2TIM_RECEIVE_MESSAGE,
|
||||
);
|
||||
}
|
||||
|
||||
fetchList();
|
||||
|
||||
return result.code == 0;
|
||||
}
|
||||
|
||||
/// 发送消息
|
||||
Future<bool> sendTextMessage(
|
||||
V2TimConversation conversation,
|
||||
String text,
|
||||
) async {
|
||||
var msg = await messageManager.createTextAtMessage(
|
||||
text: text,
|
||||
atUserList: [],
|
||||
);
|
||||
if (msg.code == 0) {
|
||||
return await _sendMessage(conversation, msg.data!);
|
||||
} else {
|
||||
UiTools.toast(msg.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 发送图片消息
|
||||
Future<bool> sendImageMessage(
|
||||
V2TimConversation conversation,
|
||||
AssetEntity asset,
|
||||
) async {
|
||||
var msg = await messageManager.createImageMessage(
|
||||
imagePath: (await asset.file)!.path,
|
||||
);
|
||||
if (msg.code == 0) {
|
||||
return await _sendMessage(conversation, msg.data!);
|
||||
} else {
|
||||
UiTools.toast(msg.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 发送语音消息
|
||||
Future<bool> sendSoundMessage(
|
||||
V2TimConversation conversation,
|
||||
String soundPath,
|
||||
int duration,
|
||||
) async {
|
||||
var msg = await messageManager.createSoundMessage(
|
||||
soundPath: soundPath, duration: duration);
|
||||
if (msg.code == 0) {
|
||||
return await _sendMessage(conversation, msg.data!);
|
||||
} else {
|
||||
UiTools.toast(msg.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 发送视频消息
|
||||
Future<bool> sendVideoMessage(
|
||||
V2TimConversation conversation,
|
||||
AssetEntity asset,
|
||||
) async {
|
||||
return false;
|
||||
// final originFile = await asset.originFile;
|
||||
// var size = await originFile!.length();
|
||||
|
||||
// if (size >= 104857600) {
|
||||
// UiTools.toast('视频文件不能超过100M');
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// final duration = asset.videoDuration.inSeconds;
|
||||
|
||||
// String tempPath = (await getTemporaryDirectory()).path;
|
||||
// String? thumbnail = await VideoThumbnail.thumbnailFile(
|
||||
// video: originFile.path,
|
||||
// thumbnailPath: tempPath,
|
||||
// imageFormat: ImageFormat.JPEG,
|
||||
// maxWidth: 256,
|
||||
// quality: 25,
|
||||
// );
|
||||
|
||||
// var msg = await messageManager.createVideoMessage(
|
||||
// videoFilePath: originFile.path,
|
||||
// type: asset.mimeType!.replaceFirst('video/', ''),
|
||||
// duration: duration,
|
||||
// snapshotPath: thumbnail ?? '',
|
||||
// );
|
||||
// if (msg.code == 0) {
|
||||
// return await _sendMessage(conversation, msg.data!);
|
||||
// } else {
|
||||
// UiTools.toast(msg.desc);
|
||||
// return false;
|
||||
// }
|
||||
}
|
||||
|
||||
/// 发送文件消息
|
||||
Future<bool> sendFileMessage(
|
||||
V2TimConversation conversation,
|
||||
String fileName,
|
||||
String filePath,
|
||||
) async {
|
||||
var msg = await messageManager.createFileMessage(
|
||||
fileName: fileName,
|
||||
filePath: filePath,
|
||||
);
|
||||
if (msg.code == 0) {
|
||||
return await _sendMessage(conversation, msg.data!);
|
||||
} else {
|
||||
UiTools.toast(msg.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 发送位置消息
|
||||
Future<bool> sendLocationMessage(
|
||||
V2TimConversation conversation,
|
||||
LocationModel messageModel,
|
||||
) async {
|
||||
var msg = await messageManager.createLocationMessage(
|
||||
desc: messageModel.name,
|
||||
latitude: messageModel.latitude,
|
||||
longitude: messageModel.longitude,
|
||||
);
|
||||
if (msg.code == 0) {
|
||||
return await _sendMessage(conversation, msg.data!);
|
||||
} else {
|
||||
UiTools.toast(msg.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 发送表情消息
|
||||
Future<bool> sendFaceMessage(
|
||||
V2TimConversation conversation,
|
||||
) async {
|
||||
var msg = await messageManager.createFaceMessage(
|
||||
data: '',
|
||||
index: 0,
|
||||
);
|
||||
if (msg.code == 0) {
|
||||
return await _sendMessage(conversation, msg.data!);
|
||||
} else {
|
||||
UiTools.toast(msg.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 发送聊天记录消息
|
||||
Future<bool> sendMergerMessage(
|
||||
V2TimConversation conversation,
|
||||
) async {
|
||||
var msg = await messageManager.createMergerMessage(
|
||||
abstractList: [],
|
||||
compatibleText: '',
|
||||
msgIDList: [],
|
||||
title: '',
|
||||
);
|
||||
if (msg.code == 0) {
|
||||
return await _sendMessage(conversation, msg.data!);
|
||||
} else {
|
||||
UiTools.toast(msg.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 发送自定义消息
|
||||
Future<bool> sendCustomMessage(
|
||||
V2TimConversation conversation,
|
||||
CustomMessageModel customMessageModel,
|
||||
String desc,
|
||||
) async {
|
||||
var msg = await messageManager.createCustomMessage(
|
||||
data: customMessageModel.toJson(),
|
||||
desc: desc,
|
||||
);
|
||||
if (msg.code == 0) {
|
||||
return await _sendMessage(conversation, msg.data!);
|
||||
} else {
|
||||
UiTools.toast(msg.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> _sendMessage(
|
||||
V2TimConversation conversation,
|
||||
V2TimMsgCreateInfoResult result,
|
||||
) async {
|
||||
var sendMessageRes = await messageManager.sendMessage(
|
||||
id: result.id!,
|
||||
receiver: conversation.type == ConversationType.V2TIM_C2C
|
||||
? conversation.userID!
|
||||
: '',
|
||||
groupID: conversation.type == ConversationType.V2TIM_GROUP
|
||||
? conversation.groupID!
|
||||
: '',
|
||||
// isExcludedFromUnreadCount: true,
|
||||
// isExcludedFromLastMessage: true,
|
||||
// needReadReceipt: true,
|
||||
);
|
||||
|
||||
if (sendMessageRes.code == 0) {
|
||||
// TimMessageService.to
|
||||
// .add(conversation.conversationID, result.messageInfo!);
|
||||
// eventBus.fire(result.messageInfo!);
|
||||
fetchList();
|
||||
return true;
|
||||
} else {
|
||||
UiTools.toast(sendMessageRes.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 设置会话草稿
|
||||
Future<void> draft(
|
||||
V2TimConversation conversation, {
|
||||
String? draftText = "",
|
||||
}) async {
|
||||
await conversationManager.setConversationDraft(
|
||||
conversationID: conversation.conversationID,
|
||||
draftText: draftText,
|
||||
);
|
||||
}
|
||||
}
|
||||
241
lib/services/tim/friend_service.dart
Normal file
241
lib/services/tim/friend_service.dart
Normal file
@@ -0,0 +1,241 @@
|
||||
import 'package:azlistview/azlistview.dart';
|
||||
import 'package:chat/models/im/contact_info_model.dart';
|
||||
import 'package:chat/models/im/search_user_model.dart';
|
||||
import 'package:chat/services/tim_service.dart';
|
||||
import 'package:chat/utils/im_tools.dart';
|
||||
import 'package:chat/utils/request/http.dart';
|
||||
import 'package:chat/utils/ui_tools.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:lpinyin/lpinyin.dart';
|
||||
import 'package:tencent_im_sdk_plugin/enum/friend_type_enum.dart';
|
||||
import 'package:tencent_im_sdk_plugin/manager/v2_tim_friendship_manager.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_friend_check_result.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_friend_info.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_friend_info_result.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_user_full_info.dart';
|
||||
|
||||
class TimFriendService extends GetxService {
|
||||
static TimFriendService get to => Get.find<TimFriendService>();
|
||||
|
||||
/// 好友关系
|
||||
V2TIMFriendshipManager get friendshipManager =>
|
||||
TimService.to.instance.v2TIMFriendshipManager;
|
||||
|
||||
/// 好友列表
|
||||
var friends = List<V2TimFriendInfo>.empty(growable: true).obs;
|
||||
|
||||
/// 格式化后的联系人信息
|
||||
var contacts = List<ContactInfoModel>.empty(growable: true).obs;
|
||||
|
||||
Future<void> fetchList() async {
|
||||
var result = await friendshipManager.getFriendList();
|
||||
if (result.code == 0) {
|
||||
friends.value = result.data!;
|
||||
contacts.clear();
|
||||
for (var element in result.data!) {
|
||||
String name = ImTools.parseNicknameFromInfo(element);
|
||||
String pinyin = PinyinHelper.getPinyinE(name);
|
||||
String tag = pinyin.substring(0, 1).toUpperCase();
|
||||
|
||||
if (!RegExp('[A-Z]').hasMatch(tag)) {
|
||||
tag = '#';
|
||||
}
|
||||
|
||||
contacts.add(ContactInfoModel(
|
||||
name: name,
|
||||
userID: element.userID,
|
||||
tagIndex: tag,
|
||||
namePinyin: pinyin,
|
||||
friendInfo: element,
|
||||
));
|
||||
}
|
||||
|
||||
SuspensionUtil.sortListBySuspensionTag(contacts);
|
||||
SuspensionUtil.setShowSuspensionStatus(contacts);
|
||||
}
|
||||
}
|
||||
|
||||
/// 添加好友
|
||||
Future<bool> add(
|
||||
String userID, {
|
||||
String? remark,
|
||||
String? addWording,
|
||||
String? addSource,
|
||||
}) async {
|
||||
var result = await friendshipManager.addFriend(
|
||||
userID: userID,
|
||||
remark: remark,
|
||||
addWording: addWording,
|
||||
addSource: addSource,
|
||||
addType: FriendTypeEnum.V2TIM_FRIEND_TYPE_BOTH,
|
||||
);
|
||||
if (result.code == 0) {
|
||||
if (result.data!.resultCode == 0) {
|
||||
fetchList();
|
||||
return true;
|
||||
} else if (result.data!.resultCode == 30539) {
|
||||
return true;
|
||||
} else if (result.data!.resultCode == 30010) {
|
||||
UiTools.toast('好友数量已达上限');
|
||||
return false;
|
||||
} else {
|
||||
UiTools.toast(
|
||||
result.data!.resultInfo! + result.data!.resultCode.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 删除双向好友
|
||||
Future<bool> delete(String userID) async {
|
||||
var result = await friendshipManager.deleteFromFriendList(
|
||||
deleteType: FriendTypeEnum.V2TIM_FRIEND_TYPE_BOTH,
|
||||
userIDList: [userID],
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
fetchList();
|
||||
return result.data!.first.resultCode == 0;
|
||||
} else {
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 检测好友是否有双向(单向)好友关系。
|
||||
Future<V2TimFriendCheckResult?> check(String userID) async {
|
||||
var result = await friendshipManager.checkFriend(
|
||||
checkType: FriendTypeEnum.V2TIM_FRIEND_TYPE_BOTH,
|
||||
userIDList: [userID],
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
return result.data!.first;
|
||||
} else {
|
||||
UiTools.toast(result.desc);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取用户资料
|
||||
Future<V2TimUserFullInfo?> userInfo(String userID) async {
|
||||
var result = await TimService.to.instance.getUsersInfo(
|
||||
userIDList: [userID],
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
return result.data!.first;
|
||||
}
|
||||
|
||||
UiTools.toast(result.desc);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// 获取好友资料
|
||||
Future<V2TimFriendInfoResult?> friendInfo(String userID) async {
|
||||
var result = await friendshipManager.getFriendsInfo(userIDList: [userID]);
|
||||
|
||||
if (result.code == 0) {
|
||||
if (result.data!.isNotEmpty) {
|
||||
return result.data!.first;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
UiTools.toast(result.desc);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// 修改个人资料
|
||||
Future<bool> setSelfInfo({
|
||||
String? nickname,
|
||||
String? avatar,
|
||||
}) async {
|
||||
var result = await TimService.to.instance.setSelfInfo(
|
||||
userFullInfo: V2TimUserFullInfo(
|
||||
nickName: nickname,
|
||||
faceUrl: avatar,
|
||||
),
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
// TimService.to.fetchSelfInfo();
|
||||
return true;
|
||||
}
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 设置是否允许陌生人消息
|
||||
Future<bool> allowStrangerMessage() async {
|
||||
var result = await TimService.to.instance.setSelfInfo(
|
||||
userFullInfo: V2TimUserFullInfo(
|
||||
customInfo: {
|
||||
'Stranger': 'TRUE',
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
return true;
|
||||
}
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 禁止陌生人消息
|
||||
Future<bool> forbidStrangerMessage() async {
|
||||
var result = await TimService.to.instance.setSelfInfo(
|
||||
userFullInfo: V2TimUserFullInfo(
|
||||
customInfo: {
|
||||
'Stranger': '',
|
||||
},
|
||||
),
|
||||
);
|
||||
if (result.code == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 修改好友备注信息
|
||||
Future<bool> setFriendRemark(
|
||||
String userID,
|
||||
String friendRemark,
|
||||
) async {
|
||||
var result = await friendshipManager.setFriendInfo(
|
||||
userID: userID,
|
||||
friendRemark: friendRemark,
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
return true;
|
||||
}
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 从服务器查找用户
|
||||
Future<List<SearchUserModel>?> searchUser(String keyword) async {
|
||||
try {
|
||||
var json = await Http.get(
|
||||
'user/search',
|
||||
params: {
|
||||
'keyword': keyword,
|
||||
},
|
||||
);
|
||||
|
||||
return List<SearchUserModel>.from(
|
||||
json.map(
|
||||
(x) => SearchUserModel.fromJson(x),
|
||||
),
|
||||
);
|
||||
} catch (err) {
|
||||
UiTools.toast(err.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
403
lib/services/tim/group_service.dart
Normal file
403
lib/services/tim/group_service.dart
Normal file
@@ -0,0 +1,403 @@
|
||||
import 'package:chat/services/tim/conversation_service.dart';
|
||||
import 'package:chat/services/tim_service.dart';
|
||||
import 'package:chat/utils/ui_tools.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tencent_im_sdk_plugin/enum/group_add_opt_enum.dart';
|
||||
import 'package:tencent_im_sdk_plugin/enum/group_application_type_enum.dart';
|
||||
import 'package:tencent_im_sdk_plugin/enum/group_member_filter_enum.dart';
|
||||
import 'package:tencent_im_sdk_plugin/enum/group_member_role_enum.dart';
|
||||
import 'package:tencent_im_sdk_plugin/enum/group_type.dart';
|
||||
import 'package:tencent_im_sdk_plugin/manager/v2_tim_group_manager.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_conversation.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_friend_info.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_group_application.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_group_info.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_group_member.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_group_member_full_info.dart';
|
||||
|
||||
class TimGroupService extends GetxService {
|
||||
static TimGroupService get to => Get.find<TimGroupService>();
|
||||
|
||||
/// 群管理实例
|
||||
V2TIMGroupManager get groupManager =>
|
||||
TimService.to.instance.v2TIMGroupManager;
|
||||
|
||||
/// 我的群组列表
|
||||
RxList<V2TimGroupInfo> groups =
|
||||
List<V2TimGroupInfo>.empty(growable: true).obs;
|
||||
|
||||
@override
|
||||
void onInit() async {
|
||||
super.onInit();
|
||||
await fetchList();
|
||||
}
|
||||
|
||||
Future<void> fetchList() async {
|
||||
var result = await groupManager.getJoinedGroupList();
|
||||
|
||||
if (result.code == 0) {
|
||||
groups.value = result.data!;
|
||||
}
|
||||
}
|
||||
|
||||
/// 创建群
|
||||
Future<String?> create(
|
||||
String groupName,
|
||||
List<V2TimFriendInfo> memberList, {
|
||||
String? groupType,
|
||||
}) async {
|
||||
var result = await groupManager.createGroup(
|
||||
groupType: groupType ?? GroupType.Public,
|
||||
groupName: groupName,
|
||||
notification: '',
|
||||
introduction: '',
|
||||
faceUrl: '',
|
||||
isAllMuted: false,
|
||||
isSupportTopic: false,
|
||||
addOpt: GroupAddOptTypeEnum.V2TIM_GROUP_ADD_AUTH,
|
||||
memberList: memberList.map((e) {
|
||||
return V2TimGroupMember(
|
||||
role: GroupMemberRoleTypeEnum.V2TIM_GROUP_MEMBER_ROLE_MEMBER,
|
||||
userID: e.userID,
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
|
||||
if (result.code != 0) {
|
||||
UiTools.toast(result.desc);
|
||||
}
|
||||
|
||||
await fetchList();
|
||||
await TimConversationService.to.fetchList();
|
||||
|
||||
return result.data;
|
||||
}
|
||||
|
||||
/// 加群申请列表
|
||||
Future<List<V2TimGroupApplication?>?> applies(String groupID) async {
|
||||
var result = await groupManager.getGroupApplicationList();
|
||||
|
||||
if (result.code == 0) {
|
||||
return result.data?.groupApplicationList;
|
||||
} else {
|
||||
UiTools.toast(result.desc);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// 同意加群
|
||||
Future<void> accept() async {
|
||||
await groupManager.acceptGroupApplication(
|
||||
fromUser: '',
|
||||
groupID: '',
|
||||
toUser: '',
|
||||
);
|
||||
}
|
||||
|
||||
/// 拒绝加群请求
|
||||
Future<void> refuse() async {
|
||||
await groupManager.refuseGroupApplication(
|
||||
addTime: 0,
|
||||
fromUser: '',
|
||||
groupID: '',
|
||||
toUser: '',
|
||||
type: GroupApplicationTypeEnum.V2TIM_GROUP_APPLICATION_GET_TYPE_JOIN,
|
||||
);
|
||||
}
|
||||
|
||||
/// 加入群组
|
||||
Future<bool> join(
|
||||
V2TimGroupInfo group,
|
||||
String message,
|
||||
) async {
|
||||
var result = await TimService.to.instance.joinGroup(
|
||||
groupID: group.groupID,
|
||||
groupType: group.groupType,
|
||||
message: message,
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
await fetchList();
|
||||
return true;
|
||||
} else {
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 邀请加群
|
||||
Future<bool> invite(
|
||||
V2TimGroupInfo group,
|
||||
List<String> userList,
|
||||
) async {
|
||||
var result = await groupManager.inviteUserToGroup(
|
||||
groupID: group.groupID,
|
||||
userList: userList,
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
return true;
|
||||
} else {
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 退出群组
|
||||
Future<void> quit(
|
||||
V2TimGroupInfo group,
|
||||
) async {
|
||||
await TimService.to.instance.quitGroup(
|
||||
groupID: group.groupID,
|
||||
);
|
||||
await fetchList();
|
||||
await TimConversationService.to.deleteById(
|
||||
'group_' + group.groupID,
|
||||
);
|
||||
}
|
||||
|
||||
/// 解散群组
|
||||
Future<bool> dismiss(
|
||||
V2TimGroupInfo group,
|
||||
V2TimConversation conversation,
|
||||
) async {
|
||||
var result = await TimService.to.instance.dismissGroup(
|
||||
groupID: group.groupID,
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
return true;
|
||||
}
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 获取群资料
|
||||
Future<V2TimGroupInfo?> info(String groupId) async {
|
||||
var result = await groupManager.getGroupsInfo(groupIDList: [groupId]);
|
||||
|
||||
if (result.code == 0) {
|
||||
return result.data![0].groupInfo!;
|
||||
} else {
|
||||
UiTools.toast(result.desc);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// 更新群资料
|
||||
Future<bool> updateName(
|
||||
V2TimGroupInfo group,
|
||||
String groupName,
|
||||
) async {
|
||||
var result = await groupManager.setGroupInfo(
|
||||
info: V2TimGroupInfo.fromJson(
|
||||
{
|
||||
'groupID': group.groupID,
|
||||
'groupType': group.groupType,
|
||||
'groupName': groupName,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
return true;
|
||||
}
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 更新群公告
|
||||
Future<bool> updateNotification(
|
||||
V2TimGroupInfo group,
|
||||
String notification,
|
||||
) async {
|
||||
var result = await groupManager.setGroupInfo(
|
||||
info: V2TimGroupInfo.fromJson(
|
||||
{
|
||||
'groupID': group.groupID,
|
||||
'groupType': group.groupType,
|
||||
'notification': notification,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
await TimConversationService.to.fetchList();
|
||||
return true;
|
||||
}
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 修改加群方式
|
||||
Future<bool> updateAddOpt(
|
||||
V2TimGroupInfo group,
|
||||
String notification,
|
||||
) async {
|
||||
var result = await groupManager.setGroupInfo(
|
||||
info: V2TimGroupInfo.fromJson(
|
||||
{
|
||||
'groupID': group.groupID,
|
||||
'groupType': group.groupType,
|
||||
'groupAddOpt': group.groupAddOpt,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
await TimConversationService.to.fetchList();
|
||||
return true;
|
||||
}
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 获取群组成员
|
||||
Future<List<V2TimGroupMemberFullInfo?>?> members(
|
||||
String groupID, {
|
||||
int count = 10,
|
||||
GroupMemberFilterTypeEnum filter =
|
||||
GroupMemberFilterTypeEnum.V2TIM_GROUP_MEMBER_FILTER_ALL,
|
||||
}) async {
|
||||
var result = await groupManager.getGroupMemberList(
|
||||
count: count,
|
||||
filter: filter,
|
||||
nextSeq: '0',
|
||||
offset: 0,
|
||||
groupID: groupID,
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
return result.data!.memberInfoList!;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// 获取群成员资料
|
||||
Future<V2TimGroupMemberFullInfo?> getMemberInfo(
|
||||
V2TimGroupInfo group,
|
||||
String userID,
|
||||
) async {
|
||||
var result = await groupManager.getGroupMembersInfo(
|
||||
groupID: group.groupID,
|
||||
memberList: [userID],
|
||||
);
|
||||
|
||||
if (result.data != null) {
|
||||
return result.data!.first;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// 设置群成员资料
|
||||
Future<bool> setMemberInfo(
|
||||
V2TimGroupInfo group,
|
||||
String userID,
|
||||
String nameCard,
|
||||
) async {
|
||||
var result = await groupManager.setGroupMemberInfo(
|
||||
groupID: group.groupID,
|
||||
userID: userID,
|
||||
nameCard: nameCard,
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
return true;
|
||||
}
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 禁言群成员, 时间单位秒,如果是0,应该就解除禁言了
|
||||
Future<bool> muteMember(
|
||||
V2TimGroupInfo group,
|
||||
String userID, {
|
||||
int seconds = 60,
|
||||
}) async {
|
||||
var result = await groupManager.muteGroupMember(
|
||||
groupID: group.groupID,
|
||||
userID: userID,
|
||||
seconds: seconds,
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
return true;
|
||||
}
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 全员禁言/解除全员禁言
|
||||
Future<bool> mute(
|
||||
V2TimGroupInfo group,
|
||||
bool isAllMuted,
|
||||
) async {
|
||||
var result = await groupManager.setGroupInfo(
|
||||
info: V2TimGroupInfo(
|
||||
isAllMuted: isAllMuted,
|
||||
groupID: group.groupID,
|
||||
groupType: group.groupType,
|
||||
),
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
return true;
|
||||
}
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 踢人
|
||||
Future<bool> kickMember(
|
||||
V2TimGroupInfo group,
|
||||
List<String> memberList,
|
||||
) async {
|
||||
var result = await groupManager.kickGroupMember(
|
||||
groupID: group.groupID,
|
||||
memberList: memberList,
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
return true;
|
||||
}
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 设置管理员
|
||||
Future<bool> setMemberRole(
|
||||
V2TimGroupInfo group,
|
||||
String userID,
|
||||
GroupMemberRoleTypeEnum role,
|
||||
) async {
|
||||
var result = await groupManager.setGroupMemberRole(
|
||||
groupID: group.groupID,
|
||||
userID: userID,
|
||||
role: role,
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
return true;
|
||||
}
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 转让群主
|
||||
Future<bool> transfer(
|
||||
V2TimGroupInfo group,
|
||||
String userID,
|
||||
) async {
|
||||
var result = await groupManager.transferGroupOwner(
|
||||
groupID: group.groupID,
|
||||
userID: userID,
|
||||
);
|
||||
|
||||
if (result.code == 0) {
|
||||
return true;
|
||||
}
|
||||
UiTools.toast(result.desc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
77
lib/services/tim/message_service.dart
Normal file
77
lib/services/tim/message_service.dart
Normal file
@@ -0,0 +1,77 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:scroll_to_index/scroll_to_index.dart';
|
||||
import 'package:tencent_im_sdk_plugin/enum/conversation_type.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_conversation.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_message.dart';
|
||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_value_callback.dart';
|
||||
import 'conversation_service.dart';
|
||||
|
||||
class LoadMessageResult {
|
||||
String? lastMsgId;
|
||||
bool noMore;
|
||||
|
||||
LoadMessageResult({
|
||||
this.lastMsgId,
|
||||
required this.noMore,
|
||||
});
|
||||
}
|
||||
|
||||
class TimMessageService extends GetxService {
|
||||
static TimMessageService get to => Get.find<TimMessageService>();
|
||||
|
||||
RxList<V2TimMessage> messages = List<V2TimMessage>.empty(growable: true).obs;
|
||||
|
||||
var curConversationId = '';
|
||||
|
||||
Future<String?> loadMessagesFromService(
|
||||
V2TimConversation conversation,
|
||||
String? lastMsgId,
|
||||
AutoScrollController _scrollController,
|
||||
) async {
|
||||
if (lastMsgId == null && curConversationId != conversation.conversationID) {
|
||||
messages.clear();
|
||||
curConversationId = conversation.conversationID;
|
||||
}
|
||||
|
||||
V2TimValueCallback<List<V2TimMessage>> result;
|
||||
if (conversation.type == ConversationType.V2TIM_GROUP) {
|
||||
result = await TimConversationService.to.messageManager
|
||||
.getGroupHistoryMessageList(
|
||||
groupID: conversation.groupID!,
|
||||
count: 20,
|
||||
lastMsgID: lastMsgId,
|
||||
);
|
||||
} else {
|
||||
result = await TimConversationService.to.messageManager
|
||||
.getC2CHistoryMessageList(
|
||||
userID: conversation.userID!,
|
||||
count: 20,
|
||||
lastMsgID: lastMsgId,
|
||||
);
|
||||
}
|
||||
var list = result.data ?? [];
|
||||
if (lastMsgId == null) {
|
||||
messages.value = list.reversed.toList();
|
||||
_scrollController.scrollToIndex(
|
||||
messages.length - 1,
|
||||
preferPosition: AutoScrollPosition.begin,
|
||||
);
|
||||
} else {
|
||||
//加载更多
|
||||
if (list.isNotEmpty) {
|
||||
messages.value = messages.reversed.toList(); //正常顺序
|
||||
messages.addAll(list);
|
||||
messages.value = messages.reversed.toList(); //反转一次
|
||||
}
|
||||
}
|
||||
if (messages.isNotEmpty) {
|
||||
return messages.first.msgID;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
addMessage(V2TimMessage message) {
|
||||
messages.add(message);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user