├── .all-contributorsrc ├── .github └── FUNDING.yml ├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── README_3.0_upgrade.md ├── android ├── .gitignore ├── build.gradle ├── consumer-proguard-rules.txt ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── top │ └── huic │ └── tencent_im_plugin │ ├── DownloadCallBack.java │ ├── TencentImPlugin.java │ ├── ValueCallBack.java │ ├── VoidCallBack.java │ ├── entity │ ├── CustomConversationEntity.java │ ├── CustomConversationResultEntity.java │ ├── CustomFriendAddApplication.java │ ├── CustomMessageEntity.java │ ├── FindFriendApplicationEntity.java │ ├── FindGroupApplicationEntity.java │ └── FindMessageEntity.java │ ├── enums │ ├── ListenerTypeEnum.java │ └── MessageNodeType.java │ ├── listener │ ├── CustomAdvancedMsgListener.java │ ├── CustomConversationListener.java │ ├── CustomFriendshipListener.java │ ├── CustomGroupListener.java │ ├── CustomSDKListener.java │ └── CustomSignalingListener.java │ ├── message │ ├── AbstractMessageNode.java │ ├── CustomMessageNode.java │ ├── FaceMessageNode.java │ ├── FileMessageNode.java │ ├── GroupTipsMessageNode.java │ ├── ImageMessageNode.java │ ├── LocationMessageNode.java │ ├── SoundMessageNode.java │ ├── TextMessageNode.java │ ├── VideoMessageNode.java │ └── entity │ │ ├── AbstractMessageEntity.java │ │ ├── CustomMessageEntity.java │ │ ├── FaceMessageEntity.java │ │ ├── FileMessageEntity.java │ │ ├── GroupTipsMessageEntity.java │ │ ├── ImageMessageEntity.java │ │ ├── LocationMessageEntity.java │ │ ├── SoundMessageEntity.java │ │ ├── TextMessageEntity.java │ │ └── VideoMessageEntity.java │ └── util │ ├── BeanUtils.java │ ├── CommonUtil.java │ ├── JsonUtil.java │ └── TencentImUtils.java ├── example ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── agconnect-services.json │ │ ├── build.gradle │ │ ├── key.jks │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── top │ │ │ │ │ └── huic │ │ │ │ │ └── tencent_im_plugin_example │ │ │ │ │ └── MainActivity.java │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ └── contents.xcworkspacedata │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h ├── lib │ ├── main.dart │ ├── page │ │ ├── chat.dart │ │ ├── home.dart │ │ ├── interfaces_test.dart │ │ ├── login.dart │ │ └── main │ │ │ ├── components │ │ │ ├── conversation.dart │ │ │ ├── friend.dart │ │ │ └── group.dart │ │ │ └── main.dart │ └── utils │ │ └── GenerateTestUserSig.dart ├── pubspec.lock ├── pubspec.yaml └── test │ └── widget_test.dart ├── ios ├── .gitignore ├── Assets │ └── .gitkeep ├── Classes │ ├── SwiftTencentImPlugin.swift │ ├── TencentImPlugin.h │ ├── TencentImPlugin.m │ ├── entity │ │ ├── CustomConversationEntity.swift │ │ ├── CustomConversationResultEntity.swift │ │ ├── CustomCreateGroupMemberEntity.swift │ │ ├── CustomFriendAddApplicationEntity.swift │ │ ├── CustomFriendApplicationEntity.swift │ │ ├── CustomFriendApplicationResultEntity.swift │ │ ├── CustomFriendCheckResultEntity.swift │ │ ├── CustomFriendGroupEntity.swift │ │ ├── CustomFriendInfoEntity.swift │ │ ├── CustomFriendInfoResultEntity.swift │ │ ├── CustomFriendOperationResultEntity.swift │ │ ├── CustomGroupApplicationEntity.swift │ │ ├── CustomGroupApplicationResultEntity.swift │ │ ├── CustomGroupAtInfoEntity.swift │ │ ├── CustomGroupChangeInfoEntity.swift │ │ ├── CustomGroupInfoEntity.swift │ │ ├── CustomGroupInfoResultEntity.swift │ │ ├── CustomGroupMemberChangeInfoEntity.swift │ │ ├── CustomGroupMemberFullInfoEntity.swift │ │ ├── CustomGroupMemberInfoResultEntity.swift │ │ ├── CustomGroupMemberOperationResultEntity.swift │ │ ├── CustomMessageReceiptEntity.swift │ │ ├── CustomOfflinePushInfoEntity.swift │ │ ├── CustomSignalingInfoEntity.swift │ │ ├── CustomUserEntity.swift │ │ ├── FindFriendApplicationEntity.swift │ │ ├── FindGroupApplicationEntity.swift │ │ ├── FindMessageEntity.swift │ │ └── MessageEntity.swift │ ├── enums │ │ ├── DownloadType.swift │ │ ├── ListenerType.swift │ │ └── MessageNodeType.swift │ ├── listener │ │ ├── CustomAPNSListener.swift │ │ ├── CustomAdvancedMsgListener.swift │ │ ├── CustomConversationListener.swift │ │ ├── CustomFriendshipListener.swift │ │ ├── CustomGroupListener.swift │ │ ├── CustomSDKListener.swift │ │ └── CustomSignalingListener.swift │ ├── message │ │ ├── AbstractMessageNode.swift │ │ ├── CustomMessageNode.swift │ │ ├── FaceMessageNode.swift │ │ ├── FileMessageNode.swift │ │ ├── GroupTipsMessageNode.swift │ │ ├── ImageMessageNode.swift │ │ ├── LocationMessageNode.swift │ │ ├── SoundMessageNode.swift │ │ ├── TextMessageNode.swift │ │ ├── VideoMessageNode.swift │ │ └── entity │ │ │ ├── AbstractMessageEntity.swift │ │ │ ├── CustomMessageEntity.swift │ │ │ ├── FaceMessageEntity.swift │ │ │ ├── FileMessageEntity.swift │ │ │ ├── LocationMessageEntity.swift │ │ │ ├── SoundMessageEntity.swift │ │ │ ├── TextMessageEntity.swift │ │ │ ├── VideoMessageEntity.swift │ │ │ ├── group_tips │ │ │ └── GroupTipsMessageEntity.swift │ │ │ └── image │ │ │ ├── ImageEntity.swift │ │ │ └── ImageMessageEntity.swift │ └── utils │ │ ├── CommonUtils.swift │ │ ├── JsonUtil.swift │ │ └── TencentImUtil.swift └── tencent_im_plugin.podspec ├── lib ├── entity │ ├── conversation_entity.dart │ ├── conversation_result_entity.dart │ ├── download_progress_entity.dart │ ├── error_entity.dart │ ├── find_friend_application_entity.dart │ ├── find_group_application_entity.dart │ ├── find_message_entity.dart │ ├── friend_add_application_entity.dart │ ├── friend_application_entity.dart │ ├── friend_application_result_entity.dart │ ├── friend_check_result_entity.dart │ ├── friend_group_entity.dart │ ├── friend_info_entity.dart │ ├── friend_info_result_entity.dart │ ├── friend_operation_result_entity.dart │ ├── group_administrator_op_entity.dart │ ├── group_application_entity.dart │ ├── group_application_processed_entity.dart │ ├── group_application_result_entity.dart │ ├── group_at_info_entity.dart │ ├── group_attribute_changed_entity.dart │ ├── group_changed_entity.dart │ ├── group_create_member_entity.dart │ ├── group_dismissed_or_recycled_entity.dart │ ├── group_info_entity.dart │ ├── group_info_result_entity.dart │ ├── group_member_changed_entity.dart │ ├── group_member_enter_entity.dart │ ├── group_member_entity.dart │ ├── group_member_info_result_entity.dart │ ├── group_member_invited_or_kicked_entity.dart │ ├── group_member_leave_entity.dart │ ├── group_member_operation_result_entity.dart │ ├── group_receive_join_application_entity.dart │ ├── group_receive_rest_entity.dart │ ├── message_entity.dart │ ├── message_receipt_entity.dart │ ├── message_search_param.dart │ ├── message_send_fail_entity.dart │ ├── message_send_progress_entity.dart │ ├── offline_push_info_entity.dart │ ├── signaling_common_entity.dart │ ├── signaling_info_entity.dart │ └── user_entity.dart ├── entity_factory.dart ├── enums │ ├── conversation_type_enum.dart │ ├── download_type_enum.dart │ ├── friend_application_agree_type_enum.dart │ ├── friend_application_type_enum.dart │ ├── friend_relation_type_enum.dart │ ├── friend_status_enum.dart │ ├── friend_type_enum.dart │ ├── get_message_type_enum.dart │ ├── group_add_opt_enum.dart │ ├── group_application_handler_result_enum.dart │ ├── group_application_handler_status_enum.dart │ ├── group_application_type_enum.dart │ ├── group_at_type_enum.dart │ ├── group_info_changed_type_enum.dart │ ├── group_member_filter_enum.dart │ ├── group_member_role_enum.dart │ ├── group_system_type.dart │ ├── group_tips_group_info_type.dart │ ├── group_tips_type_enum.dart │ ├── group_type_enum.dart │ ├── image_type_enum.dart │ ├── log_print_level.dart │ ├── login_status_enum.dart │ ├── message_elem_type_enum.dart │ ├── message_priority_enum.dart │ ├── message_status_enum.dart │ ├── operation_result_enum.dart │ ├── pendency_examine_type_enum.dart │ ├── pendency_type_enum.dart │ ├── receive_message_opt_enum.dart │ ├── signaling_action_type_enum.dart │ ├── sns_tips_type.dart │ ├── tencent_im_listener_type_enum.dart │ ├── user_allow_type_enum.dart │ └── user_gender_enum.dart ├── list_util.dart ├── listener │ └── tencent_im_plugin_listener.dart ├── message_node │ ├── custom_message_node.dart │ ├── face_message_node.dart │ ├── file_message_node.dart │ ├── group_tips_message_node.dart │ ├── image_message_node.dart │ ├── location_message_node.dart │ ├── message_node.dart │ ├── sound_message_node.dart │ ├── text_message_node.dart │ └── video_message_node.dart ├── tencent_im_plugin.dart └── utils │ └── enum_util.dart ├── pubspec.lock └── pubspec.yaml /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "contributors": [ 8 | { 9 | "login": "kxr224", 10 | "name": "cyrus", 11 | "avatar_url": "https://avatars.githubusercontent.com/u/28681083?v=4", 12 | "profile": "https://github.com/kxr224", 13 | "contributions": [ 14 | "bug" 15 | ] 16 | }, 17 | { 18 | "login": "songjiabin", 19 | "name": "宋佳宾", 20 | "avatar_url": "https://avatars.githubusercontent.com/u/13177100?v=4", 21 | "profile": "https://github.com/songjiabin", 22 | "contributions": [ 23 | "code" 24 | ] 25 | }, 26 | { 27 | "login": "ligui-iOS", 28 | "name": "ligui-iOS", 29 | "avatar_url": "https://avatars.githubusercontent.com/u/20856361?v=4", 30 | "profile": "https://github.com/ligui-iOS", 31 | "contributions": [ 32 | "code" 33 | ] 34 | }, 35 | { 36 | "login": "laiiihz", 37 | "name": "LAIIIHZ", 38 | "avatar_url": "https://avatars.githubusercontent.com/u/35956195?v=4", 39 | "profile": "http://laiiihz.github.io", 40 | "contributions": [ 41 | "code" 42 | ] 43 | } 44 | ], 45 | "contributorsPerLine": 7, 46 | "projectName": "FlutterTencentImPlugin", 47 | "projectOwner": "JiangJuHong", 48 | "repoType": "github", 49 | "repoHost": "https://github.com", 50 | "skipCi": true 51 | } 52 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: https://www.yuque.com/jiangjuhong/tencent-im-flutter/ygi582 # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | .idea 7 | *.iml 8 | build/ 9 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: d345a3b303ce041846ff895eb49a104bef133c4b 8 | channel: master 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /README_3.0_upgrade.md: -------------------------------------------------------------------------------- 1 | # 3.0升级文档 2 | 3 | ## 通用变化 4 | 5 | * 将 `setReceiveMessageOpt` 替换为 `setGroupReceiveMessageOpt` 6 | * 将 `GroupReceiveMessageOptEnum` 替换为 `ReceiveMessageOptEnum` 7 | * `MessageStatusEnum` 增加 Imported 属性 8 | 9 | ## 新增内容 10 | 11 | * 新增 ``setGroupReceiveMessageOpt`` 设置群接收消息选项接口 12 | * 新增 ``setC2CReceiveMessageOpt`` 设置C2C接收消息选项接口 13 | * 新增 ``ReceiveMessageOptEnum`` 接收消息选项枚举类 14 | * 新增 ``pinConversation`` 置顶会话接口 15 | * 新增 ``getTotalUnreadMessageCount`` 获得会话总未读数接口 16 | * 新增 ``conversation`` 增加 ``pinned`` 会话是否置顶属性 17 | * 新增 ``insertC2CMessageToLocalStorage`` 添加C2C会话接口 18 | * 新增 ``setOfflinePushConfig`` 接口增加 tpns 参数 19 | * 新增 ``searchGroups`` 搜索群接口 20 | * 新增 ``searchGroupMembers`` 搜索群成员接口 21 | * 新增 ``UserEntity`` 增加 生日(birthday) 属性 22 | 23 | ## 移除内容 24 | 25 | * 移除 ``setReceiveMessageOpt`` 接口 26 | * 移除 ``GroupReceiveMessageOptEnum`` 枚举 -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'top.huic.tencent_im_plugin' 2 | version '1.0' 3 | 4 | buildscript { 5 | repositories { 6 | // maven { url 'https://maven.aliyun.com/repository/google' } 7 | // maven { url 'https://maven.aliyun.com/repository/jcenter' } 8 | // maven { url 'http://maven.aliyun.com/nexus/content/groups/public' } 9 | google() 10 | jcenter() 11 | } 12 | 13 | dependencies { 14 | classpath 'com.android.tools.build:gradle:3.5.3' 15 | } 16 | } 17 | 18 | rootProject.allprojects { 19 | repositories { 20 | // maven { url 'https://maven.aliyun.com/repository/google' } 21 | // maven { url 'https://maven.aliyun.com/repository/jcenter' } 22 | // maven { url 'http://maven.aliyun.com/nexus/content/groups/public' } 23 | google() 24 | jcenter() 25 | } 26 | } 27 | 28 | apply plugin: 'com.android.library' 29 | 30 | android { 31 | compileSdkVersion 28 32 | 33 | defaultConfig { 34 | minSdkVersion 16 35 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 36 | ndk { 37 | abiFilters "armeabi-v7a" 38 | } 39 | // library 混淆 -> 随 library 引用,自动添加到 apk 打包混淆 40 | consumerProguardFiles 'consumer-proguard-rules.txt' 41 | } 42 | lintOptions { 43 | disable 'InvalidPackage' 44 | } 45 | dependencies { 46 | api 'com.tencent.imsdk:imsdk-plus:6.1.2155' 47 | api 'com.alibaba:fastjson:1.1.72.android' 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /android/consumer-proguard-rules.txt: -------------------------------------------------------------------------------- 1 | # 腾讯云IM 2 | -keep class com.tencent.** { *; } 3 | 4 | # FastJson 5 | -dontwarn com.alibaba.fastjson.** 6 | -keep class com.alibaba.fastjson.**{*;} 7 | 8 | # 泛型 9 | -keepattributes Signature 10 | 11 | # 不混淆Serializable接口的子类 12 | -keepclassmembers class * implements java.io.Serializable { *; } 13 | 14 | # 忽略实体类 15 | -keep class top.huic.tencent_im_plugin.** {*;} -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Dec 05 14:15:15 CST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'tencent_im_plugin' 2 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/ValueCallBack.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin; 2 | 3 | import com.tencent.imsdk.v2.V2TIMValueCallback; 4 | 5 | import io.flutter.plugin.common.MethodChannel.Result; 6 | import top.huic.tencent_im_plugin.util.JsonUtil; 7 | 8 | /** 9 | * 值改变回调 10 | * 11 | * @author 蒋具宏 12 | */ 13 | public class ValueCallBack implements V2TIMValueCallback { 14 | /** 15 | * 回调 16 | */ 17 | private Result result; 18 | 19 | public ValueCallBack(Result result) { 20 | this.result = result; 21 | } 22 | 23 | /** 24 | * 成功事件 25 | * 26 | * @param t 结果 27 | */ 28 | @Override 29 | public void onSuccess(T t) { 30 | if (result != null) { 31 | if(t instanceof Number || t instanceof String || t instanceof Boolean){ 32 | result.success(t); 33 | }else{ 34 | result.success(JsonUtil.toJSONString(t)); 35 | } 36 | } 37 | } 38 | 39 | 40 | /** 41 | * 失败事件 42 | * 43 | * @param code 错误码 44 | * @param desc 错误描述 45 | */ 46 | @Override 47 | public void onError(int code, String desc) { 48 | if (this.result != null) { 49 | result.error(String.valueOf(code), desc, desc); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/VoidCallBack.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin; 2 | 3 | import com.tencent.imsdk.v2.V2TIMCallback; 4 | 5 | import io.flutter.plugin.common.MethodChannel; 6 | 7 | /** 8 | * 操作结果回调 9 | * 10 | * @author 蒋具宏 11 | */ 12 | public class VoidCallBack implements V2TIMCallback { 13 | /** 14 | * 回调 15 | */ 16 | private MethodChannel.Result result; 17 | 18 | public VoidCallBack(MethodChannel.Result result) { 19 | this.result = result; 20 | } 21 | 22 | @Override 23 | public void onError(int code, String desc) { 24 | if (result != null) { 25 | result.error(String.valueOf(code), "Execution Error", desc); 26 | } 27 | } 28 | 29 | @Override 30 | public void onSuccess() { 31 | if (result != null) { 32 | result.success(null); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/entity/CustomConversationResultEntity.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.entity; 2 | 3 | import com.tencent.imsdk.v2.V2TIMConversation; 4 | import com.tencent.imsdk.v2.V2TIMConversationResult; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import top.huic.tencent_im_plugin.util.BeanUtils; 10 | 11 | /** 12 | * 自定义会话结果实体 13 | */ 14 | public class CustomConversationResultEntity { 15 | 16 | /** 17 | * 下一次分页拉取的游标 18 | */ 19 | private Long nextSeq; 20 | 21 | /** 22 | * 会话列表是否已经拉取完毕 23 | */ 24 | private Boolean finished; 25 | 26 | /** 27 | * 会话列表 28 | */ 29 | private List conversationList; 30 | 31 | public CustomConversationResultEntity() { 32 | } 33 | 34 | public CustomConversationResultEntity(V2TIMConversationResult data) { 35 | BeanUtils.copyProperties(data, this, "conversationList"); 36 | 37 | if (data.getConversationList() != null) { 38 | List conversationList = new ArrayList<>(data.getConversationList().size()); 39 | for (V2TIMConversation item : data.getConversationList()) { 40 | conversationList.add(new CustomConversationEntity(item)); 41 | } 42 | this.conversationList = conversationList; 43 | } 44 | } 45 | 46 | public Long getNextSeq() { 47 | return nextSeq; 48 | } 49 | 50 | public void setNextSeq(Long nextSeq) { 51 | this.nextSeq = nextSeq; 52 | } 53 | 54 | public Boolean getFinished() { 55 | return finished; 56 | } 57 | 58 | public void setFinished(Boolean finished) { 59 | this.finished = finished; 60 | } 61 | 62 | public List getConversationList() { 63 | return conversationList; 64 | } 65 | 66 | public void setConversationList(List conversationList) { 67 | this.conversationList = conversationList; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/entity/CustomFriendAddApplication.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.entity; 2 | 3 | import com.tencent.imsdk.v2.V2TIMFriendAddApplication; 4 | 5 | /** 6 | * 自定义好友添加申请实体 7 | */ 8 | public class CustomFriendAddApplication extends V2TIMFriendAddApplication { 9 | public CustomFriendAddApplication() { 10 | super(null); 11 | } 12 | 13 | public CustomFriendAddApplication(String userID) { 14 | super(userID); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/entity/FindFriendApplicationEntity.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.entity; 2 | 3 | /** 4 | * 查找好友申请实体 5 | */ 6 | public class FindFriendApplicationEntity { 7 | /** 8 | * 用户ID 9 | */ 10 | String userID; 11 | 12 | /** 13 | * 类型 14 | */ 15 | int type; 16 | 17 | public String getUserID() { 18 | return userID; 19 | } 20 | 21 | public void setUserID(String userID) { 22 | this.userID = userID; 23 | } 24 | 25 | public int getType() { 26 | return type; 27 | } 28 | 29 | public void setType(int type) { 30 | this.type = type; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/entity/FindGroupApplicationEntity.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.entity; 2 | 3 | /** 4 | * 查找群申请实体 5 | */ 6 | public class FindGroupApplicationEntity { 7 | /** 8 | * 来自用户 9 | */ 10 | String fromUser; 11 | 12 | /** 13 | * 群ID 14 | */ 15 | String groupID; 16 | 17 | public String getFromUser() { 18 | return fromUser; 19 | } 20 | 21 | public void setFromUser(String fromUser) { 22 | this.fromUser = fromUser; 23 | } 24 | 25 | public String getGroupID() { 26 | return groupID; 27 | } 28 | 29 | public void setGroupID(String groupID) { 30 | this.groupID = groupID; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/entity/FindMessageEntity.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.entity; 2 | 3 | /** 4 | * 查找消息实体 5 | */ 6 | public class FindMessageEntity { 7 | /** 8 | * 消息ID 9 | */ 10 | private String msgId; 11 | 12 | public FindMessageEntity() { 13 | } 14 | 15 | public FindMessageEntity(String msgId) { 16 | this.msgId = msgId; 17 | } 18 | 19 | public String getMsgId() { 20 | return msgId; 21 | } 22 | 23 | public void setMsgId(String msgId) { 24 | this.msgId = msgId; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/listener/CustomAdvancedMsgListener.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.listener; 2 | 3 | import com.tencent.imsdk.v2.V2TIMAdvancedMsgListener; 4 | import com.tencent.imsdk.v2.V2TIMMessage; 5 | import com.tencent.imsdk.v2.V2TIMMessageReceipt; 6 | 7 | import java.util.List; 8 | 9 | import top.huic.tencent_im_plugin.TencentImPlugin; 10 | import top.huic.tencent_im_plugin.entity.CustomMessageEntity; 11 | import top.huic.tencent_im_plugin.enums.ListenerTypeEnum; 12 | 13 | /** 14 | * 消息相关监听器 15 | */ 16 | public class CustomAdvancedMsgListener extends V2TIMAdvancedMsgListener { 17 | /** 18 | * 新消息通知 19 | */ 20 | @Override 21 | public void onRecvNewMessage(V2TIMMessage msg) { 22 | super.onRecvNewMessage(msg); 23 | TencentImPlugin.invokeListener(ListenerTypeEnum.NewMessage, new CustomMessageEntity(msg)); 24 | } 25 | 26 | /** 27 | * C2C已读回执 28 | */ 29 | @Override 30 | public void onRecvC2CReadReceipt(List receiptList) { 31 | super.onRecvC2CReadReceipt(receiptList); 32 | TencentImPlugin.invokeListener(ListenerTypeEnum.C2CReadReceipt, receiptList); 33 | } 34 | 35 | /** 36 | * 消息撤回 37 | */ 38 | @Override 39 | public void onRecvMessageRevoked(String msgID) { 40 | super.onRecvMessageRevoked(msgID); 41 | TencentImPlugin.invokeListener(ListenerTypeEnum.MessageRevoked, msgID); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/listener/CustomSDKListener.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.listener; 2 | 3 | import com.tencent.imsdk.v2.V2TIMSDKListener; 4 | import com.tencent.imsdk.v2.V2TIMUserFullInfo; 5 | 6 | import java.util.HashMap; 7 | 8 | import top.huic.tencent_im_plugin.TencentImPlugin; 9 | import top.huic.tencent_im_plugin.enums.ListenerTypeEnum; 10 | 11 | /** 12 | * SDK基本监听器 13 | */ 14 | public class CustomSDKListener extends V2TIMSDKListener { 15 | /** 16 | * 正在连接到腾讯云服务器 17 | */ 18 | @Override 19 | public void onConnecting() { 20 | super.onConnecting(); 21 | TencentImPlugin.invokeListener(ListenerTypeEnum.Connecting, null); 22 | } 23 | 24 | /** 25 | * 网络连接成功 26 | */ 27 | @Override 28 | public void onConnectSuccess() { 29 | super.onConnectSuccess(); 30 | TencentImPlugin.invokeListener(ListenerTypeEnum.ConnectSuccess, null); 31 | } 32 | 33 | /** 34 | * 网络连接失败 35 | */ 36 | @Override 37 | public void onConnectFailed(final int code, final String error) { 38 | super.onConnectFailed(code, error); 39 | TencentImPlugin.invokeListener(ListenerTypeEnum.ConnectFailed, new HashMap() { 40 | { 41 | put("code", code); 42 | put("error", error); 43 | } 44 | }); 45 | } 46 | 47 | /** 48 | * 踢下线通知 49 | */ 50 | @Override 51 | public void onKickedOffline() { 52 | super.onKickedOffline(); 53 | TencentImPlugin.invokeListener(ListenerTypeEnum.KickedOffline, null); 54 | } 55 | 56 | /** 57 | * 当前用户的资料发生了更新 58 | */ 59 | @Override 60 | public void onSelfInfoUpdated(V2TIMUserFullInfo info) { 61 | super.onSelfInfoUpdated(info); 62 | TencentImPlugin.invokeListener(ListenerTypeEnum.SelfInfoUpdated, info); 63 | } 64 | 65 | /** 66 | * 用户登录的 userSig 过期(用户需要重新获取 userSig 后登录) 67 | */ 68 | @Override 69 | public void onUserSigExpired() { 70 | super.onUserSigExpired(); 71 | TencentImPlugin.invokeListener(ListenerTypeEnum.UserSigExpired, null); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/AbstractMessageNode.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message; 2 | 3 | import com.tencent.imsdk.v2.V2TIMMessage; 4 | 5 | import top.huic.tencent_im_plugin.message.entity.AbstractMessageEntity; 6 | 7 | /** 8 | * 消息节点接口 9 | * 10 | * @param 节点类型,对应腾讯云 TIMElem 11 | */ 12 | public abstract class AbstractMessageNode { 13 | /** 14 | * 获得发送的消息体 15 | * 16 | * @param entity 消息实体 17 | * @return 结果 18 | */ 19 | public V2TIMMessage getV2TIMMessage(E entity) { 20 | throw new RuntimeException("This node does not support sending"); 21 | } 22 | 23 | /** 24 | * 根据消息节点获得描述 25 | * 26 | * @param elem 节点 27 | */ 28 | public abstract String getNote(N elem); 29 | 30 | /** 31 | * 将节点解析为实体对象 32 | * 33 | * @param elem 节点 34 | * @return 实体对象 35 | */ 36 | public abstract E analysis(N elem); 37 | 38 | /** 39 | * 获得实体类型 40 | * 41 | * @return 类型 42 | */ 43 | public abstract Class getEntityClass(); 44 | } -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/CustomMessageNode.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message; 2 | 3 | import com.tencent.imsdk.v2.V2TIMCustomElem; 4 | import com.tencent.imsdk.v2.V2TIMManager; 5 | import com.tencent.imsdk.v2.V2TIMMessage; 6 | 7 | import top.huic.tencent_im_plugin.message.entity.CustomMessageEntity; 8 | 9 | /** 10 | * 自定义消息节点 11 | */ 12 | public class CustomMessageNode extends AbstractMessageNode { 13 | 14 | @Override 15 | public V2TIMMessage getV2TIMMessage(CustomMessageEntity entity) { 16 | return V2TIMManager.getMessageManager().createCustomMessage(entity.getData().getBytes(), entity.getDesc(), entity.getExt() == null ? null : entity.getExt().getBytes()); 17 | } 18 | 19 | @Override 20 | public String getNote(V2TIMCustomElem elem) { 21 | return "[其它消息]"; 22 | } 23 | 24 | @Override 25 | public CustomMessageEntity analysis(V2TIMCustomElem elem) { 26 | return new CustomMessageEntity(elem); 27 | } 28 | 29 | @Override 30 | public Class getEntityClass() { 31 | return CustomMessageEntity.class; 32 | } 33 | } -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/FaceMessageNode.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message; 2 | 3 | import com.tencent.imsdk.v2.V2TIMFaceElem; 4 | import com.tencent.imsdk.v2.V2TIMManager; 5 | import com.tencent.imsdk.v2.V2TIMMessage; 6 | 7 | import top.huic.tencent_im_plugin.message.entity.FaceMessageEntity; 8 | 9 | /** 10 | * 表情消息节点 11 | */ 12 | public class FaceMessageNode extends AbstractMessageNode { 13 | 14 | @Override 15 | public V2TIMMessage getV2TIMMessage(FaceMessageEntity entity) { 16 | return V2TIMManager.getMessageManager().createFaceMessage(entity.getIndex(), entity.getData().getBytes()); 17 | } 18 | 19 | @Override 20 | public String getNote(V2TIMFaceElem elem) { 21 | return "[表情]"; 22 | } 23 | 24 | @Override 25 | public FaceMessageEntity analysis(V2TIMFaceElem elem) { 26 | return new FaceMessageEntity(elem); 27 | } 28 | 29 | @Override 30 | public Class getEntityClass() { 31 | return FaceMessageEntity.class; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/FileMessageNode.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message; 2 | 3 | import com.tencent.imsdk.v2.V2TIMFileElem; 4 | import com.tencent.imsdk.v2.V2TIMManager; 5 | import com.tencent.imsdk.v2.V2TIMMessage; 6 | 7 | import top.huic.tencent_im_plugin.message.entity.FileMessageEntity; 8 | 9 | /** 10 | * 文件消息节点 11 | */ 12 | public class FileMessageNode extends AbstractMessageNode { 13 | @Override 14 | public V2TIMMessage getV2TIMMessage(FileMessageEntity entity) { 15 | return V2TIMManager.getMessageManager().createFileMessage(entity.getFilePath(), entity.getFileName()); 16 | } 17 | 18 | @Override 19 | public String getNote(V2TIMFileElem elem) { 20 | return "[文件]"; 21 | } 22 | 23 | @Override 24 | public FileMessageEntity analysis(V2TIMFileElem elem) { 25 | return new FileMessageEntity(elem); 26 | } 27 | 28 | @Override 29 | public Class getEntityClass() { 30 | return FileMessageEntity.class; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/GroupTipsMessageNode.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message; 2 | 3 | import com.tencent.imsdk.v2.V2TIMGroupTipsElem; 4 | 5 | import top.huic.tencent_im_plugin.message.entity.GroupTipsMessageEntity; 6 | 7 | /** 8 | * 群提示消息节点 9 | */ 10 | public class GroupTipsMessageNode extends AbstractMessageNode { 11 | @Override 12 | public String getNote(V2TIMGroupTipsElem elem) { 13 | return "[群提示]"; 14 | } 15 | 16 | @Override 17 | public GroupTipsMessageEntity analysis(V2TIMGroupTipsElem elem) { 18 | return new GroupTipsMessageEntity(elem); 19 | } 20 | 21 | @Override 22 | public Class getEntityClass() { 23 | return GroupTipsMessageEntity.class; 24 | } 25 | } -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/ImageMessageNode.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message; 2 | 3 | import com.tencent.imsdk.v2.V2TIMImageElem; 4 | import com.tencent.imsdk.v2.V2TIMManager; 5 | import com.tencent.imsdk.v2.V2TIMMessage; 6 | 7 | import top.huic.tencent_im_plugin.message.entity.ImageMessageEntity; 8 | 9 | /** 10 | * 图片消息节点 11 | */ 12 | public class ImageMessageNode extends AbstractMessageNode { 13 | @Override 14 | public V2TIMMessage getV2TIMMessage(ImageMessageEntity entity) { 15 | return V2TIMManager.getMessageManager().createImageMessage(entity.getPath()); 16 | } 17 | 18 | @Override 19 | public String getNote(V2TIMImageElem elem) { 20 | return "[图片]"; 21 | } 22 | 23 | @Override 24 | public ImageMessageEntity analysis(V2TIMImageElem elem) { 25 | ImageMessageEntity entity = new ImageMessageEntity(); 26 | entity.setPath(elem.getPath()); 27 | entity.setImageData(elem.getImageList()); 28 | return entity; 29 | } 30 | 31 | @Override 32 | public Class getEntityClass() { 33 | return ImageMessageEntity.class; 34 | } 35 | } -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/LocationMessageNode.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message; 2 | 3 | import com.tencent.imsdk.v2.V2TIMLocationElem; 4 | import com.tencent.imsdk.v2.V2TIMManager; 5 | import com.tencent.imsdk.v2.V2TIMMessage; 6 | 7 | import top.huic.tencent_im_plugin.message.entity.LocationMessageEntity; 8 | 9 | /** 10 | * 位置消息节点 11 | */ 12 | public class LocationMessageNode extends AbstractMessageNode { 13 | @Override 14 | public V2TIMMessage getV2TIMMessage(LocationMessageEntity entity) { 15 | return V2TIMManager.getMessageManager().createLocationMessage(entity.getDesc(), entity.getLongitude(), entity.getLatitude()); 16 | } 17 | 18 | @Override 19 | public String getNote(V2TIMLocationElem elem) { 20 | return "[位置消息]"; 21 | } 22 | 23 | @Override 24 | public LocationMessageEntity analysis(V2TIMLocationElem elem) { 25 | return new LocationMessageEntity(elem); 26 | } 27 | 28 | @Override 29 | public Class getEntityClass() { 30 | return LocationMessageEntity.class; 31 | } 32 | } -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/SoundMessageNode.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message; 2 | 3 | import com.tencent.imsdk.v2.V2TIMManager; 4 | import com.tencent.imsdk.v2.V2TIMMessage; 5 | import com.tencent.imsdk.v2.V2TIMSoundElem; 6 | 7 | import top.huic.tencent_im_plugin.message.entity.SoundMessageEntity; 8 | 9 | /** 10 | * 语音消息节点 11 | */ 12 | public class SoundMessageNode extends AbstractMessageNode { 13 | 14 | @Override 15 | public V2TIMMessage getV2TIMMessage(SoundMessageEntity entity) { 16 | return V2TIMManager.getMessageManager().createSoundMessage(entity.getPath(), entity.getDuration()); 17 | } 18 | 19 | @Override 20 | public String getNote(V2TIMSoundElem elem) { 21 | return "[语音]"; 22 | } 23 | 24 | @Override 25 | public SoundMessageEntity analysis(V2TIMSoundElem elem) { 26 | return new SoundMessageEntity(elem); 27 | } 28 | 29 | @Override 30 | public Class getEntityClass() { 31 | return SoundMessageEntity.class; 32 | } 33 | } -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/TextMessageNode.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message; 2 | 3 | import com.tencent.imsdk.v2.V2TIMGroupAtInfo; 4 | import com.tencent.imsdk.v2.V2TIMManager; 5 | import com.tencent.imsdk.v2.V2TIMMessage; 6 | import com.tencent.imsdk.v2.V2TIMTextElem; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import top.huic.tencent_im_plugin.message.entity.TextMessageEntity; 11 | 12 | /** 13 | * 文本消息节点 14 | */ 15 | public class TextMessageNode extends AbstractMessageNode { 16 | @Override 17 | public V2TIMMessage getV2TIMMessage(TextMessageEntity entity) { 18 | 19 | // 有@用户或者@所有人则进入分支 20 | if ((entity.getAtUserList() != null && entity.getAtUserList().size() >= 1) || (entity.getAtAll() != null && entity.getAtAll())) { 21 | List atList = new ArrayList<>(); 22 | // @所有人 23 | if (entity.getAtAll() != null && entity.getAtAll()) { 24 | atList.add(V2TIMGroupAtInfo.AT_ALL_TAG); 25 | } 26 | 27 | // @目标用户 28 | if (entity.getAtUserList() != null) { 29 | atList.addAll(entity.getAtUserList()); 30 | } 31 | return V2TIMManager.getMessageManager().createTextAtMessage(entity.getContent(), atList); 32 | } 33 | return V2TIMManager.getMessageManager().createTextMessage(entity.getContent()); 34 | } 35 | 36 | @Override 37 | public String getNote(V2TIMTextElem elem) { 38 | return elem.getText(); 39 | } 40 | 41 | @Override 42 | public TextMessageEntity analysis(V2TIMTextElem elem) { 43 | return new TextMessageEntity(elem); 44 | } 45 | 46 | @Override 47 | public Class getEntityClass() { 48 | return TextMessageEntity.class; 49 | } 50 | } -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/VideoMessageNode.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message; 2 | 3 | import com.tencent.imsdk.v2.V2TIMManager; 4 | import com.tencent.imsdk.v2.V2TIMMessage; 5 | import com.tencent.imsdk.v2.V2TIMVideoElem; 6 | 7 | import top.huic.tencent_im_plugin.message.entity.VideoMessageEntity; 8 | 9 | /** 10 | * 视频消息节点 11 | */ 12 | public class VideoMessageNode extends AbstractMessageNode { 13 | @Override 14 | public V2TIMMessage getV2TIMMessage(VideoMessageEntity entity) { 15 | String suffix = null; 16 | if (entity.getVideoPath().contains(".")) { 17 | String[] ss = entity.getVideoPath().split("\\."); 18 | suffix = ss[ss.length - 1]; 19 | } 20 | return V2TIMManager.getMessageManager().createVideoMessage(entity.getVideoPath(), suffix, entity.getDuration(), entity.getSnapshotPath()); 21 | } 22 | 23 | @Override 24 | public String getNote(V2TIMVideoElem elem) { 25 | return "[视频]"; 26 | } 27 | 28 | @Override 29 | public VideoMessageEntity analysis(V2TIMVideoElem elem) { 30 | return new VideoMessageEntity(elem); 31 | } 32 | 33 | @Override 34 | public Class getEntityClass() { 35 | return VideoMessageEntity.class; 36 | } 37 | } -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/entity/AbstractMessageEntity.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message.entity; 2 | 3 | import java.io.Serializable; 4 | 5 | import top.huic.tencent_im_plugin.enums.MessageNodeType; 6 | 7 | /** 8 | * 消息实体 9 | * 10 | * @author 蒋具宏 11 | */ 12 | public class AbstractMessageEntity implements Serializable { 13 | private MessageNodeType nodeType; 14 | 15 | public AbstractMessageEntity(MessageNodeType nodeType) { 16 | this.nodeType = nodeType; 17 | } 18 | 19 | public MessageNodeType getNodeType() { 20 | return nodeType; 21 | } 22 | 23 | public void setNodeType(MessageNodeType nodeType) { 24 | this.nodeType = nodeType; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/entity/CustomMessageEntity.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message.entity; 2 | 3 | import com.tencent.imsdk.v2.V2TIMCustomElem; 4 | 5 | import top.huic.tencent_im_plugin.enums.MessageNodeType; 6 | 7 | /** 8 | * 自定义消息实体 9 | * 10 | * @author 蒋具宏 11 | */ 12 | public class CustomMessageEntity extends AbstractMessageEntity { 13 | /** 14 | * 自定义内容 15 | */ 16 | private String data; 17 | 18 | /** 19 | * 描述 20 | */ 21 | private String desc; 22 | 23 | /** 24 | * 扩展内容 25 | */ 26 | private String ext; 27 | 28 | public CustomMessageEntity() { 29 | super(MessageNodeType.Custom); 30 | } 31 | 32 | public CustomMessageEntity(V2TIMCustomElem elem) { 33 | super(MessageNodeType.Custom); 34 | if (elem.getData() == null || elem.getData().length == 0) { 35 | this.data = null; 36 | } else { 37 | this.data = new String(elem.getData()); 38 | } 39 | this.desc = elem.getDescription(); 40 | if (elem.getExtension() != null && elem.getExtension().length != 0) { 41 | this.ext = new String(elem.getExtension()); 42 | } 43 | } 44 | 45 | public String getData() { 46 | return data; 47 | } 48 | 49 | public void setData(String data) { 50 | this.data = data; 51 | } 52 | 53 | public String getDesc() { 54 | return desc; 55 | } 56 | 57 | public void setDesc(String desc) { 58 | this.desc = desc; 59 | } 60 | 61 | public String getExt() { 62 | return ext; 63 | } 64 | 65 | public void setExt(String ext) { 66 | this.ext = ext; 67 | } 68 | } -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/entity/FaceMessageEntity.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message.entity; 2 | 3 | import com.tencent.imsdk.v2.V2TIMFaceElem; 4 | 5 | import top.huic.tencent_im_plugin.enums.MessageNodeType; 6 | 7 | /** 8 | * 表情消息实体 9 | */ 10 | public class FaceMessageEntity extends AbstractMessageEntity { 11 | 12 | /** 13 | * 索引 14 | */ 15 | private int index; 16 | 17 | /** 18 | * 数据 19 | */ 20 | private String data; 21 | 22 | 23 | public FaceMessageEntity() { 24 | super(MessageNodeType.Face); 25 | } 26 | 27 | public FaceMessageEntity(V2TIMFaceElem elem) { 28 | super(MessageNodeType.Face); 29 | this.setIndex(elem.getIndex()); 30 | this.setData(elem.getData() == null ? null : new String(elem.getData())); 31 | } 32 | 33 | public int getIndex() { 34 | return index; 35 | } 36 | 37 | public void setIndex(int index) { 38 | this.index = index; 39 | } 40 | 41 | public String getData() { 42 | return data; 43 | } 44 | 45 | public void setData(String data) { 46 | this.data = data; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/entity/FileMessageEntity.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message.entity; 2 | 3 | import com.tencent.imsdk.v2.V2TIMFileElem; 4 | 5 | import top.huic.tencent_im_plugin.enums.MessageNodeType; 6 | 7 | /** 8 | * 文件消息实体 9 | */ 10 | public class FileMessageEntity extends AbstractMessageEntity { 11 | /** 12 | * 文件路径 13 | */ 14 | private String filePath; 15 | 16 | /** 17 | * 文件名 18 | */ 19 | private String fileName; 20 | 21 | /** 22 | * 文件UUID 23 | */ 24 | private String uuid; 25 | 26 | /** 27 | * 文件大小 28 | */ 29 | private int size; 30 | 31 | public FileMessageEntity() { 32 | super(MessageNodeType.File); 33 | } 34 | 35 | public FileMessageEntity(V2TIMFileElem elem) { 36 | super(MessageNodeType.File); 37 | this.setFileName(elem.getFileName()); 38 | this.setFilePath(elem.getPath()); 39 | this.setSize(elem.getFileSize()); 40 | this.setUuid(elem.getUUID()); 41 | } 42 | 43 | public String getFilePath() { 44 | return filePath; 45 | } 46 | 47 | public void setFilePath(String filePath) { 48 | this.filePath = filePath; 49 | } 50 | 51 | public String getFileName() { 52 | return fileName; 53 | } 54 | 55 | public void setFileName(String fileName) { 56 | this.fileName = fileName; 57 | } 58 | 59 | public String getUuid() { 60 | return uuid; 61 | } 62 | 63 | public void setUuid(String uuid) { 64 | this.uuid = uuid; 65 | } 66 | 67 | public int getSize() { 68 | return size; 69 | } 70 | 71 | public void setSize(int size) { 72 | this.size = size; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/entity/ImageMessageEntity.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message.entity; 2 | 3 | import com.tencent.imsdk.v2.V2TIMImageElem; 4 | 5 | import java.util.List; 6 | 7 | import top.huic.tencent_im_plugin.enums.MessageNodeType; 8 | 9 | /** 10 | * 图片消息实体 11 | * 12 | * @author 蒋具宏 13 | */ 14 | public class ImageMessageEntity extends AbstractMessageEntity { 15 | /** 16 | * 原图本地文件路径,发送方有效 17 | */ 18 | private String path; 19 | 20 | /** 21 | * 图片列表,根据类型分开 22 | */ 23 | private List imageData; 24 | 25 | public ImageMessageEntity() { 26 | super(MessageNodeType.Image); 27 | } 28 | 29 | public ImageMessageEntity(V2TIMImageElem elem) { 30 | super(MessageNodeType.Image); 31 | this.setPath(elem.getPath()); 32 | this.setImageData(elem.getImageList()); 33 | } 34 | 35 | public String getPath() { 36 | return path; 37 | } 38 | 39 | public void setPath(String path) { 40 | this.path = path; 41 | } 42 | 43 | public List getImageData() { 44 | return imageData; 45 | } 46 | 47 | public void setImageData(List imageData) { 48 | this.imageData = imageData; 49 | } 50 | } -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/entity/LocationMessageEntity.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message.entity; 2 | 3 | import com.tencent.imsdk.v2.V2TIMLocationElem; 4 | 5 | import top.huic.tencent_im_plugin.enums.MessageNodeType; 6 | 7 | /** 8 | * 位置消息实体 9 | * 10 | * @author 蒋具宏 11 | */ 12 | public class LocationMessageEntity extends AbstractMessageEntity { 13 | /** 14 | * 描述 15 | */ 16 | private String desc; 17 | 18 | /** 19 | * 经度 20 | */ 21 | private double latitude; 22 | 23 | /** 24 | * 纬度 25 | */ 26 | private double longitude; 27 | 28 | public LocationMessageEntity() { 29 | super(MessageNodeType.Location); 30 | } 31 | 32 | public LocationMessageEntity(V2TIMLocationElem elem) { 33 | super(MessageNodeType.Location); 34 | this.setDesc(elem.getDesc()); 35 | this.setLongitude(elem.getLongitude()); 36 | this.setLatitude(elem.getLatitude()); 37 | } 38 | 39 | public String getDesc() { 40 | return desc; 41 | } 42 | 43 | public void setDesc(String desc) { 44 | this.desc = desc; 45 | } 46 | 47 | public double getLatitude() { 48 | return latitude; 49 | } 50 | 51 | public void setLatitude(double latitude) { 52 | this.latitude = latitude; 53 | } 54 | 55 | public double getLongitude() { 56 | return longitude; 57 | } 58 | 59 | public void setLongitude(double longitude) { 60 | this.longitude = longitude; 61 | } 62 | } -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/entity/SoundMessageEntity.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message.entity; 2 | 3 | import com.tencent.imsdk.v2.V2TIMSoundElem; 4 | 5 | import top.huic.tencent_im_plugin.enums.MessageNodeType; 6 | 7 | /** 8 | * 语音消息实体 9 | * 10 | * @author 蒋具宏 11 | */ 12 | public class SoundMessageEntity extends AbstractMessageEntity { 13 | 14 | /** 15 | * 语音ID 16 | */ 17 | private String uuid; 18 | 19 | /** 20 | * 路径 21 | */ 22 | private String path; 23 | 24 | /** 25 | * 时长 26 | */ 27 | private Integer duration; 28 | 29 | /** 30 | * 数据大小 31 | */ 32 | private Integer dataSize; 33 | 34 | public SoundMessageEntity() { 35 | super(MessageNodeType.Sound); 36 | } 37 | 38 | public SoundMessageEntity(V2TIMSoundElem elem) { 39 | super(MessageNodeType.Sound); 40 | this.setPath(elem.getPath()); 41 | this.setDuration(elem.getDuration()); 42 | this.setDataSize(elem.getDataSize()); 43 | this.setUuid(elem.getUUID()); 44 | } 45 | 46 | public String getPath() { 47 | return path; 48 | } 49 | 50 | public void setPath(String path) { 51 | this.path = path; 52 | } 53 | 54 | public Integer getDuration() { 55 | return duration; 56 | } 57 | 58 | public void setDuration(Integer duration) { 59 | this.duration = duration; 60 | } 61 | 62 | public Integer getDataSize() { 63 | return dataSize; 64 | } 65 | 66 | public void setDataSize(Integer dataSize) { 67 | this.dataSize = dataSize; 68 | } 69 | 70 | public String getUuid() { 71 | return uuid; 72 | } 73 | 74 | public void setUuid(String uuid) { 75 | this.uuid = uuid; 76 | } 77 | } -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/message/entity/TextMessageEntity.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.message.entity; 2 | 3 | import com.tencent.imsdk.v2.V2TIMTextElem; 4 | 5 | import java.util.List; 6 | 7 | import top.huic.tencent_im_plugin.enums.MessageNodeType; 8 | 9 | /** 10 | * 文本消息实体 11 | * 12 | * @author 蒋具宏 13 | */ 14 | public class TextMessageEntity extends AbstractMessageEntity { 15 | /** 16 | * 消息内容 17 | */ 18 | private String content; 19 | 20 | /** 21 | * \@的用户列表 22 | */ 23 | private List atUserList; 24 | 25 | /** 26 | * 是否@所有人 27 | */ 28 | private Boolean atAll; 29 | 30 | public TextMessageEntity() { 31 | super(MessageNodeType.Text); 32 | } 33 | 34 | public TextMessageEntity(V2TIMTextElem elem) { 35 | super(MessageNodeType.Text); 36 | this.content = elem.getText(); 37 | } 38 | 39 | public String getContent() { 40 | return content; 41 | } 42 | 43 | public void setContent(String content) { 44 | this.content = content; 45 | } 46 | 47 | public List getAtUserList() { 48 | return atUserList; 49 | } 50 | 51 | public void setAtUserList(List atUserList) { 52 | this.atUserList = atUserList; 53 | } 54 | 55 | public Boolean getAtAll() { 56 | return atAll; 57 | } 58 | 59 | public void setAtAll(Boolean atAll) { 60 | this.atAll = atAll; 61 | } 62 | } -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/util/CommonUtil.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.util; 2 | 3 | import android.os.Handler; 4 | import android.os.Looper; 5 | 6 | import io.flutter.plugin.common.MethodCall; 7 | import io.flutter.plugin.common.MethodChannel; 8 | 9 | /** 10 | * 工具类 11 | */ 12 | public class CommonUtil { 13 | /** 14 | * 主线程处理器 15 | */ 16 | private final static Handler MAIN_HANDLER = new Handler(Looper.getMainLooper()); 17 | 18 | /** 19 | * 通用方法,获得参数值,如未找到参数,则直接中断 20 | * 21 | * @param methodCall 方法调用对象 22 | * @param result 返回对象 23 | * @param param 参数名 24 | */ 25 | public static T getParam(MethodCall methodCall, MethodChannel.Result result, String param) { 26 | T par = methodCall.argument(param); 27 | if (par == null) { 28 | result.error("Missing parameter", "Cannot find parameter `" + param + "` or `" + param + "` is null!", 5); 29 | throw new RuntimeException("Cannot find parameter `" + param + "` or `" + param + "` is null!"); 30 | } 31 | return par; 32 | } 33 | 34 | /** 35 | * 运行主线程返回结果执行 36 | * 37 | * @param result 返回结果对象 38 | * @param param 返回参数 39 | */ 40 | public static void runMainThreadReturn(final MethodChannel.Result result, final Object param) { 41 | MAIN_HANDLER.post(new Runnable() { 42 | @Override 43 | public void run() { 44 | result.success(param); 45 | } 46 | }); 47 | } 48 | 49 | /** 50 | * 运行主线程返回错误结果执行 51 | * 52 | * @param result 返回结果对象 53 | * @param errorCode 错误码 54 | * @param errorMessage 错误信息 55 | * @param errorDetails 错误内容 56 | */ 57 | public static void runMainThreadReturnError(final MethodChannel.Result result, final String errorCode, final String errorMessage, final Object errorDetails) { 58 | MAIN_HANDLER.post(new Runnable() { 59 | @Override 60 | public void run() { 61 | result.error(errorCode, errorMessage, errorDetails); 62 | } 63 | }); 64 | } 65 | 66 | /** 67 | * 运行主线程方法 68 | */ 69 | public static void runMainThreadMethod(Runnable runnable){ 70 | MAIN_HANDLER.post(runnable); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /android/src/main/java/top/huic/tencent_im_plugin/util/JsonUtil.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin.util; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.serializer.ValueFilter; 5 | 6 | /** 7 | * JSON工具类 8 | * 9 | * @author 蒋具宏 10 | */ 11 | public class JsonUtil { 12 | /** 13 | * 自定义数据过滤器 14 | */ 15 | private static final ValueFilter filter = new ValueFilter() { 16 | @Override 17 | public Object process(Object object, String name, Object value) { 18 | if (value instanceof byte[]) { 19 | return new String((byte[]) value); 20 | } 21 | return value; 22 | } 23 | }; 24 | 25 | /** 26 | * 将对象序列化为JSON 27 | * 28 | * @param data 对象 29 | * @return 解析结果 30 | */ 31 | public static String toJSONString(Object data) { 32 | if (data instanceof String) return data.toString(); 33 | return JSON.toJSONString(data, filter); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | /build/ 32 | 33 | # Web related 34 | lib/generated_plugin_registrant.dart 35 | 36 | # Exceptions to above rules. 37 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 38 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: d345a3b303ce041846ff895eb49a104bef133c4b 8 | channel: master 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # tencent_im_plugin_example 2 | 3 | Demonstrates how to use the tencent_im_plugin plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | -------------------------------------------------------------------------------- /example/android/app/agconnect-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "agcgw":{ 3 | "backurl":"connect-drcn.dbankcloud.cn", 4 | "url":"connect-drcn.hispace.hicloud.com" 5 | }, 6 | "client":{ 7 | "cp_id":"890086000102176873", 8 | "product_id":"736430079244549109", 9 | "client_id":"400572237515588608", 10 | "client_secret":"76A8613ED5A461B6AA74396CAF70DBB0B23690F8B4136A0A66AA202FFEEA890D", 11 | "app_id":"102514829", 12 | "package_name":"top.huic.tencent_im_plugin_example", 13 | "api_key":"CgB6e3x9I8KuPeIag8AT0fhvvrEf57HaQCYqoB91348bgNFNEim2y+8s3/ervtmQDygm6EKiBqCBRdNurhYotfYi" 14 | }, 15 | "service":{ 16 | "analytics":{ 17 | "collector_url":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn", 18 | "resource_id":"p1", 19 | "channel_id":"" 20 | }, 21 | "cloudstorage":{ 22 | "storage_url":"https://agc-storage-drcn.platform.dbankcloud.cn" 23 | }, 24 | "ml":{ 25 | "mlservice_url":"ml-api-drcn.ai.dbankcloud.com,ml-api-drcn.ai.dbankcloud.cn" 26 | } 27 | }, 28 | "region":"CN", 29 | "configuration_version":"1.0" 30 | } -------------------------------------------------------------------------------- /example/android/app/key.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/android/app/key.jks -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/top/huic/tencent_im_plugin_example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package top.huic.tencent_im_plugin_example; 2 | 3 | import android.app.ActivityManager; 4 | import android.content.Context; 5 | import android.os.Bundle; 6 | import java.util.List; 7 | 8 | import androidx.annotation.NonNull; 9 | import androidx.annotation.Nullable; 10 | import io.flutter.embedding.android.FlutterActivity; 11 | import io.flutter.embedding.engine.FlutterEngine; 12 | import io.flutter.plugin.common.MethodChannel; 13 | import io.flutter.plugins.GeneratedPluginRegistrant; 14 | 15 | public class MainActivity extends FlutterActivity { 16 | 17 | /** 18 | * Flutter 通知器 19 | */ 20 | public static MethodChannel channel; 21 | 22 | @Override 23 | protected void onCreate(@Nullable Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | channel = new MethodChannel(this.getFlutterEngine().getDartExecutor(), "tencent_im_plugin_example"); 26 | } 27 | 28 | @Override 29 | public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { 30 | GeneratedPluginRegistrant.registerWith(flutterEngine); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | maven {url 'https://developer.huawei.com/repo/'} 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.6.3' 10 | classpath 'com.huawei.agconnect:agcp:1.2.1.301' 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Feb 28 14:11:06 CST 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 9.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:tencent_im_plugin_example/page/chat.dart'; 3 | import 'package:tencent_im_plugin_example/page/home.dart'; 4 | import 'package:tencent_im_plugin_example/page/interfaces_test.dart'; 5 | import 'package:tencent_im_plugin_example/page/login.dart'; 6 | import 'package:tencent_im_plugin_example/page/main/main.dart'; 7 | 8 | void main() => runApp(MyApp()); 9 | 10 | class MyApp extends StatefulWidget { 11 | @override 12 | _MyAppState createState() => _MyAppState(); 13 | } 14 | 15 | class _MyAppState extends State { 16 | @override 17 | Widget build(BuildContext context) { 18 | return MaterialApp( 19 | debugShowCheckedModeBanner: false, 20 | routes: { 21 | "/": (context) => HomePage(), 22 | "/interfaces_test": (context) => InterfacesTest(), 23 | "/login": (context) => Login(), 24 | "/main": (context) => Main(), 25 | "/chat": (context) => Chat(), 26 | }, 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /example/lib/page/home.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/widgets.dart'; 4 | import 'package:tencent_im_plugin/tencent_im_plugin.dart'; 5 | 6 | class HomePage extends StatefulWidget { 7 | @override 8 | _HomePageState createState() => _HomePageState(); 9 | } 10 | 11 | class _HomePageState extends State { 12 | @override 13 | void initState() { 14 | super.initState(); 15 | TencentImPlugin.initSDK(appid: '1400294314'); 16 | } 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return Scaffold( 21 | appBar: AppBar(title: Text("页面导航")), 22 | body: Center( 23 | child: Column( 24 | mainAxisAlignment: MainAxisAlignment.center, 25 | children: [ 26 | OutlinedButton( 27 | onPressed: () => Navigator.pushNamed(context, "/interfaces_test"), 28 | child: Text("接口测试"), 29 | ), 30 | OutlinedButton( 31 | onPressed: () => Navigator.pushNamed(context, "/login"), 32 | child: Text("进入Demo"), 33 | ), 34 | ], 35 | ), 36 | ), 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /example/lib/page/login.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:tencent_im_plugin/tencent_im_plugin.dart'; 4 | import 'package:tencent_im_plugin_example/utils/GenerateTestUserSig.dart'; 5 | 6 | /// 登录页面 7 | class Login extends StatefulWidget { 8 | @override 9 | _LoginState createState() => _LoginState(); 10 | } 11 | 12 | class _LoginState extends State { 13 | TextEditingController _controller = TextEditingController(); 14 | 15 | /// 用户名 16 | String _userName = "dev"; 17 | 18 | @override 19 | void initState() { 20 | super.initState(); 21 | _controller.text = _userName; 22 | } 23 | 24 | /// 登录按钮点击事件 25 | _onLogin() async { 26 | String sign = GenerateTestUserSig( 27 | sdkappid: 1400294314, 28 | key: "706da51f9280812611bcc80b5182b1c5554db8d053bc00b8a37ae8cba887f6a7", 29 | ).genSig(identifier: _userName, expire: 1 * 60 * 1000); 30 | 31 | await TencentImPlugin.login( 32 | userID: _userName, 33 | userSig: sign, 34 | ); 35 | 36 | Navigator.pushNamedAndRemoveUntil( 37 | context, "/main", (Route route) => false); 38 | } 39 | 40 | @override 41 | Widget build(BuildContext context) { 42 | return Scaffold( 43 | appBar: AppBar( 44 | title: Text("登录页面"), 45 | ), 46 | body: Padding( 47 | padding: const EdgeInsets.all(8.0), 48 | child: Center( 49 | child: Column( 50 | mainAxisAlignment: MainAxisAlignment.center, 51 | children: [ 52 | TextField( 53 | decoration: InputDecoration(hintText: "请输入用户名"), 54 | textAlign: TextAlign.center, 55 | onChanged: (value) => this.setState(() => _userName = value), 56 | controller: _controller, 57 | ), 58 | Container(height: 20), 59 | OutlinedButton( 60 | onPressed: _userName.trim() == '' ? null : _onLogin, 61 | child: Text("立即登录"), 62 | ), 63 | ], 64 | ), 65 | ), 66 | ), 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /example/lib/page/main/components/group.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/scheduler.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:tencent_im_plugin/tencent_im_plugin.dart'; 5 | import 'package:tencent_im_plugin/entity/group_info_entity.dart'; 6 | 7 | /// 群组列表 8 | class Group extends StatefulWidget { 9 | @override 10 | _GroupState createState() => _GroupState(); 11 | } 12 | 13 | class _GroupState extends State { 14 | /// 刷新指示器Key 15 | GlobalKey _refreshIndicatorKey = GlobalKey(); 16 | 17 | /// 数据结果对象 18 | List _data = []; 19 | 20 | @override 21 | void initState() { 22 | super.initState(); 23 | TencentImPlugin.addListener(_imListener); 24 | 25 | SchedulerBinding.instance.addPostFrameCallback((_) { 26 | _refreshIndicatorKey.currentState.show(); 27 | }); 28 | } 29 | 30 | @override 31 | void dispose() { 32 | super.dispose(); 33 | TencentImPlugin.removeListener(_imListener); 34 | } 35 | 36 | /// IM监听器 37 | _imListener(type, params) {} 38 | 39 | /// 刷新事件 40 | Future _onRefresh() { 41 | return TencentImPlugin.getJoinedGroupList() 42 | .then((value) => this.setState(() => _data = value)); 43 | } 44 | 45 | @override 46 | Widget build(BuildContext context) { 47 | return RefreshIndicator( 48 | key: _refreshIndicatorKey, 49 | onRefresh: _onRefresh, 50 | child: ListView( 51 | children: ListTile.divideTiles( 52 | context: context, 53 | tiles: _data 54 | .map( 55 | (item) => ListTile( 56 | leading: CircleAvatar( 57 | backgroundImage: 58 | item.faceUrl == null || item.faceUrl == '' 59 | ? null 60 | : NetworkImage(item.faceUrl)), 61 | title: RichText( 62 | text: TextSpan( 63 | children: [ 64 | TextSpan(text: "${item.groupName}"), 65 | ], 66 | style: TextStyle(color: Colors.black), 67 | ), 68 | ), 69 | subtitle: Text(item.introduction ?? ""), 70 | ), 71 | ) 72 | .toList(), 73 | ).toList(), 74 | ), 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /example/lib/utils/GenerateTestUserSig.dart: -------------------------------------------------------------------------------- 1 | library generate_test_im_usersig; 2 | 3 | import 'dart:convert'; 4 | import 'dart:io'; 5 | 6 | import 'package:crypto/crypto.dart'; 7 | import 'package:flutter/material.dart'; 8 | 9 | ///生成腾讯云即时通信测试用userSig 10 | /// 11 | class GenerateTestUserSig { 12 | GenerateTestUserSig({@required this.sdkappid, @required this.key}); 13 | int sdkappid; 14 | String key; 15 | 16 | ///生成UserSig 17 | String genSig({ 18 | @required String identifier, 19 | @required int expire, 20 | List userBuf, 21 | }) { 22 | int currTime = _getCurrentTime(); 23 | String sig = ''; 24 | Map sigDoc = new Map(); 25 | sigDoc.addAll({ 26 | "TLS.ver": "2.0", 27 | "TLS.identifier": identifier, 28 | "TLS.sdkappid": this.sdkappid, 29 | "TLS.expire": expire, 30 | "TLS.time": currTime, 31 | }); 32 | 33 | sig = _hmacsha256( 34 | identifier: identifier, 35 | currTime: currTime, 36 | expire: expire, 37 | ); 38 | sigDoc['TLS.sig'] = sig; 39 | String jsonStr = json.encode(sigDoc); 40 | List compress = zlib.encode(utf8.encode(jsonStr)); 41 | return _escape(content: base64.encode(compress)); 42 | } 43 | 44 | int _getCurrentTime() { 45 | return (new DateTime.now().millisecondsSinceEpoch / 1000).floor(); 46 | } 47 | 48 | String _hmacsha256({ 49 | @required String identifier, 50 | @required int currTime, 51 | @required int expire, 52 | }) { 53 | int sdkappid = this.sdkappid; 54 | String contentToBeSigned = 55 | "TLS.identifier:$identifier\nTLS.sdkappid:$sdkappid\nTLS.time:$currTime\nTLS.expire:$expire\n"; 56 | Hmac hmacSha256 = new Hmac(sha256, utf8.encode(this.key)); 57 | Digest hmacSha256Digest = 58 | hmacSha256.convert(utf8.encode(contentToBeSigned)); 59 | return base64.encode(hmacSha256Digest.bytes); 60 | } 61 | 62 | String _escape({ 63 | @required String content, 64 | }) { 65 | return content 66 | .replaceAll('\+', '*') 67 | .replaceAll('\/', '-') 68 | .replaceAll('=', '_'); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:tencent_im_plugin_example/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Verify Platform version', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that platform version is retrieved. 19 | expect( 20 | find.byWidgetPredicate( 21 | (Widget widget) => 22 | widget is Text && widget.data.startsWith('Running on:'), 23 | ), 24 | findsOneWidget, 25 | ); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JiangJuHong/FlutterTencentImPlugin/84a314326778a38de7203193b69577ee03d8b76a/ios/Assets/.gitkeep -------------------------------------------------------------------------------- /ios/Classes/TencentImPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface TencentImPlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /ios/Classes/TencentImPlugin.m: -------------------------------------------------------------------------------- 1 | #import "TencentImPlugin.h" 2 | #if __has_include() 3 | #import 4 | #else 5 | // Support project import fallback if the generated compatibility header 6 | // is not copied when this plugin is created as a library. 7 | // https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 8 | #import "tencent_im_plugin-Swift.h" 9 | #endif 10 | 11 | @implementation TencentImPlugin 12 | + (void)registerWithRegistrar:(NSObject*)registrar { 13 | [SwiftTencentImPlugin registerWithRegistrar:registrar]; 14 | } 15 | @end 16 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomConversationEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/29. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义会话实体 9 | class CustomConversationEntity: V2TIMConversation { 10 | 11 | 12 | /// 根据对象获得字典对象 13 | public static func getDict(info: V2TIMConversation) -> [String: Any] { 14 | var result: [String: Any] = [:]; 15 | result["conversationID"] = info.conversationID; 16 | result["type"] = info.type.rawValue; 17 | result["userID"] = info.userID; 18 | result["groupID"] = info.groupID; 19 | result["showName"] = info.showName; 20 | result["faceUrl"] = info.faceUrl; 21 | result["recvOpt"] = info.recvOpt.rawValue; 22 | result["groupType"] = info.groupType; 23 | result["unreadCount"] = info.unreadCount; 24 | result["lastMessage"] = info.lastMessage == nil ? nil : MessageEntity.init(message: info.lastMessage); 25 | result["draftText"] = info.draftText; 26 | result["draftText"] = info.draftText; 27 | result["draftTimestamp"] = info.draftTimestamp; 28 | result["pinned"] = info.isPinned; 29 | result["test"] = nil; 30 | if info.groupAtInfolist != nil { 31 | var groupAtInfoList: [[String: Any]] = []; 32 | for item in info.groupAtInfolist { 33 | groupAtInfoList.append(CustomGroupAtInfoEntity.getDict(info: item)); 34 | } 35 | result["groupAtInfoList"] = groupAtInfoList; 36 | } 37 | return result; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomConversationResultEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/29. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义会话结果实体 9 | class CustomConversationResultEntity: NSObject { 10 | /// 下一次分页拉取的游标 11 | var nextSeq: UInt64?; 12 | 13 | /// 是否拉取完毕 14 | var finished: Bool?; 15 | 16 | /// 会话列表 17 | var conversationList: [[String: Any]]?; 18 | 19 | required public override init() { 20 | } 21 | 22 | init(conversations: [V2TIMConversation], nextSeq: UInt64, finished: Bool) { 23 | super.init(); 24 | self.nextSeq = nextSeq; 25 | self.finished = finished; 26 | conversationList = []; 27 | for item in conversations { 28 | conversationList!.append(CustomConversationEntity.getDict(info: item)); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomCreateGroupMemberEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/29. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义群创建群成员实体 9 | class CustomCreateGroupMemberEntity: V2TIMCreateGroupMemberInfo { 10 | required public override init() { 11 | } 12 | 13 | convenience init(json: String) { 14 | self.init(dict: JsonUtil.getDictionaryFromJSONString(jsonString: json)) 15 | } 16 | 17 | init(dict: [String: Any]) { 18 | super.init(); 19 | self.userID = (dict["userID"] as? String); 20 | if dict["role"] != nil { 21 | self.role = (dict["role"] as! UInt32); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomFriendAddApplicationEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/11/3. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 好友申请实体 9 | class CustomFriendAddApplicationEntity: V2TIMFriendAddApplication { 10 | convenience init(json: String) { 11 | self.init(dict: JsonUtil.getDictionaryFromJSONString(jsonString: json)) 12 | } 13 | 14 | init(dict: [String: Any]) { 15 | super.init(); 16 | self.userID = (dict["userID"] as? String); 17 | self.friendRemark = (dict["friendRemark"] as? String); 18 | self.addWording = (dict["addWording"] as? String); 19 | self.addSource = (dict["addSource"] as? String); 20 | if dict["addType"] != nil { 21 | self.addType = V2TIMFriendType.init(rawValue: (dict["addType"] as! Int))! 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomFriendApplicationEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/11/3. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 好友申请实体 9 | class CustomFriendApplicationEntity: V2TIMFriendApplication { 10 | 11 | /// 根据对象获得字典对象 12 | public static func getDict(info: V2TIMFriendApplication) -> [String: Any] { 13 | var result: [String: Any] = [:]; 14 | result["userID"] = info.userID; 15 | result["nickname"] = info.nickName; 16 | result["faceUrl"] = info.faceUrl; 17 | result["addTime"] = info.addTime; 18 | result["addSource"] = info.addSource; 19 | result["addWording"] = info.addWording; 20 | result["type"] = info.type.rawValue; 21 | return result; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomFriendApplicationResultEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/11/3. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 好友申请结果实体 9 | class CustomFriendApplicationResultEntity: V2TIMFriendApplicationResult { 10 | 11 | /// 根据对象获得字典对象 12 | public static func getDict(info: V2TIMFriendApplicationResult) -> [String: Any] { 13 | var result: [String: Any] = [:]; 14 | result["unreadCount"] = info.unreadCount; 15 | 16 | var friendApplicationList: [[String: Any]] = []; 17 | for item in info.applicationList { 18 | friendApplicationList.append(CustomFriendApplicationEntity.getDict(info: item as! V2TIMFriendApplication)) 19 | } 20 | result["friendApplicationList"] = friendApplicationList; 21 | return result; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomFriendCheckResultEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/11/3. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义好友检查结果实体 9 | class CustomFriendCheckResultEntity : V2TIMFriendCheckResult{ 10 | 11 | /// 根据对象获得字典对象 12 | public static func getDict(info: V2TIMFriendCheckResult) -> [String: Any] { 13 | var result: [String: Any] = [:]; 14 | result["userID"] = info.userID; 15 | result["resultCode"] = info.resultCode; 16 | result["resultInfo"] = info.resultInfo; 17 | result["resultType"] = info.relationType.rawValue; 18 | return result; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomFriendGroupEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/11/3. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义好友分组实体 9 | class CustomFriendGroupEntity: V2TIMFriendGroup { 10 | 11 | /// 根据对象获得字典对象 12 | public static func getDict(info: V2TIMFriendGroup) -> [String: Any] { 13 | var result: [String: Any] = [:]; 14 | result["name"] = info.groupName; 15 | result["friendCount"] = info.userCount; 16 | result["friendIDList"] = info.friendList; 17 | return result; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomFriendInfoEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/29. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义好友信息实体 9 | class CustomFriendInfoEntity: V2TIMFriendInfo { 10 | 11 | convenience init(json: String) { 12 | self.init(dict: JsonUtil.getDictionaryFromJSONString(jsonString: json)) 13 | } 14 | 15 | init(dict: [String: Any]) { 16 | super.init(); 17 | self.userID = (dict["userID"] as? String); 18 | self.friendRemark = (dict["friendRemark"] as? String); 19 | if dict["friendCustomInfo"] != nil { 20 | self.friendCustomInfo = [:]; 21 | for (k, v) in (dict["friendCustomInfo"] as! [String: String]) { 22 | self.friendCustomInfo[k] = v.data(using: .utf8) 23 | } 24 | } 25 | } 26 | 27 | /// 根据对象获得字典对象 28 | public static func getDict(info: V2TIMFriendInfo) -> [String: Any] { 29 | var result: [String: Any] = [:]; 30 | result["userID"] = info.userID; 31 | result["friendRemark"] = info.friendRemark; 32 | result["friendGroups"] = info.friendGroups; 33 | result["friendCustomInfo"] = info.friendCustomInfo; 34 | result["userProfile"] = CustomUserEntity.getDict(info: info.userFullInfo); 35 | return result; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomFriendInfoResultEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/11/3. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | class CustomFriendInfoResultEntity: V2TIMFriendInfoResult { 9 | 10 | /// 根据对象获得字典对象 11 | public static func getDict(info: V2TIMFriendInfoResult) -> [String: Any] { 12 | var result: [String: Any] = [:]; 13 | result["resultCode"] = info.resultCode; 14 | result["resultInfo"] = info.resultInfo; 15 | result["relation"] = info.relation.rawValue; 16 | result["friendInfo"] = CustomFriendInfoEntity.getDict(info: info.friendInfo); 17 | return result; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomFriendOperationResultEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/29. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 好友操作结果实体 9 | class CustomFriendOperationResultEntity: V2TIMFriendOperationResult { 10 | 11 | /// 根据对象获得字典对象 12 | public static func getDict(info: V2TIMFriendOperationResult) -> [String: Any] { 13 | var result: [String: Any] = [:]; 14 | result["userID"] = info.userID; 15 | result["resultCode"] = info.resultCode; 16 | result["resultInfo"] = info.resultInfo; 17 | return result; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomGroupApplicationEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/29. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义群申请实体 9 | class CustomGroupApplicationEntity: V2TIMGroupApplication { 10 | 11 | /// 根据对象获得字典对象 12 | public static func getDict(info: V2TIMGroupApplication) -> [String: Any] { 13 | var result: [String: Any] = [:]; 14 | result["groupID"] = info.groupID; 15 | result["fromUser"] = info.fromUser; 16 | result["fromUserNickName"] = info.fromUserNickName; 17 | result["fromUserFaceUrl"] = info.fromUserFaceUrl; 18 | result["toUser"] = info.toUser; 19 | result["addTime"] = info.addTime; 20 | result["requestMsg"] = info.requestMsg; 21 | result["handledMsg"] = info.handledMsg; 22 | result["type"] = info.getType.rawValue; 23 | result["handleStatus"] = info.handleStatus.rawValue; 24 | result["handleResult"] = info.handleResult.rawValue; 25 | return result; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomGroupApplicationResultEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/29. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 群申请结果实体 9 | class CustomGroupApplicationResultEntity: V2TIMGroupApplicationResult { 10 | 11 | /// 根据对象获得字典对象 12 | public static func getDict(info: V2TIMGroupApplicationResult) -> [String: Any] { 13 | var result: [String: Any] = [:]; 14 | result["unreadCount"] = info.unreadCount; 15 | var groupApplicationList: [[String: Any]] = []; 16 | for item in info.applicationList! { 17 | groupApplicationList.append(CustomGroupApplicationEntity.getDict(info: item as! V2TIMGroupApplication)) 18 | } 19 | result["groupApplicationList"] = groupApplicationList; 20 | return result; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomGroupAtInfoEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/29. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义群@信息实体 9 | class CustomGroupAtInfoEntity: V2TIMGroupAtInfo { 10 | 11 | /// 根据对象获得字典对象 12 | public static func getDict(info: V2TIMGroupAtInfo) -> [String: Any] { 13 | var result: [String: Any] = [:]; 14 | result["seq"] = info.seq; 15 | result["atType"] = info.atType.rawValue; 16 | return result; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomGroupChangeInfoEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/11/4. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义群改变信息 9 | class CustomGroupChangeInfoEntity: V2TIMGroupChangeInfo { 10 | 11 | /// 根据对象获得字典对象 12 | public static func getDict(info: V2TIMGroupChangeInfo) -> [String: Any] { 13 | var result: [String: Any] = [:]; 14 | result["type"] = info.type.rawValue; 15 | result["key"] = info.key; 16 | result["value"] = info.value; 17 | return result; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomGroupInfoResultEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/29. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义群信息结果实体 9 | class CustomGroupInfoResultEntity: V2TIMGroupInfoResult { 10 | required public override init() { 11 | } 12 | 13 | /// 根据对象获得字典对象 14 | public static func getDict(info: V2TIMGroupInfoResult) -> [String: Any] { 15 | var result: [String: Any] = [:]; 16 | result["resultCode"] = info.resultCode; 17 | result["resultMessage"] = info.resultMsg; 18 | result["groupInfo"] = CustomGroupInfoEntity.getDict(info: info.info); 19 | return result; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomGroupMemberChangeInfoEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/11/4. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义群信息实体 9 | class CustomGroupMemberChangeInfoEntity: V2TIMGroupMemberChangeInfo { 10 | 11 | /// 根据对象获得字典对象 12 | public static func getDict(info: V2TIMGroupMemberChangeInfo) -> [String: Any] { 13 | var result: [String: Any] = [:]; 14 | result["userID"] = info.userID; 15 | result["muteTime"] = info.muteTime; 16 | return result; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomGroupMemberFullInfoEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/29. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义群成员信息实体 9 | class CustomGroupMemberFullInfoEntity: V2TIMGroupMemberFullInfo { 10 | 11 | convenience init(json: String) { 12 | self.init(dict: JsonUtil.getDictionaryFromJSONString(jsonString: json)) 13 | } 14 | 15 | init(dict: [String: Any]) { 16 | super.init(); 17 | self.userID = (dict["userID"] as? String); 18 | 19 | if dict["customInfo"] != nil { 20 | self.customInfo = [:]; 21 | for (k, v) in (dict["customInfo"] as! [String: String]) { 22 | self.customInfo[k] = v.data(using: .utf8) 23 | } 24 | } 25 | 26 | self.nameCard = (dict["nameCard"] as? String); 27 | } 28 | 29 | /// 根据对象获得字典对象 30 | public static func getDict(info: V2TIMGroupMemberFullInfo) -> [String: Any] { 31 | var result: [String: Any] = [:]; 32 | result["userID"] = info.userID; 33 | result["nickName"] = info.nickName; 34 | result["friendRemark"] = info.friendRemark; 35 | result["faceUrl"] = info.faceURL; 36 | result["role"] = info.role; 37 | result["muteUntil"] = info.muteUntil; 38 | result["joinTime"] = info.joinTime; 39 | result["customInfo"] = info.customInfo; 40 | result["nameCard"] = info.nameCard; 41 | return result; 42 | } 43 | 44 | /// 根据对象获得字典对象 45 | public static func getDict(simpleInfo: V2TIMGroupMemberInfo) -> [String: Any] { 46 | var result: [String: Any] = [:]; 47 | result["userID"] = simpleInfo.userID; 48 | result["nickName"] = simpleInfo.nickName; 49 | result["friendRemark"] = simpleInfo.friendRemark; 50 | result["faceUrl"] = simpleInfo.faceURL; 51 | result["nameCard"] = simpleInfo.nameCard; 52 | return result; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomGroupMemberInfoResultEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/29. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | class CustomGroupMemberInfoResultEntity: NSObject { 9 | /// 获取分页拉取的 seq。如果为 0 表示拉取结束。 10 | var nextSeq: UInt64?; 11 | 12 | /// 群成员信息 13 | var memberInfoList: [[String: Any]]?; 14 | 15 | override init() { 16 | } 17 | 18 | init(nextSeq: UInt64, infos: [V2TIMGroupMemberFullInfo]) { 19 | super.init(); 20 | self.nextSeq = nextSeq; 21 | self.memberInfoList = []; 22 | for info in infos { 23 | self.memberInfoList!.append(CustomGroupMemberFullInfoEntity.getDict(info: info)) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomGroupMemberOperationResultEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/29. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义群成员操作结果 9 | class CustomGroupMemberOperationResultEntity: V2TIMGroupMemberOperationResult { 10 | 11 | /// 根据对象获得字典对象 12 | public static func getDict(info: V2TIMGroupMemberOperationResult) -> [String: Any] { 13 | var result: [String: Any] = [:]; 14 | result["result"] = info.result.rawValue; 15 | result["memberID"] = info.userID; 16 | return result; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomMessageReceiptEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/11/3. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义消息响应实体 9 | class CustomMessageReceiptEntity: V2TIMMessageReceipt { 10 | 11 | /// 根据对象获得字典对象 12 | public static func getDict(info: V2TIMMessageReceipt) -> [String: Any] { 13 | var result: [String: Any] = [:]; 14 | result["userID"] = info.userID; 15 | result["timestamp"] = info.timestamp; 16 | return result; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomOfflinePushInfoEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/27. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义离线推送数据实体 9 | class CustomOfflinePushInfoEntity: V2TIMOfflinePushInfo { 10 | required public override init() { 11 | } 12 | 13 | init(jsonStr: String?) { 14 | super.init(); 15 | 16 | if jsonStr == nil { 17 | return; 18 | } 19 | 20 | let dict = JsonUtil.getDictionaryFromJSONString(jsonString: jsonStr!); 21 | self.title = (dict["title"] as? String); 22 | self.desc = (dict["desc"] as? String); 23 | self.ext = (dict["ext"] as? String); 24 | self.iOSSound = (dict["iOSSound"] as? String); 25 | if dict["ignoreIOSBadge"] != nil { 26 | self.ignoreIOSBadge = (dict["ignoreIOSBadge"] as! Bool); 27 | } 28 | self.androidOPPOChannelID = (dict["androidOPPOChannelID"] as? String); 29 | if dict["disablePush"] != nil { 30 | self.disablePush = (dict["disablePush"] as! Bool); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomSignalingInfoEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/11/6. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义信令信息实体 9 | class CustomSignalingInfoEntity: V2TIMSignalingInfo { 10 | required public override init() { 11 | } 12 | 13 | init(jsonStr: String?) { 14 | super.init(); 15 | 16 | if jsonStr == nil { 17 | return; 18 | } 19 | let dict = JsonUtil.getDictionaryFromJSONString(jsonString: jsonStr!); 20 | self.inviteID = (dict["inviteID"] as? String); 21 | self.groupID = (dict["groupID"] as? String); 22 | self.inviter = (dict["inviter"] as? String); 23 | self.inviteeList = (dict["inviteeList"] as? NSMutableArray); 24 | self.data = (dict["data"] as? String); 25 | if dict["timeout"] != nil { 26 | self.timeout = (dict["timeout"] as! UInt32); 27 | } 28 | if dict["actionType"] != nil { 29 | self.actionType = SignalingActionType.init(rawValue: (dict["actionType"] as! Int))!; 30 | } 31 | } 32 | 33 | /// 根据对象获得字典对象 34 | public static func getDict(info: V2TIMSignalingInfo) -> [String: Any] { 35 | var result: [String: Any] = [:]; 36 | result["inviteID"] = info.inviteID; 37 | result["groupID"] = info.groupID; 38 | result["inviter"] = info.inviter; 39 | result["inviteeList"] = info.inviteeList; 40 | result["data"] = info.data; 41 | result["timeout"] = info.timeout; 42 | result["actionType"] = info.actionType.rawValue; 43 | return result; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ios/Classes/entity/CustomUserEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/29. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义用户实体 9 | class CustomUserEntity: V2TIMUserFullInfo { 10 | 11 | convenience init(json: String) { 12 | self.init(dict: JsonUtil.getDictionaryFromJSONString(jsonString: json)) 13 | } 14 | 15 | init(dict: [String: Any]) { 16 | super.init(); 17 | if dict["nickName"] != nil{ 18 | self.nickName = (dict["nickName"] as? String); 19 | } 20 | if dict["faceURL"] != nil{ 21 | self.faceURL = (dict["faceURL"] as? String); 22 | } 23 | if dict["selfSignature"] != nil{ 24 | self.selfSignature = (dict["selfSignature"] as? String); 25 | } 26 | if dict["gender"] != nil { 27 | self.gender = V2TIMGender.init(rawValue: (dict["gender"] as! Int))!; 28 | } 29 | if dict["role"] != nil { 30 | self.role = (dict["role"] as! UInt32); 31 | } 32 | if dict["level"] != nil { 33 | self.level = (dict["level"] as! UInt32); 34 | } 35 | if dict["birthday"] != nil { 36 | self.birthday = (dict["birthday"] as! UInt32); 37 | } 38 | if dict["allowType"] != nil { 39 | self.allowType = V2TIMFriendAllowType.init(rawValue: (dict["allowType"] as! Int))!; 40 | } 41 | if dict["customInfo"] != nil { 42 | self.customInfo = [:]; 43 | for (k, v) in (dict["customInfo"] as! [String: String]) { 44 | self.customInfo[k] = v.data(using: .utf8) 45 | } 46 | } 47 | } 48 | 49 | /// 根据对象获得字典对象 50 | public static func getDict(info: V2TIMUserFullInfo) -> [String: Any] { 51 | var result: [String: Any] = [:]; 52 | result["userID"] = info.userID; 53 | result["nickName"] = info.nickName; 54 | result["faceUrl"] = info.faceURL; 55 | result["selfSignature"] = info.selfSignature; 56 | result["gender"] = info.gender.rawValue; 57 | result["role"] = info.role; 58 | result["level"] = info.level; 59 | result["birthday"] = info.birthday; 60 | result["allowType"] = info.allowType.rawValue; 61 | result["customInfo"] = info.customInfo; 62 | return result; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /ios/Classes/entity/FindFriendApplicationEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/11/3. 3 | // 4 | 5 | import Foundation 6 | 7 | /// 查找好友申请实体 8 | class FindFriendApplicationEntity: NSObject { 9 | 10 | /// 用户ID 11 | var userID: String?; 12 | 13 | /// 类型 14 | var type: Int?; 15 | 16 | required public override init() { 17 | } 18 | 19 | convenience init(json: String) { 20 | self.init(dict: JsonUtil.getDictionaryFromJSONString(jsonString: json)) 21 | } 22 | 23 | init(dict: [String: Any]) { 24 | super.init(); 25 | self.userID = dict["userID"] as! String; 26 | self.type = dict["type"] as! Int; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ios/Classes/entity/FindGroupApplicationEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/28. 3 | // 4 | 5 | import Foundation 6 | 7 | /// 查找群申请信息实体 8 | class FindGroupApplicationEntity: NSObject { 9 | 10 | /// 来自用户 11 | var fromUser: String?; 12 | 13 | /// 群ID 14 | var groupID: String?; 15 | 16 | required public override init() { 17 | } 18 | 19 | convenience init(json: String) { 20 | self.init(dict: JsonUtil.getDictionaryFromJSONString(jsonString: json)) 21 | } 22 | 23 | init(dict: [String: Any]) { 24 | super.init(); 25 | self.fromUser = (dict["fromUser"] as! String); 26 | self.groupID = (dict["groupID"] as! String); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ios/Classes/entity/FindMessageEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/27. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 查找消息实体 9 | class FindMessageEntity: NSObject { 10 | 11 | /// 消息ID 12 | var msgId: String?; 13 | 14 | required public override init() { 15 | } 16 | 17 | convenience init(json: String) { 18 | self.init(dict: JsonUtil.getDictionaryFromJSONString(jsonString: json)) 19 | } 20 | 21 | init(dict: [String: Any]) { 22 | super.init(); 23 | self.msgId = dict["msgId"] as! String; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ios/Classes/enums/DownloadType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2021/1/5. 3 | // 4 | 5 | import Foundation 6 | 7 | /// 下载类型 8 | enum DownloadType: Int { 9 | /// 语音 10 | case Sound = 0 11 | 12 | /// 视频 13 | case Video = 1 14 | 15 | /// 视频缩略图 16 | case VideoThumbnail = 2 17 | 18 | /// 文件 19 | case File = 3 20 | } 21 | -------------------------------------------------------------------------------- /ios/Classes/listener/CustomAPNSListener.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/29. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义APNS监听器 9 | class CustomAPNSListener: NSObject, V2TIMAPNSListener { 10 | public static var number: UInt32 = 0; 11 | 12 | 13 | /// 程序进后台后,自定义 APP 的未读数,如果不处理,APP 未读数默认为所有会话未读数之和 14 | func onSetAPPUnreadCount() -> UInt32 { 15 | return CustomAPNSListener.number; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ios/Classes/listener/CustomAdvancedMsgListener.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/27. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 消息相关监听器 9 | class CustomAdvancedMsgListener: NSObject, V2TIMAdvancedMsgListener { 10 | /// 新消息通知 11 | func onRecvNewMessage(_ msg: V2TIMMessage!) { 12 | SwiftTencentImPlugin.invokeListener(type: ListenerType.NewMessage, params: MessageEntity.init(message: msg!)) 13 | } 14 | 15 | /// C2C已读回执 16 | func onRecvC2CReadReceipt(_ receiptList: [V2TIMMessageReceipt]!) { 17 | var data: [[String: Any]] = []; 18 | for item in receiptList! { 19 | data.append(CustomMessageReceiptEntity.getDict(info: item)); 20 | } 21 | SwiftTencentImPlugin.invokeListener(type: ListenerType.C2CReadReceipt, params: data) 22 | } 23 | 24 | /// 消息撤回 25 | func onRecvMessageRevoked(_ msgID: String!) { 26 | SwiftTencentImPlugin.invokeListener(type: ListenerType.MessageRevoked, params: msgID!) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ios/Classes/listener/CustomConversationListener.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/27. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义会话监听 9 | class CustomConversationListener: NSObject, V2TIMConversationListener { 10 | /// 同步服务开始 11 | func onSyncServerStart() { 12 | SwiftTencentImPlugin.invokeListener(type: ListenerType.SyncServerStart, params: nil) 13 | } 14 | 15 | /// 同步服务完成 16 | func onSyncServerFinish() { 17 | SwiftTencentImPlugin.invokeListener(type: ListenerType.SyncServerFinish, params: nil) 18 | } 19 | 20 | /// 同步服务失败 21 | func onSyncServerFailed() { 22 | SwiftTencentImPlugin.invokeListener(type: ListenerType.SyncServerFailed, params: nil) 23 | } 24 | 25 | /// 新会话 26 | func onNewConversation(_ conversationList: [V2TIMConversation]!) { 27 | var cs: [[String: Any]] = []; 28 | for item in conversationList! { 29 | cs.append(CustomConversationEntity.getDict(info: item)); 30 | } 31 | SwiftTencentImPlugin.invokeListener(type: ListenerType.NewConversation, params: cs) 32 | } 33 | 34 | /// 会话刷新 35 | func onConversationChanged(_ conversationList: [V2TIMConversation]!) { 36 | var cs: [[String: Any]] = []; 37 | for item in conversationList! { 38 | cs.append(CustomConversationEntity.getDict(info: item)); 39 | } 40 | SwiftTencentImPlugin.invokeListener(type: ListenerType.ConversationChanged, params: cs) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ios/Classes/listener/CustomSDKListener.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/27. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义SDK监听器 9 | class CustomSDKListener: NSObject, V2TIMSDKListener { 10 | /// 连接中 11 | public func onConnecting() { 12 | SwiftTencentImPlugin.invokeListener(type: ListenerType.Connecting, params: nil) 13 | } 14 | 15 | /// 网络连接成功 16 | public func onConnectSuccess() { 17 | SwiftTencentImPlugin.invokeListener(type: ListenerType.ConnectSuccess, params: nil) 18 | } 19 | 20 | /// 网络连接失败 21 | public func onConnectFailed(_ code: Int32, err: String!) { 22 | SwiftTencentImPlugin.invokeListener(type: ListenerType.ConnectFailed, params: [ 23 | "code": code, 24 | "err": err!, 25 | ]) 26 | } 27 | 28 | /// 踢下线通知 29 | public func onKickedOffline() { 30 | SwiftTencentImPlugin.invokeListener(type: ListenerType.KickedOffline, params: nil) 31 | } 32 | 33 | /// 用户登录的 userSig 过期(用户需要重新获取 userSig 后登录) 34 | public func onUserSigExpired() { 35 | SwiftTencentImPlugin.invokeListener(type: ListenerType.UserSigExpired, params: nil) 36 | } 37 | 38 | /// 当前用户的资料发生了更新 39 | public func onSelfInfoUpdated(_ Info: V2TIMUserFullInfo!) { 40 | SwiftTencentImPlugin.invokeListener(type: ListenerType.SelfInfoUpdated, params: CustomUserEntity.getDict(info: Info!)) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ios/Classes/listener/CustomSignalingListener.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/27. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 自定义信令监听 9 | class CustomSignalingListener: NSObject, V2TIMSignalingListener { 10 | ///收到新邀请时 11 | func onReceiveNewInvitation(_ inviteID: String!, inviter: String!, groupID: String!, inviteeList: [String]!, data: String?) { 12 | var params: [String: Any] = ["inviteID": inviteID!]; 13 | if let temp = inviter { 14 | params["inviter"] = temp; 15 | } 16 | if let temp = groupID { 17 | params["groupID"] = temp; 18 | } 19 | if let temp = inviteeList { 20 | params["inviteeList"] = temp; 21 | } 22 | if let temp = data { 23 | params["data"] = temp; 24 | } 25 | SwiftTencentImPlugin.invokeListener(type: ListenerType.ReceiveNewInvitation, params: params) 26 | } 27 | 28 | /// 被邀请者接受邀请 29 | func onInviteeAccepted(_ inviteID: String!, invitee: String!, data: String?) { 30 | var params: [String: Any] = ["inviteID": inviteID!,"invitee": invitee!]; 31 | if let temp = data { 32 | params["data"] = temp; 33 | } 34 | SwiftTencentImPlugin.invokeListener(type: ListenerType.InviteeAccepted, params: params) 35 | } 36 | 37 | /// 被邀请者拒绝邀请 38 | func onInviteeRejected(_ inviteID: String!, invitee: String!, data: String?) { 39 | var params: [String: Any] = ["inviteID": inviteID!,"invitee": invitee!]; 40 | if let temp = data { 41 | params["data"] = temp; 42 | } 43 | SwiftTencentImPlugin.invokeListener(type: ListenerType.InviteeRejected, params: params) 44 | } 45 | 46 | /// 邀请被取消 47 | func onInvitationCancelled(_ inviteID: String!, inviter: String!, data: String?) { 48 | var params: [String: Any] = ["inviteID": inviteID!,"inviter": inviter!]; 49 | if let temp = data { 50 | params["data"] = temp; 51 | } 52 | SwiftTencentImPlugin.invokeListener(type: ListenerType.InvitationCancelled, params: params) 53 | } 54 | 55 | /// 邀请超时 56 | func onInvitationTimeout(_ inviteID: String!, inviteeList: [String]!) { 57 | SwiftTencentImPlugin.invokeListener(type: ListenerType.InvitationTimeout, params: [ 58 | "inviteID": inviteID!, 59 | "inviteeList": inviteeList!, 60 | ]) 61 | } 62 | } -------------------------------------------------------------------------------- /ios/Classes/message/AbstractMessageNode.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // 4 | // AbstractMessageNode.swift 5 | // tencent_im_plugin 6 | // 7 | // Created by 蒋具宏 on 2020/3/13. 8 | // 消息节点抽象 9 | public class AbstractMessageNode { 10 | 11 | /** 12 | * 获得发送的消息体 13 | * @param params 参数 14 | */ 15 | func getV2TIMMessage(params: [String: Any]) -> V2TIMMessage { 16 | return V2TIMMessage(); 17 | } 18 | 19 | /** 20 | * 根据消息节点获得描述 21 | * 22 | * @param elem 节点 23 | */ 24 | func getNote(elem: V2TIMElem) -> String? { 25 | return nil; 26 | } 27 | 28 | /// 根据节点解析为实体对象 29 | func analysis(elem: V2TIMElem) -> AbstractMessageEntity? { 30 | return nil; 31 | } 32 | 33 | /// 获得参数 34 | func getParam(params: [AnyHashable: Any], paramKey: AnyHashable) -> T? { 35 | if let value = params[paramKey] { 36 | return (value as? T); 37 | } 38 | return nil; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ios/Classes/message/CustomMessageNode.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // 4 | // TextMessageNode.swift 5 | // tencent_im_plugin 6 | // 7 | // Created by 蒋具宏 on 2020/3/13. 8 | // 自定义消息节点 9 | public class CustomMessageNode: AbstractMessageNode { 10 | 11 | override func getV2TIMMessage(params: [String: Any]) -> V2TIMMessage { 12 | let data: String = getParam(params: params, paramKey: "data")!; 13 | let desc: String? = getParam(params: params, paramKey: "desc"); 14 | let ext: String? = getParam(params: params, paramKey: "ext"); 15 | return V2TIMManager.sharedInstance().createCustomMessage(data.data(using: String.Encoding.utf8), desc: desc, extension: ext) 16 | } 17 | 18 | override func getNote(elem: V2TIMElem) -> String { 19 | "[其它消息]" 20 | } 21 | 22 | override func analysis(elem: V2TIMElem) -> AbstractMessageEntity { 23 | CustomMessageEntity(elem: elem as! V2TIMCustomElem) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ios/Classes/message/FaceMessageNode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/27. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 表情消息实体 9 | class FaceMessageNode: AbstractMessageNode { 10 | override func getV2TIMMessage(params: [String: Any]) -> V2TIMMessage { 11 | let index: Int32 = getParam(params: params, paramKey: "index")!; 12 | let data: String = getParam(params: params, paramKey: "data")!; 13 | return V2TIMManager.sharedInstance().createFaceMessage(index, data: data.data(using: String.Encoding.utf8)) 14 | } 15 | 16 | override func getNote(elem: V2TIMElem) -> String { 17 | "[表情]"; 18 | } 19 | 20 | override func analysis(elem: V2TIMElem) -> AbstractMessageEntity { 21 | FaceMessageEntity(elem: elem as! V2TIMFaceElem) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Classes/message/FileMessageNode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/27. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | class FileMessageNode: AbstractMessageNode { 9 | override func getV2TIMMessage(params: [String: Any]) -> V2TIMMessage { 10 | let filePath: String = getParam(params: params, paramKey: "filePath")!; 11 | let fileName: String = getParam(params: params, paramKey: "fileName")!; 12 | return V2TIMManager.sharedInstance().createFileMessage(filePath, fileName: fileName) 13 | } 14 | 15 | override func getNote(elem: V2TIMElem) -> String { 16 | "[文件]"; 17 | } 18 | 19 | override func analysis(elem: V2TIMElem) -> AbstractMessageEntity { 20 | FileMessageEntity(elem: elem as! V2TIMFileElem) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ios/Classes/message/GroupTipsMessageNode.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // 4 | // GroupTipsMessageNode.swift 5 | // tencent_im_plugin 6 | // 7 | // Created by 蒋具宏 on 2020/3/21. 8 | // 群提示消息节点 9 | public class GroupTipsMessageNode: AbstractMessageNode { 10 | override func getNote(elem: V2TIMElem) -> String { 11 | "[群提示]"; 12 | } 13 | 14 | override func analysis(elem: V2TIMElem) -> AbstractMessageEntity { 15 | GroupTipsMessageEntity(elem: elem as! V2TIMGroupTipsElem); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ios/Classes/message/ImageMessageNode.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // 4 | // TextMessageNode.swift 5 | // tencent_im_plugin 6 | // 7 | // Created by 蒋具宏 on 2020/3/13. 8 | // 图片消息节点 9 | public class ImageMessageNode: AbstractMessageNode { 10 | 11 | override func getV2TIMMessage(params: [String: Any]) -> V2TIMMessage { 12 | let path: String = getParam(params: params, paramKey: "path")!; 13 | return V2TIMManager.sharedInstance().createImageMessage(path) 14 | } 15 | 16 | override func getNote(elem: V2TIMElem) -> String { 17 | "[图片]"; 18 | } 19 | 20 | override func analysis(elem: V2TIMElem) -> AbstractMessageEntity { 21 | ImageMessageEntity(elem: elem as! V2TIMImageElem) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Classes/message/LocationMessageNode.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // 4 | // TextMessageNode.swift 5 | // tencent_im_plugin 6 | // 7 | // Created by 蒋具宏 on 2020/3/13. 8 | // 位置消息节点 9 | public class LocationMessageNode: AbstractMessageNode { 10 | 11 | override func getV2TIMMessage(params: [String: Any]) -> V2TIMMessage { 12 | let desc: String = getParam(params: params, paramKey: "desc")!; 13 | let longitude: Double = getParam(params: params, paramKey: "longitude")!; 14 | let latitude: Double = getParam(params: params, paramKey: "latitude")!; 15 | return V2TIMManager.sharedInstance().createLocationMessage(desc, longitude: longitude, latitude: latitude) 16 | } 17 | 18 | override func getNote(elem: V2TIMElem) -> String { 19 | "[位置消息]"; 20 | } 21 | 22 | override func analysis(elem: V2TIMElem) -> AbstractMessageEntity { 23 | LocationMessageEntity(elem: elem as! V2TIMLocationElem); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ios/Classes/message/SoundMessageNode.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // 4 | // TextMessageNode.swift 5 | // tencent_im_plugin 6 | // 7 | // Created by 蒋具宏 on 2020/3/13. 8 | // 语音消息节点 9 | public class SoundMessageNode: AbstractMessageNode { 10 | 11 | override func getV2TIMMessage(params: [String: Any]) -> V2TIMMessage { 12 | let path: String = getParam(params: params, paramKey: "path")!; 13 | let duration: Int32 = getParam(params: params, paramKey: "duration")!; 14 | return V2TIMManager.sharedInstance().createSoundMessage(path, duration: duration) 15 | } 16 | 17 | override func getNote(elem: V2TIMElem) -> String { 18 | "[语音]"; 19 | } 20 | 21 | override func analysis(elem: V2TIMElem) -> AbstractMessageEntity { 22 | SoundMessageEntity(elem: elem as! V2TIMSoundElem); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ios/Classes/message/TextMessageNode.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // 4 | // TextMessageNode.swift 5 | // tencent_im_plugin 6 | // 7 | // Created by 蒋具宏 on 2020/3/13. 8 | // 文本消息节点 9 | public class TextMessageNode: AbstractMessageNode { 10 | override func getV2TIMMessage(params: [String: Any]) -> V2TIMMessage { 11 | let text: String = getParam(params: params, paramKey: "content")!; 12 | let atUserList: Any? = getParam(params: params, paramKey: "atUserList"); 13 | let atAll: Any? = getParam(params: params, paramKey: "atAll"); 14 | 15 | // 有@用户或者@所有人则进入分支 16 | if (atUserList != nil && !(atUserList is NSNull)) || (atAll != nil && atAll is NSNull && atAll as! Bool) { 17 | var atList: [String] = []; 18 | 19 | // 追加@的目标 20 | if atUserList != nil && !(atUserList is NSNull) { 21 | for item in atUserList as! [String] { 22 | atList.append(item); 23 | } 24 | } 25 | 26 | // @所有人 27 | if atAll != nil && !(atAll is NSNull) && (atAll as! Bool) { 28 | atList.append(kImSDK_MesssageAtALL); 29 | } 30 | 31 | // @有内容则直接返回 32 | if atList.count >= 1 { 33 | return V2TIMManager.sharedInstance().createText(atMessage: text, atUserList: (atList as AnyObject as! NSArray).mutableCopy() as! NSMutableArray) 34 | } 35 | } 36 | return V2TIMManager.sharedInstance().createTextMessage(text); 37 | } 38 | 39 | override func getNote(elem: V2TIMElem) -> String { 40 | (elem as! V2TIMTextElem).text ?? ""; 41 | } 42 | 43 | override func analysis(elem: V2TIMElem) -> AbstractMessageEntity { 44 | TextMessageEntity(elem: elem as! V2TIMTextElem) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ios/Classes/message/VideoMessageNode.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // 4 | // TextMessageNode.swift 5 | // tencent_im_plugin 6 | // 7 | // Created by 蒋具宏 on 2020/3/13. 8 | // 视频消息节点 9 | public class VideoMessageNode: AbstractMessageNode { 10 | 11 | override func getV2TIMMessage(params: [String: Any]) -> V2TIMMessage { 12 | let videoPath: String = getParam(params: params, paramKey: "videoPath")!; 13 | let duration: Int32 = getParam(params: params, paramKey: "duration")!; 14 | let snapshotPath: String = getParam(params: params, paramKey: "snapshotPath")!; 15 | 16 | var suffix: String = ""; 17 | if videoPath.contains(".") { 18 | let ss = videoPath.split(separator: "."); 19 | suffix = String(ss[ss.count - 1]); 20 | } 21 | return V2TIMManager.sharedInstance().createVideoMessage(videoPath, type: suffix, duration: duration, snapshotPath: snapshotPath) 22 | } 23 | 24 | override func getNote(elem: V2TIMElem) -> String { 25 | "[视频]"; 26 | } 27 | 28 | override func analysis(elem: V2TIMElem) -> AbstractMessageEntity { 29 | VideoMessageEntity(elem: elem as! V2TIMVideoElem); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ios/Classes/message/entity/AbstractMessageEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AbstractMessageEntity.swift 3 | // tencent_im_plugin 4 | // 5 | // Created by 蒋具宏 on 2020/3/15. 6 | // 抽象消息实体 7 | public class AbstractMessageEntity : NSObject{ 8 | var nodeType : MessageNodeType?; 9 | 10 | override init() { 11 | } 12 | 13 | init(_ type : MessageNodeType) { 14 | nodeType = type; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ios/Classes/message/entity/CustomMessageEntity.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // Created by 蒋具宏 on 2020/3/15. 4 | // 自定义消息实体 5 | public class CustomMessageEntity: AbstractMessageEntity { 6 | /// 自定义内容 7 | var data: String?; 8 | 9 | /// 描述 10 | var desc: String?; 11 | 12 | /// 扩展 13 | var ext: String?; 14 | 15 | override init() { 16 | super.init(MessageNodeType.Custom); 17 | } 18 | 19 | init(elem: V2TIMCustomElem) { 20 | super.init(MessageNodeType.Custom); 21 | self.data = String(data: elem.data, encoding: String.Encoding.utf8)!; 22 | if let v = elem.desc { 23 | self.desc = v; 24 | } 25 | if let v = elem.`extension` { 26 | self.ext = v; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ios/Classes/message/entity/FaceMessageEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/27. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 表情消息实体 9 | class FaceMessageEntity: AbstractMessageEntity { 10 | /** 11 | * 下标 12 | */ 13 | var index: Int32?; 14 | 15 | /** 16 | * 文件名 17 | */ 18 | var data: Data?; 19 | 20 | override init() { 21 | super.init(MessageNodeType.Face); 22 | } 23 | 24 | init(elem: V2TIMFaceElem) { 25 | super.init(MessageNodeType.Face); 26 | self.index = elem.index; 27 | self.data = elem.data; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ios/Classes/message/entity/FileMessageEntity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 蒋具宏 on 2020/10/27. 3 | // 4 | 5 | import Foundation 6 | import ImSDK_Plus 7 | 8 | /// 文件消息实体 9 | class FileMessageEntity: AbstractMessageEntity { 10 | /** 11 | * 文件路径 12 | */ 13 | var filePath: String?; 14 | 15 | /** 16 | * 文件名 17 | */ 18 | var fileName: String?; 19 | 20 | /** 21 | * 文件UUID 22 | */ 23 | var uuid: String?; 24 | 25 | /** 26 | * 文件大小 27 | */ 28 | var size: Int32?; 29 | 30 | override init() { 31 | super.init(MessageNodeType.File); 32 | } 33 | 34 | init(elem: V2TIMFileElem) { 35 | super.init(MessageNodeType.File); 36 | self.uuid = elem.uuid; 37 | self.fileName = elem.filename; 38 | self.filePath = elem.path; 39 | self.size = elem.fileSize; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ios/Classes/message/entity/LocationMessageEntity.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // Created by 蒋具宏 on 2020/3/15. 4 | // 位置消息实体 5 | public class LocationMessageEntity: AbstractMessageEntity { 6 | 7 | /// 描述 8 | var desc: String?; 9 | 10 | /// 经度 11 | var latitude: Double?; 12 | 13 | /// 纬度 14 | var longitude: Double?; 15 | 16 | override init() { 17 | super.init(MessageNodeType.Location) 18 | } 19 | 20 | init(elem: V2TIMLocationElem) { 21 | super.init(MessageNodeType.Location) 22 | self.desc = elem.desc; 23 | self.longitude = elem.longitude; 24 | self.latitude = elem.latitude; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ios/Classes/message/entity/SoundMessageEntity.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // Created by 蒋具宏 on 2020/3/15. 4 | // 语音消息实体 5 | public class SoundMessageEntity: AbstractMessageEntity { 6 | 7 | /// 语音ID 8 | var uuid: String?; 9 | 10 | /// 路径 11 | var path: String?; 12 | 13 | /// 时长 14 | var duration: Int32?; 15 | 16 | /// 数据大小 17 | var dataSize: Int32?; 18 | 19 | override init() { 20 | super.init(MessageNodeType.Sound); 21 | } 22 | 23 | init(elem: V2TIMSoundElem) { 24 | super.init(MessageNodeType.Sound); 25 | self.path = elem.path; 26 | self.dataSize = elem.dataSize; 27 | self.duration = elem.duration; 28 | self.uuid = elem.uuid; 29 | } 30 | } -------------------------------------------------------------------------------- /ios/Classes/message/entity/TextMessageEntity.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // 4 | // TextMessageEntity.swift 5 | // tencent_im_plugin 6 | // 7 | // Created by 蒋具宏 on 2020/3/15. 8 | // 文本消息实体 9 | public class TextMessageEntity: AbstractMessageEntity { 10 | /// 消息内容 11 | var content: String?; 12 | 13 | override init() { 14 | super.init(MessageNodeType.Text); 15 | } 16 | 17 | init(elem: V2TIMTextElem) { 18 | super.init(MessageNodeType.Text); 19 | self.content = elem.text; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ios/Classes/message/entity/VideoMessageEntity.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // Created by 蒋具宏 on 2020/3/15. 4 | // 视频消息实体 5 | public class VideoMessageEntity: AbstractMessageEntity { 6 | 7 | /** 8 | * 视频路径 9 | */ 10 | var videoPath: String?; 11 | /** 12 | * 视频UUID 13 | */ 14 | var videoUuid: String?; 15 | /** 16 | * 视频大小 17 | */ 18 | var videoSize: Int32?; 19 | /** 20 | * 时长 21 | */ 22 | var duration: Int32?; 23 | /** 24 | * 缩略图路径 25 | */ 26 | var snapshotPath: String?; 27 | /** 28 | * 缩略图UUID 29 | */ 30 | var snapshotUuid: String?; 31 | /** 32 | * 缩略图大小 33 | */ 34 | var snapshotSize: Int32?; 35 | /** 36 | * 缩略图宽度 37 | */ 38 | var snapshotWidth: Int32?; 39 | /** 40 | * 缩略图高度 41 | */ 42 | var snapshotHeight: Int32?; 43 | 44 | override init() { 45 | super.init(MessageNodeType.Video); 46 | } 47 | 48 | init(elem: V2TIMVideoElem) { 49 | super.init(MessageNodeType.Video); 50 | self.videoUuid = elem.videoUUID; 51 | self.videoPath = elem.videoPath; 52 | self.videoSize = elem.videoSize; 53 | self.duration = elem.duration; 54 | self.snapshotUuid = elem.snapshotUUID; 55 | self.snapshotWidth = elem.snapshotWidth; 56 | self.snapshotHeight = elem.snapshotHeight; 57 | self.snapshotPath = elem.snapshotPath; 58 | self.snapshotSize = elem.snapshotSize; 59 | } 60 | } -------------------------------------------------------------------------------- /ios/Classes/message/entity/group_tips/GroupTipsMessageEntity.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // 4 | // GroupTipsMessageself.swift 5 | // tencent_im_plugin 6 | // 7 | // Created by 蒋具宏 on 2020/3/21. 8 | // 群体是消息实体 9 | public class GroupTipsMessageEntity: AbstractMessageEntity { 10 | /// 群ID 11 | var groupID: String?; 12 | 13 | /// 操作类型 14 | var type: Int?; 15 | 16 | /// 操作者 17 | var opMember: [String: Any]?; 18 | 19 | /// 被操作人列表 20 | var memberList: [[String: Any]]?; 21 | 22 | /// 群资料变更信息列表,仅当tipsType值为V2TIMGroupTipsElem#V2TIM_GROUP_TIPS_TYPE_GROUP_INFO_CHANGE时有效 23 | var groupChangeInfoList: [[String: Any]]?; 24 | 25 | /// 群成员变更信息列表,仅当tipsType值为V2TIMGroupTipsElem#V2TIM_GROUP_TIPS_TYPE_MEMBER_INFO_CHANGE时有效 26 | var memberChangeInfoList: [[String: Any]]?; 27 | 28 | /// 当前群成员数,仅当tipsType值为V2TIMGroupTipsElem#V2TIM_GROUP_TIPS_TYPE_JOIN, V2TIMGroupTipsElem#V2TIM_GROUP_TIPS_TYPE_QUIT, V2TIMGroupTipsElem#V2TIM_GROUP_TIPS_TYPE_KICKED的时候有效 29 | var memberCount : UInt32?; 30 | 31 | override init() { 32 | super.init(MessageNodeType.GroupTips); 33 | } 34 | 35 | init(elem: V2TIMGroupTipsElem) { 36 | super.init(MessageNodeType.GroupTips); 37 | self.groupID = elem.groupID; 38 | self.type = elem.type.rawValue; 39 | self.opMember = CustomGroupMemberFullInfoEntity.getDict(simpleInfo: elem.opMember); 40 | var memberList : [[String: Any]] = []; 41 | for var item in elem.memberList{ 42 | memberList.append(CustomGroupMemberFullInfoEntity.getDict(simpleInfo: item)); 43 | } 44 | self.memberList = memberList; 45 | 46 | var groupChangeInfoList : [[String: Any]] = []; 47 | for var item in elem.groupChangeInfoList{ 48 | groupChangeInfoList.append(CustomGroupChangeInfoEntity.getDict(info: item)); 49 | } 50 | self.groupChangeInfoList = groupChangeInfoList; 51 | 52 | var memberChangeInfoList : [[String: Any]] = []; 53 | for var item in elem.memberChangeInfoList{ 54 | memberChangeInfoList.append(CustomGroupMemberChangeInfoEntity.getDict(info: item)); 55 | } 56 | self.memberChangeInfoList = groupChangeInfoList; 57 | 58 | self.memberCount = elem.memberCount; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ios/Classes/message/entity/image/ImageEntity.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // Created by 蒋具宏 on 2020/2/10. 4 | // 图片实体 5 | public class ImageEntity: NSObject { 6 | 7 | /** 8 | * 大小 9 | */ 10 | var size: Int32?; 11 | 12 | /** 13 | * 宽度 14 | */ 15 | var width: Int32?; 16 | 17 | /** 18 | * 类型 19 | */ 20 | var type: Int?; 21 | 22 | /** 23 | * url 24 | */ 25 | var url: String?; 26 | 27 | /** 28 | * 高度 29 | */ 30 | var height: Int32?; 31 | 32 | /// ID 33 | var uUID: String?; 34 | 35 | override init() { 36 | } 37 | 38 | init(image: V2TIMImage) { 39 | super.init(); 40 | self.size = image.size; 41 | self.width = image.width; 42 | self.type = image.type.rawValue; 43 | self.url = image.url; 44 | self.height = image.height; 45 | self.uUID = image.uuid; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ios/Classes/message/entity/image/ImageMessageEntity.swift: -------------------------------------------------------------------------------- 1 | import ImSDK_Plus 2 | 3 | // Created by 蒋具宏 on 2020/3/15. 4 | // 图片消息实体 5 | public class ImageMessageEntity: AbstractMessageEntity { 6 | 7 | /// 路径 8 | var path: String?; 9 | 10 | /// 图片数据 11 | var imageData: [ImageEntity]?; 12 | 13 | override init() { 14 | super.init(MessageNodeType.Image); 15 | } 16 | 17 | init(elem: V2TIMImageElem) { 18 | super.init(MessageNodeType.Image); 19 | self.path = elem.path; 20 | self.imageData = []; 21 | for item in elem.imageList { 22 | self.imageData!.append(ImageEntity(image: item)); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ios/Classes/utils/CommonUtils.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | 3 | // 通用工具类 4 | // Created by 蒋具宏 on 2020/2/10. 5 | public class CommonUtils { 6 | /** 7 | * 通用方法,获得参数值,如未找到参数,则直接中断 8 | * 9 | * @param methodCall 方法调用对象 10 | * @param result 返回对象 11 | * @param param 参数名 12 | */ 13 | public static func getParam(call: FlutterMethodCall, result: @escaping FlutterResult, param: String) -> Any? { 14 | let value = (call.arguments as! [String: Any])[param]; 15 | if value == nil { 16 | result( 17 | FlutterError(code: "5", message: "Missing parameter", details: "Cannot find parameter `\(param)` or `\(param)` is null!") 18 | ); 19 | } 20 | return value 21 | } 22 | 23 | /// 将hex string 转为Data 24 | public static func dataWithHexString(hex: String) -> Data { 25 | var hex = hex 26 | var data = Data() 27 | while (hex.count > 0) { 28 | let index1 = hex.index(hex.startIndex, offsetBy: 2) 29 | let index2 = hex.index(hex.endIndex, offsetBy: 0) 30 | let c: String = String(hex[hex.startIndex.. '../LICENSE' } 14 | s.author = { 'JiangJuHong' => '690717394@qq.com' } 15 | s.source = { :path => '.' } 16 | s.source_files = 'Classes/**/*' 17 | s.dependency 'Flutter' 18 | s.platform = :ios, '8.0' 19 | 20 | # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. 21 | # s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } 22 | s.swift_version = '5.0' 23 | 24 | # 解决 for architecture arm64 问题 25 | s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' } 26 | s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' } 27 | 28 | # 资源导入 29 | s.vendored_frameworks = '**/*.framework' 30 | 31 | # SDK 依赖 32 | s.dependency 'TXIMSDK_Plus_iOS_Bitcode', '6.1.2155' 33 | 34 | # alibaba json 序列化库(https://github.com/alibaba/HandyJSON) 35 | s.dependency 'HandyJSON' 36 | end 37 | -------------------------------------------------------------------------------- /lib/entity/conversation_result_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:tencent_im_plugin/entity/conversation_entity.dart'; 4 | import 'package:tencent_im_plugin/list_util.dart'; 5 | 6 | /// 会话结果实体 7 | class ConversationResultEntity { 8 | /// 下一次分页拉取的游标 9 | late int nextSeq; 10 | 11 | /// 会话列表是否已经拉取完毕 12 | late bool finished; 13 | 14 | /// 会话列表 15 | late List conversationList; 16 | 17 | ConversationResultEntity.fromJson(data) { 18 | Map json = 19 | data is Map ? data.cast() : jsonDecode(data); 20 | if (json['nextSeq'] != null) nextSeq = json['nextSeq']; 21 | if (json['finished'] != null) finished = json['finished']; 22 | if (json['conversationList'] != null) 23 | conversationList = ListUtil.generateOBJList( 24 | json["conversationList"]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/entity/download_progress_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:tencent_im_plugin/enums/download_type_enum.dart'; 4 | 5 | /// 下载进度实体 6 | class DownloadProgressEntity { 7 | /// 消息ID 8 | late String msgId; 9 | 10 | /// 当前下载大小 11 | late int currentSize; 12 | 13 | /// 总大小 14 | late int totalSize; 15 | 16 | /// 下载类型 17 | late DownloadTypeEnum type; 18 | 19 | DownloadProgressEntity.fromJson(data) { 20 | Map json = 21 | data is Map ? data.cast() : jsonDecode(data); 22 | if (json['msgId'] != null) msgId = json["msgId"]; 23 | if (json['currentSize'] != null) currentSize = json["currentSize"]; 24 | if (json['totalSize'] != null) totalSize = json["totalSize"]; 25 | if (json['type'] != null) type = DownloadTypeTool.getByInt(json["type"]); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/entity/error_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | /// 错误实体 4 | class ErrorEntity { 5 | /// 错误码 6 | late int code; 7 | 8 | /// 错误描述 9 | String? error; 10 | 11 | ErrorEntity.fromJson(data) { 12 | Map json = 13 | data is Map ? data.cast() : jsonDecode(data); 14 | if (json['code'] != null) code = json['code']; 15 | if (json['error'] != null) error = json['error']; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/entity/find_friend_application_entity.dart: -------------------------------------------------------------------------------- 1 | import 'package:tencent_im_plugin/entity/friend_application_entity.dart'; 2 | import 'package:tencent_im_plugin/enums/friend_application_type_enum.dart'; 3 | 4 | /// 查找好友申请实体 5 | class FindFriendApplicationEntity { 6 | /// 用户ID 7 | String userID; 8 | 9 | /// 类型 10 | FriendApplicationTypeEnum type; 11 | 12 | FindFriendApplicationEntity({ 13 | required this.userID, 14 | required this.type, 15 | }); 16 | 17 | /// 根据[data]对象快速转换为查找好友申请实体 18 | factory FindFriendApplicationEntity.fromFriendApplicationEntity(FriendApplicationEntity data) { 19 | return FindFriendApplicationEntity(userID: data.userID, type: data.type); 20 | } 21 | 22 | Map toJson() { 23 | final Map data = new Map(); 24 | data["userID"] = userID; 25 | data["type"] = FriendApplicationTypeTool.toInt(type); 26 | return data; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/entity/find_group_application_entity.dart: -------------------------------------------------------------------------------- 1 | /// 查找群申请实体 2 | class FindGroupApplicationEntity { 3 | /// 来自用户 4 | String fromUser; 5 | 6 | /// 群ID 7 | String groupID; 8 | 9 | FindGroupApplicationEntity({ 10 | required this.fromUser, 11 | required this.groupID, 12 | }); 13 | 14 | Map toJson() { 15 | final Map data = new Map(); 16 | data["fromUser"] = fromUser; 17 | data["groupID"] = groupID; 18 | return data; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/entity/find_message_entity.dart: -------------------------------------------------------------------------------- 1 | /// 查找消息实体 2 | class FindMessageEntity { 3 | /// 消息ID 4 | String msgId; 5 | 6 | FindMessageEntity({ 7 | required this.msgId, 8 | }); 9 | 10 | Map toJson() { 11 | final Map data = new Map(); 12 | data["msgId"] = this.msgId; 13 | return data; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/entity/friend_add_application_entity.dart: -------------------------------------------------------------------------------- 1 | import 'package:tencent_im_plugin/enums/friend_type_enum.dart'; 2 | 3 | /// 好友添加申请实体 4 | class FriendAddApplicationEntity { 5 | /// 用户ID 6 | String userID; 7 | 8 | /// 好友备注 9 | String? friendRemark; 10 | 11 | /// 申请描述 12 | String? addWording; 13 | 14 | /// 添加来源 15 | String? addSource; 16 | 17 | /// 添加类型 18 | FriendTypeEnum addType; 19 | 20 | FriendAddApplicationEntity({ 21 | required this.userID, 22 | this.friendRemark, 23 | this.addWording, 24 | this.addSource, 25 | required this.addType, 26 | }); 27 | 28 | Map toJson() { 29 | final Map data = new Map(); 30 | data['userID'] = this.userID; 31 | if (this.friendRemark != null) data['friendRemark'] = this.friendRemark; 32 | if (this.addWording != null) data['addWording'] = this.addWording; 33 | if (this.addSource != null) data['addSource'] = this.addSource; 34 | data['addType'] = FriendTypeTool.toInt(this.addType); 35 | return data; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/entity/friend_application_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/enums/friend_application_type_enum.dart'; 3 | 4 | /// 好友申请实体 5 | class FriendApplicationEntity { 6 | /// 用户ID 7 | late String userID; 8 | 9 | /// 用户昵称 10 | String? nickname; 11 | 12 | /// 用户头像 13 | String? faceUrl; 14 | 15 | /// 申请时间 16 | late int addTime; 17 | 18 | /// 申请来源 19 | String? addSource; 20 | 21 | /// 申请描述 22 | String? addWording; 23 | 24 | /// 类型 25 | late FriendApplicationTypeEnum type; 26 | 27 | FriendApplicationEntity.fromJson(data) { 28 | Map json = 29 | data is Map ? data.cast() : jsonDecode(data); 30 | if (json['userID'] != null) userID = json['userID']; 31 | if (json['nickname'] != null) nickname = json['nickname']; 32 | if (json['faceUrl'] != null) faceUrl = json['faceUrl']; 33 | if (json['addTime'] != null) addTime = json['addTime']; 34 | if (json['addSource'] != null) addSource = json['addSource']; 35 | if (json['addWording'] != null) addWording = json['addWording']; 36 | if (json['type'] != null) 37 | type = FriendApplicationTypeTool.getByInt(json['type']); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/entity/friend_application_result_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/entity/friend_application_entity.dart'; 3 | import 'package:tencent_im_plugin/list_util.dart'; 4 | 5 | /// 好友申请结果实体 6 | class FriendApplicationResultEntity { 7 | /// 未读数量 8 | late int unreadCount; 9 | 10 | /// 好友申请列表 11 | late List friendApplicationList; 12 | 13 | FriendApplicationResultEntity.fromJson(data) { 14 | Map json = 15 | data is Map ? data.cast() : jsonDecode(data); 16 | if (json['unreadCount'] != null) unreadCount = json['unreadCount']; 17 | if (json['friendApplicationList'] != null) 18 | friendApplicationList = ListUtil.generateOBJList( 19 | json['friendApplicationList']); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/entity/friend_check_result_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/enums/friend_relation_type_enum.dart'; 3 | 4 | /// 好友检测结果实体 5 | class FriendCheckResultEntity { 6 | /// 好友 id 7 | late String userID; 8 | 9 | /// 返回结果码 10 | late int resultCode; 11 | 12 | /// 返回结果描述 13 | String? resultInfo; 14 | 15 | /// 好友结果类型 16 | FriendRelationTypeEnum? resultType; 17 | 18 | FriendCheckResultEntity.fromJson(data) { 19 | Map json = 20 | data is Map ? data.cast() : jsonDecode(data); 21 | if (json['userID'] != null) userID = json['userID']; 22 | if (json['resultCode'] != null) resultCode = json['resultCode']; 23 | if (json['resultInfo'] != null) resultInfo = json['resultInfo']; 24 | if (json['resultType'] != null) 25 | resultType = FriendRelationTypeTool.getByInt(json['resultType']); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/entity/friend_group_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | /// 好友分组实体 4 | class FriendGroupEntity { 5 | /// 组名 6 | late String name; 7 | 8 | /// 好友数量 9 | late int friendCount; 10 | 11 | /// 好友ID列表 12 | late List friendIDList; 13 | 14 | FriendGroupEntity.fromJson(data) { 15 | Map json = 16 | data is Map ? data.cast() : jsonDecode(data); 17 | if (json['name'] != null) name = json['name']; 18 | if (json['friendCount'] != null) friendCount = json['friendCount']; 19 | if (json['friendIDList'] != null) 20 | friendIDList = json['friendIDList']?.cast(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/entity/friend_info_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/entity/user_entity.dart'; 3 | 4 | /// 好友信息实体 5 | class FriendInfoEntity { 6 | /// 用户ID 7 | late String userID; 8 | 9 | /// 好友备注 10 | String? friendRemark; 11 | 12 | /// 好友分组列表 13 | List? friendGroups; 14 | 15 | /// 好友自定义信息 16 | Map? friendCustomInfo; 17 | 18 | /// 用户信息 19 | UserEntity? userProfile; 20 | 21 | FriendInfoEntity({ 22 | required this.userID, 23 | this.friendRemark, 24 | this.friendCustomInfo, 25 | }); 26 | 27 | FriendInfoEntity.fromJson(data) { 28 | Map json = data is Map ? data.cast() : jsonDecode(data); 29 | if (json['userID'] != null) userID = json['userID']; 30 | if (json['friendRemark'] != null) friendRemark = json['friendRemark']; 31 | if (json['friendGroups'] != null) friendGroups = json['friendGroups']?.cast(); 32 | if (json['friendCustomInfo'] != null) friendCustomInfo = json['friendCustomInfo']?.cast(); 33 | if (json['userProfile'] != null) userProfile = UserEntity.fromJson(json['userProfile']); 34 | } 35 | 36 | Map toJson() { 37 | final Map data = new Map(); 38 | data['userID'] = this.userID; 39 | if (this.friendRemark != null) data['friendRemark'] = this.friendRemark; 40 | if (this.friendCustomInfo != null) data['friendCustomInfo'] = this.friendCustomInfo; 41 | return data; 42 | } 43 | 44 | @override 45 | bool operator ==(Object other) => identical(this, other) || other is FriendInfoEntity && runtimeType == other.runtimeType && userID == other.userID; 46 | 47 | @override 48 | int get hashCode => userID.hashCode; 49 | } 50 | -------------------------------------------------------------------------------- /lib/entity/friend_info_result_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/entity/friend_info_entity.dart'; 3 | import 'package:tencent_im_plugin/enums/friend_relation_type_enum.dart'; 4 | 5 | /// 好友信息结果实体 6 | class FriendInfoResultEntity { 7 | /// 结果码 8 | late int resultCode; 9 | 10 | /// 结果信息` 11 | String? resultInfo; 12 | 13 | /// 好友类型 14 | FriendRelationTypeEnum? relation; 15 | 16 | /// 好友信息 17 | FriendInfoEntity? friendInfo; 18 | 19 | FriendInfoResultEntity.fromJson(data) { 20 | Map json = 21 | data is Map ? data.cast() : jsonDecode(data); 22 | if (json['resultCode'] != null) resultCode = json['resultCode']; 23 | if (json['resultInfo'] != null) resultInfo = json['resultInfo']; 24 | if (json['relation'] != null) 25 | relation = FriendRelationTypeTool.getByInt(json['relation']); 26 | if (json['friendInfo'] != null) 27 | friendInfo = FriendInfoEntity.fromJson(json['friendInfo']); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/entity/friend_operation_result_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | /// 好友操作结果实体 4 | class FriendOperationResultEntity { 5 | /// 用户ID 6 | late String userID; 7 | 8 | /// 返回码 9 | late int resultCode; 10 | 11 | /// 返回信息 12 | String? resultInfo; 13 | 14 | FriendOperationResultEntity.fromJson(data) { 15 | Map json = 16 | data is Map ? data.cast() : jsonDecode(data); 17 | if (json['userID'] != null) userID = json['userID']; 18 | if (json['resultCode'] != null) resultCode = json['resultCode']; 19 | if (json['resultInfo'] != null) resultInfo = json['resultInfo']; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/entity/group_administrator_op_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/entity/group_member_entity.dart'; 3 | import 'package:tencent_im_plugin/list_util.dart'; 4 | 5 | /// 群管理员操作通知实体 6 | class GroupAdministratorOpEntity { 7 | /// 群ID 8 | late String groupID; 9 | 10 | /// 群成员列表 11 | List? changInfo; 12 | 13 | /// 操作用户 14 | GroupMemberEntity? opUser; 15 | 16 | GroupAdministratorOpEntity.fromJson(data) { 17 | Map json = 18 | data is Map ? data.cast() : jsonDecode(data); 19 | if (json['groupID'] != null) groupID = json['groupID']; 20 | if (json["changInfo"] != null) 21 | changInfo = 22 | ListUtil.generateOBJList(json['changInfo']); 23 | if (json["opUser"] != null) 24 | opUser = GroupMemberEntity.fromJson(json["opUser"]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/entity/group_application_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/enums/group_application_handler_result_enum.dart'; 3 | import 'package:tencent_im_plugin/enums/group_application_handler_status_enum.dart'; 4 | import 'package:tencent_im_plugin/enums/group_application_type_enum.dart'; 5 | 6 | /// 群申请实体 7 | class GroupApplicationEntity { 8 | /// 群ID 9 | late String groupID; 10 | 11 | /// 获取请求者 ID,请求加群:请求者,邀请加群:邀请人 12 | late String fromUser; 13 | 14 | /// 用户昵称 15 | String? fromUserNickName; 16 | 17 | /// 用户头像 18 | String? fromUserFaceUrl; 19 | 20 | /// 获取处理者 ID, 请求加群:0,邀请加群:被邀请人 21 | String? toUser; 22 | 23 | /// 获取群未决添加的时间,单位:秒 24 | late int addTime; 25 | 26 | /// 获取请求者添加的附加信息 27 | String? requestMsg; 28 | 29 | /// 获取处理者添加的附加信息,只有处理状态不为V2TIMGroupApplication#V2TIM_GROUP_APPLICATION_HANDLE_STATUS_UNHANDLED的时候有效 30 | String? handledMsg; 31 | 32 | /// 获取群未决请求类型 33 | late GroupApplicationTypeEnum type; 34 | 35 | /// 获取群未决处理状态 36 | GroupApplicationHandlerStatusEnum? handleStatus; 37 | 38 | /// 获取群未决处理操作类型,只有处理状态不为V2TIMGroupApplication#V2TIM_GROUP_APPLICATION_HANDLE_STATUS_UNHANDLED的时候有效 39 | GroupApplicationHandlerResultEnum? handleResult; 40 | 41 | GroupApplicationEntity.fromJson(data) { 42 | Map json = 43 | data is Map ? data.cast() : jsonDecode(data); 44 | if (json['groupID'] != null) groupID = json['groupID']; 45 | if (json['fromUser'] != null) fromUser = json['fromUser']; 46 | if (json['fromUserNickName'] != null) 47 | fromUserNickName = json['fromUserNickName']; 48 | if (json['fromUserFaceUrl'] != null) 49 | fromUserFaceUrl = json['fromUserFaceUrl']; 50 | if (json['toUser'] != null) toUser = json['toUser']; 51 | if (json['addTime'] != null) addTime = json['addTime']; 52 | if (json['requestMsg'] != null) requestMsg = json['requestMsg']; 53 | if (json['handledMsg'] != null) handledMsg = json['handledMsg']; 54 | if (json['type'] != null) 55 | type = GroupApplicationTypeTool.getByInt(json['type']); 56 | if (json['handleStatus'] != null) 57 | handleStatus = 58 | GroupApplicationHandlerStatusTool.getByInt(json['handleStatus']); 59 | if (json['handleResult'] != null) 60 | handleResult = 61 | GroupApplicationHandlerResultTool.getByInt(json['handleResult']); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/entity/group_application_processed_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/entity/group_member_entity.dart'; 3 | 4 | /// 群申请处理 5 | class GroupApplicationProcessedEntity { 6 | /// 群ID 7 | late String groupID; 8 | 9 | /// 操作用户 10 | GroupMemberEntity? opUser; 11 | 12 | /// 操作原因 13 | String? opReason; 14 | 15 | /// 是否同意加入 16 | bool? isAgreeJoin; 17 | 18 | GroupApplicationProcessedEntity.fromJson(data) { 19 | Map json = 20 | data is Map ? data.cast() : jsonDecode(data); 21 | if (json['groupID'] != null) groupID = json['groupID']; 22 | if (json['opReason'] != null) opReason = json['opReason']; 23 | if (json['isAgreeJoin'] != null) isAgreeJoin = json['isAgreeJoin']; 24 | if (json["opUser"] != null) 25 | opUser = GroupMemberEntity.fromJson(json['opUser']); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/entity/group_application_result_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/entity/group_application_entity.dart'; 3 | import 'package:tencent_im_plugin/list_util.dart'; 4 | 5 | /// 群申请列表结果实体 6 | class GroupApplicationResultEntity { 7 | /// 未读申请数量 8 | late int unreadCount; 9 | 10 | /// 加群的申请列表 11 | late List groupApplicationList; 12 | 13 | GroupApplicationResultEntity.fromJson(data) { 14 | Map json = 15 | data is Map ? data.cast() : jsonDecode(data); 16 | if (json['unreadCount'] != null) unreadCount = json['unreadCount']; 17 | if (json['groupApplicationList'] != null) 18 | groupApplicationList = ListUtil.generateOBJList( 19 | json['groupApplicationList']); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/entity/group_at_info_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/enums/group_at_type_enum.dart'; 3 | 4 | /// 群@信息实体 5 | class GroupAtInfoEntity { 6 | /// Seq序列号 7 | int? seq; 8 | 9 | /// @类型 10 | GroupAtTypeEnum? atType; 11 | 12 | GroupAtInfoEntity.fromJson(data) { 13 | Map json = 14 | data is Map ? data.cast() : jsonDecode(data); 15 | if (json['seq'] != null) seq = json["seq"]; 16 | if (json['atType'] != null) 17 | atType = GroupAtTypeTool.getByInt(json["atType"]); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/entity/group_attribute_changed_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | /// 群属性更新实体 4 | class GroupAttributeChangedEntity { 5 | /// 群ID 6 | late String groupID; 7 | 8 | /// 属性对象 9 | late Map attributes; 10 | 11 | GroupAttributeChangedEntity.fromJson(data) { 12 | Map json = 13 | data is Map ? data.cast() : jsonDecode(data); 14 | if (json['groupID'] != null) groupID = json['groupID']; 15 | if (json['attributes'] != null) 16 | attributes = (json["attributes"] as Map).cast(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/entity/group_changed_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/enums/group_info_changed_type_enum.dart'; 3 | import 'package:tencent_im_plugin/list_util.dart'; 4 | 5 | /// 群改变通知实体 6 | class GroupChangedEntity { 7 | /// 群ID 8 | late String groupID; 9 | 10 | /// 群改变信息实体 11 | late List changInfo; 12 | 13 | GroupChangedEntity.fromJson(data) { 14 | Map json = 15 | data is Map ? data.cast() : jsonDecode(data); 16 | if (json['groupID'] != null) groupID = json['groupID']; 17 | if (json["changInfo"] != null) 18 | changInfo = 19 | ListUtil.generateOBJList(json['changInfo']); 20 | } 21 | } 22 | 23 | /// 群改变实体 24 | class GroupChangedInfoEntity { 25 | /// 类型 26 | late GroupInfoChangedTypeEnum type; 27 | 28 | /// Key 29 | String? key; 30 | 31 | /// Value 32 | String? value; 33 | 34 | GroupChangedInfoEntity.fromJson(data) { 35 | Map json = 36 | data is Map ? data.cast() : jsonDecode(data); 37 | if (json['type'] != null) 38 | type = GroupInfoChangedTypeTool.getByInt(json['type']); 39 | if (json['key'] != null) key = json['key']; 40 | if (json['value'] != null) value = json['value']; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/entity/group_create_member_entity.dart: -------------------------------------------------------------------------------- 1 | import 'package:tencent_im_plugin/enums/group_member_role_enum.dart'; 2 | 3 | /// 群创建时需要传递的群成员实体 4 | class GroupCreateMemberEntity { 5 | /// 用户ID 6 | late String userID; 7 | 8 | /// 角色 9 | GroupMemberRoleEnum? role; 10 | 11 | GroupCreateMemberEntity({ 12 | required this.userID, 13 | this.role, 14 | }); 15 | 16 | Map toJson() { 17 | final Map data = new Map(); 18 | data['userID'] = this.userID; 19 | if (this.role != null) data['role'] = GroupMemberRoleTool.toInt(this.role!); 20 | return data; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/entity/group_dismissed_or_recycled_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/entity/group_member_entity.dart'; 3 | 4 | /// 群解散或被回收通知实体 5 | class GroupDismissedOrRecycledEntity { 6 | /// 群ID 7 | late String groupID; 8 | 9 | /// 操作用户 10 | GroupMemberEntity? opUser; 11 | 12 | GroupDismissedOrRecycledEntity.fromJson(data) { 13 | Map json = 14 | data is Map ? data.cast() : jsonDecode(data); 15 | if (json['groupID'] != null) groupID = json['groupID']; 16 | if (json["opUser"] != null) 17 | opUser = GroupMemberEntity.fromJson(json["opUser"]); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/entity/group_info_result_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/entity/group_info_entity.dart'; 3 | 4 | /// 群信息结果实体 5 | class GroupInfoResultEntity { 6 | /// 返回码,0代表成功,非零代表失败 7 | late int resultCode; 8 | 9 | /// 返回消息描述 10 | String? resultMessage; 11 | 12 | /// 群信息 13 | GroupInfoEntity? groupInfo; 14 | 15 | GroupInfoResultEntity.fromJson(data) { 16 | Map json = 17 | data is Map ? data.cast() : jsonDecode(data); 18 | if (json['resultCode'] != null) resultCode = json['resultCode']; 19 | if (json['resultMessage'] != null) resultMessage = json['resultMessage']; 20 | if (json['groupInfo'] != null) 21 | groupInfo = GroupInfoEntity.fromJson(json['groupInfo']); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/entity/group_member_changed_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/list_util.dart'; 3 | 4 | /// 群成员改变通知实体 5 | class GroupMemberChangedEntity { 6 | /// 群ID 7 | late String groupID; 8 | 9 | /// 群成员列表 10 | late List changInfo; 11 | 12 | GroupMemberChangedEntity.fromJson(data) { 13 | Map json = 14 | data is Map ? data.cast() : jsonDecode(data); 15 | if (json['groupID'] != null) groupID = json['groupID']; 16 | if (json["changInfo"] != null) 17 | changInfo = ListUtil.generateOBJList( 18 | json['changInfo']); 19 | } 20 | } 21 | 22 | /// 群成员改变信息实体 23 | class GroupMemberChangedInfoEntity { 24 | /// 用户ID 25 | late String userID; 26 | 27 | /// 禁言时长 28 | late int muteTime; 29 | 30 | GroupMemberChangedInfoEntity.fromJson(data) { 31 | Map json = 32 | data is Map ? data.cast() : jsonDecode(data); 33 | if (json['userID'] != null) userID = json['userID']; 34 | if (json['muteTime'] != null) muteTime = json['muteTime']; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/entity/group_member_enter_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/entity/group_member_entity.dart'; 3 | import 'package:tencent_im_plugin/list_util.dart'; 4 | 5 | /// 群成员加入通知实体 6 | class GroupMemberEnterEntity { 7 | /// 群ID 8 | late String groupID; 9 | 10 | /// 群成员列表 11 | late List memberList; 12 | 13 | GroupMemberEnterEntity.fromJson(data) { 14 | Map json = 15 | data is Map ? data.cast() : jsonDecode(data); 16 | if (json['groupID'] != null) groupID = json['groupID']; 17 | if (json["memberList"] != null) 18 | memberList = 19 | ListUtil.generateOBJList(json['memberList']); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/entity/group_member_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/enums/group_member_role_enum.dart'; 3 | 4 | /// 群成员实体 5 | class GroupMemberEntity { 6 | /// 用户ID 7 | late String userID; 8 | 9 | /// 用户昵称 10 | String? nickName; 11 | 12 | /// 好友备注 13 | String? friendRemark; 14 | 15 | /// 头像URL 16 | String? faceUrl; 17 | 18 | /// 角色 19 | GroupMemberRoleEnum? role; 20 | 21 | /// 群成员禁言结束时间戳 22 | int? muteUntil; 23 | 24 | /// 加入时间 25 | int? joinTime; 26 | 27 | /// 自定义字段 28 | Map? customInfo; 29 | 30 | /// 群成员名片 31 | String? nameCard; 32 | 33 | GroupMemberEntity({ 34 | required this.userID, 35 | this.customInfo, 36 | this.nameCard, 37 | }); 38 | 39 | GroupMemberEntity.fromJson(data) { 40 | Map json = data is Map ? data.cast() : jsonDecode(data); 41 | if (json['userID'] != null) userID = json['userID']; 42 | if (json['nickName'] != null) nickName = json['nickName']; 43 | if (json['friendRemark'] != null) friendRemark = json['friendRemark']; 44 | if (json['faceUrl'] != null) faceUrl = json['faceUrl']; 45 | if (json['role'] != null) role = GroupMemberRoleTool.getByInt(json['role']); 46 | if (json['muteUntil'] != null) muteUntil = json['muteUntil']; 47 | if (json['joinTime'] != null) joinTime = json['joinTime']; 48 | if (json['customInfo'] != null) customInfo = (json['customInfo'] as Map).cast(); 49 | if (json['nameCard'] != null) nameCard = json['nameCard']; 50 | } 51 | 52 | Map toJson() { 53 | final Map data = new Map(); 54 | data['userID'] = this.userID; 55 | if (this.customInfo != null) data['customInfo'] = this.customInfo; 56 | if (this.nameCard != null) data['nameCard'] = this.nameCard; 57 | return data; 58 | } 59 | 60 | @override 61 | bool operator ==(Object other) => identical(this, other) || other is GroupMemberEntity && runtimeType == other.runtimeType && userID == other.userID; 62 | 63 | @override 64 | int get hashCode => userID.hashCode; 65 | } 66 | -------------------------------------------------------------------------------- /lib/entity/group_member_info_result_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/entity/group_member_entity.dart'; 3 | import 'package:tencent_im_plugin/list_util.dart'; 4 | 5 | /// 群成员信息结果实体 6 | class GroupMemberInfoResultEntity { 7 | /// 获取分页拉取的 seq。如果为 0 表示拉取结束。 8 | late int nextSeq; 9 | 10 | /// 群信息 11 | List? memberInfoList; 12 | 13 | GroupMemberInfoResultEntity.fromJson(data) { 14 | Map json = 15 | data is Map ? data.cast() : jsonDecode(data); 16 | if (json['nextSeq'] != null) nextSeq = json['nextSeq']; 17 | if (json['memberInfoList'] != null) 18 | memberInfoList = 19 | ListUtil.generateOBJList(json['memberInfoList']); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/entity/group_member_invited_or_kicked_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/entity/group_member_entity.dart'; 3 | import 'package:tencent_im_plugin/list_util.dart'; 4 | 5 | /// 群成员邀请或踢出通知实体 6 | class GroupMemberInvitedOrKickedEntity { 7 | /// 群ID 8 | late String groupID; 9 | 10 | /// 群成员列表信息 11 | List? memberList; 12 | 13 | /// 操作用户 14 | GroupMemberEntity? opUser; 15 | 16 | GroupMemberInvitedOrKickedEntity.fromJson(data) { 17 | Map json = 18 | data is Map ? data.cast() : jsonDecode(data); 19 | if (json['groupID'] != null) groupID = json['groupID']; 20 | if (json["memberList"] != null) 21 | memberList = 22 | ListUtil.generateOBJList(json['memberList']); 23 | if (json["opUser"] != null) 24 | opUser = GroupMemberEntity.fromJson(json["opUser"]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/entity/group_member_leave_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/entity/group_member_entity.dart'; 3 | 4 | /// 群成员离开通知实体 5 | class GroupMemberLeaveEntity { 6 | /// 群ID 7 | late String groupID; 8 | 9 | /// 群成员信息 10 | late GroupMemberEntity member; 11 | 12 | GroupMemberLeaveEntity.fromJson(data) { 13 | Map json = 14 | data is Map ? data.cast() : jsonDecode(data); 15 | if (json['groupID'] != null) groupID = json['groupID']; 16 | if (json["member"] != null) 17 | member = GroupMemberEntity.fromJson(json["member"]); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/entity/group_member_operation_result_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/enums/operation_result_enum.dart'; 3 | 4 | /// 群成员操作结果实体 5 | class GroupMemberOperationResultEntity { 6 | /// 操作结果 7 | late OperationResultEnum result; 8 | 9 | /// 群成员ID 10 | late String memberID; 11 | 12 | GroupMemberOperationResultEntity.fromJson(data) { 13 | Map json = 14 | data is Map ? data.cast() : jsonDecode(data); 15 | if (json['result'] != null) 16 | result = OperationResultTool.getByInt(json['result']); 17 | if (json['memberID'] != null) memberID = json['memberID']; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/entity/group_receive_join_application_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/entity/group_member_entity.dart'; 3 | 4 | /// 群加入申请实体 5 | class GroupReceiveJoinApplicationEntity { 6 | /// 群ID 7 | late String groupID; 8 | 9 | /// 群成员 10 | GroupMemberEntity? member; 11 | 12 | /// 操作原因 13 | String? opReason; 14 | 15 | GroupReceiveJoinApplicationEntity.fromJson(data) { 16 | Map json = 17 | data is Map ? data.cast() : jsonDecode(data); 18 | if (json['groupID'] != null) groupID = json['groupID']; 19 | if (json['opReason'] != null) opReason = json['opReason']; 20 | if (json["member"] != null) 21 | member = GroupMemberEntity.fromJson(json['member']); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/entity/group_receive_rest_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | /// 群接收到REST自定义信息通知实体 4 | class GroupReceiveRESTEntity { 5 | /// 群ID 6 | late String groupID; 7 | 8 | /// 自定义数据 9 | String? customData; 10 | 11 | GroupReceiveRESTEntity.fromJson(data) { 12 | Map json = 13 | data is Map ? data.cast() : jsonDecode(data); 14 | if (json['groupID'] != null) groupID = json['groupID']; 15 | if (json['customData'] != null) customData = json['customData']; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/entity/message_receipt_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | /// 消息回执实体 4 | class MessageReceiptEntity { 5 | /// 用户ID 6 | late String userID; 7 | 8 | /// 时间 9 | int? timestamp; 10 | 11 | MessageReceiptEntity.fromJson(data) { 12 | Map json = 13 | data is Map ? data.cast() : jsonDecode(data); 14 | if (json['userID'] != null) userID = json["userID"]; 15 | if (json['timestamp'] != null) timestamp = json["timestamp"]; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/entity/message_send_fail_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | /// 消息发送失败实体 4 | class MessageSendFailEntity { 5 | /// 消息ID 6 | late String msgId; 7 | 8 | /// 错误码 9 | late int code; 10 | 11 | /// 错误描述 12 | String? desc; 13 | 14 | MessageSendFailEntity.fromJson(data) { 15 | Map json = 16 | data is Map ? data.cast() : jsonDecode(data); 17 | if (json['msgId'] != null) msgId = json["msgId"]; 18 | if (json['code'] != null) code = json["code"]; 19 | if (json['desc'] != null) desc = json["desc"]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/entity/message_send_progress_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | /// 消息发送进度实体 4 | class MessageSendProgressEntity { 5 | /// 消息ID 6 | late String msgId; 7 | 8 | /// 发送进度 9 | late int progress; 10 | 11 | MessageSendProgressEntity.fromJson(data) { 12 | Map json = 13 | data is Map ? data.cast() : jsonDecode(data); 14 | if (json['msgId'] != null) msgId = json["msgId"]; 15 | if (json['progress'] != null) progress = json["progress"]; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/entity/offline_push_info_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | /// 离线推送信息实体 4 | class OfflinePushInfoEntity { 5 | /// 通知栏标题 6 | String? title; 7 | 8 | /// 通知栏内容 9 | String? desc; 10 | 11 | /// 通知栏透传信息 12 | String? ext; 13 | 14 | /// 离线推送声音设置(仅对 iOS 生效)。 当 sound = IOS_OFFLINE_PUSH_NO_SOUND,表示接收时不会播放声音。 如果要自定义 iOSSound,需要先把语音文件链接进 Xcode 工程,然后把语音文件名(带后缀)设置给 iOSSound。 15 | String? iOSSound; 16 | 17 | /// 离线推送忽略 badge 计数(仅对 iOS 生效), 如果设置为 true,在 iOS 接收端,这条消息不会使 APP 的应用图标未读计数增加。 18 | bool? ignoreIOSBadge; 19 | 20 | /// 离线推送设置 OPPO 手机 8.0 系统及以上的渠道 ID。 21 | String? androidOPPOChannelID; 22 | 23 | /// 获取是否关闭离线推送状态。 24 | bool? disablePush; 25 | 26 | OfflinePushInfoEntity({ 27 | this.title, 28 | this.desc, 29 | this.ext, 30 | this.iOSSound, 31 | this.ignoreIOSBadge, 32 | this.androidOPPOChannelID, 33 | this.disablePush, 34 | }); 35 | 36 | OfflinePushInfoEntity.fromJson(data) { 37 | Map json = 38 | data is Map ? data.cast() : jsonDecode(data); 39 | if (json['title'] != null) title = json["title"]; 40 | if (json['desc'] != null) desc = json["desc"]; 41 | if (json['ext'] != null) ext = json["ext"]; 42 | if (json['iOSSound'] != null) iOSSound = json["iOSSound"]; 43 | if (json['ignoreIOSBadge'] != null) ignoreIOSBadge = json["ignoreIOSBadge"]; 44 | if (json['androidOPPOChannelID'] != null) 45 | androidOPPOChannelID = json["androidOPPOChannelID"]; 46 | if (json['disablePush'] != null) disablePush = json["disablePush"]; 47 | } 48 | 49 | Map toJson() { 50 | final Map data = new Map(); 51 | if (this.title != null) data['title'] = this.title; 52 | if (this.desc != null) data['desc'] = this.desc; 53 | if (this.ext != null) data['ext'] = this.ext; 54 | if (this.iOSSound != null) data['iOSSound'] = this.iOSSound; 55 | if (this.ignoreIOSBadge != null) 56 | data['ignoreIOSBadge'] = this.ignoreIOSBadge; 57 | if (this.androidOPPOChannelID != null) 58 | data['androidOPPOChannelID'] = this.androidOPPOChannelID; 59 | return data; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/entity/signaling_common_entity.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | /// 信令通用实体 4 | class SignalingCommonEntity { 5 | /// 邀请ID 6 | late String inviteID; 7 | 8 | /// 邀请人 9 | String? inviter; 10 | 11 | /// 群ID 12 | String? groupID; 13 | 14 | /// 受邀人,一般是拒绝/接受时此内容才会有值 15 | String? invitee; 16 | 17 | /// 被邀请人列表 18 | List? inviteeList; 19 | 20 | /// 消息内容 21 | String? data; 22 | 23 | SignalingCommonEntity.fromJson(data) { 24 | Map json = data is Map ? data.cast() : jsonDecode(data); 25 | if (json['inviteID'] != null) inviteID = json["inviteID"]; 26 | if (json['inviter'] != null) inviter = json["inviter"]; 27 | if (json['groupID'] != null) groupID = json["groupID"]; 28 | if (json['invitee'] != null) invitee = json["invitee"]; 29 | if (json['inviteeList'] != null) inviteeList = json["inviteeList"]?.cast(); 30 | if (json['data'] != null) this.data = json["data"]; 31 | } 32 | 33 | @override 34 | bool operator ==(Object other) => identical(this, other) || other is SignalingCommonEntity && runtimeType == other.runtimeType && inviteID == other.inviteID; 35 | 36 | @override 37 | int get hashCode => inviteID.hashCode; 38 | } 39 | -------------------------------------------------------------------------------- /lib/enums/conversation_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// 会话类型枚举 2 | enum ConversationTypeEnum { 3 | /// 非法类型 4 | Invalid, 5 | 6 | /// 单聊 7 | C2C, 8 | 9 | /// 群聊 10 | Group, 11 | } 12 | 13 | class ConversationTypeTool { 14 | /// 根据Int类型值获得枚举 15 | /// [index] Int常量 16 | /// [Return] 枚举对象 17 | static ConversationTypeEnum getByInt(int index) => 18 | ConversationTypeEnum.values[index]; 19 | 20 | /// 将枚举转换为整型 21 | static int toInt(ConversationTypeEnum level) => level.index; 22 | } 23 | -------------------------------------------------------------------------------- /lib/enums/download_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// 下载类型枚举 2 | enum DownloadTypeEnum { 3 | /// 语音 4 | Sound, 5 | 6 | /// 视频 7 | Video, 8 | 9 | /// 视频缩略图 10 | VideoThumbnail, 11 | 12 | /// 文件对象 13 | File, 14 | } 15 | 16 | class DownloadTypeTool { 17 | /// 根据Int类型值获得枚举 18 | /// [index] Int常量 19 | /// [Return] 枚举对象 20 | static DownloadTypeEnum getByInt(int index) => DownloadTypeEnum.values[index]; 21 | 22 | /// 将枚举转换为整型 23 | static int toInt(DownloadTypeEnum level) => level.index; 24 | } 25 | -------------------------------------------------------------------------------- /lib/enums/friend_application_agree_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// 好友申请接收时类型枚举 2 | enum FriendApplicationAgreeTypeEnum { 3 | // 同意加好友(建立单向好友) 4 | Agree, 5 | // 同意加好友并加对方为好友(建立双向好友) 6 | AgreeAndAdd, 7 | } 8 | 9 | /// 枚举工具 10 | class FriendApplicationAgreeTypeTool { 11 | /// 根据Int类型值获得枚举 12 | /// [index] Int常量 13 | /// [Return] 枚举对象 14 | static FriendApplicationAgreeTypeEnum getByInt(int index) => 15 | FriendApplicationAgreeTypeEnum.values[index]; 16 | 17 | /// 将枚举转换为整型 18 | static int toInt(FriendApplicationAgreeTypeEnum level) => level.index; 19 | } 20 | -------------------------------------------------------------------------------- /lib/enums/friend_application_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// 好友申请类型枚举 2 | enum FriendApplicationTypeEnum { 3 | // 别人发给我的加好友请求 4 | ComeIn, 5 | // 我发给别人的加好友请求 6 | SendOut, 7 | // 别人发给我的和我发给别人的加好友请求。仅在拉取时有效。 8 | Both, 9 | } 10 | 11 | /// 枚举工具 12 | class FriendApplicationTypeTool { 13 | /// 根据Int类型值获得枚举 14 | /// [index] Int常量 15 | /// [Return] 枚举对象 16 | static FriendApplicationTypeEnum getByInt(int index) => 17 | FriendApplicationTypeEnum.values[index - 1]; 18 | 19 | /// 将枚举转换为整型 20 | static int toInt(FriendApplicationTypeEnum level) => level.index + 1; 21 | } 22 | -------------------------------------------------------------------------------- /lib/enums/friend_relation_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// 好友关系枚举 2 | enum FriendRelationTypeEnum { 3 | // 不是好友 4 | None, 5 | // 在我的好友列表 6 | MyFriendList, 7 | // 我在对方好友列表 8 | OtherFriendList, 9 | // 互为好友 10 | BothWay, 11 | } 12 | 13 | /// 枚举工具 14 | class FriendRelationTypeTool { 15 | /// 根据Int类型值获得枚举 16 | /// [index] Int常量 17 | /// [Return] 枚举对象 18 | static FriendRelationTypeEnum getByInt(int index) => 19 | FriendRelationTypeEnum.values[index]; 20 | 21 | /// 将枚举转换为整型 22 | static int toInt(FriendRelationTypeEnum level) => level.index; 23 | } 24 | -------------------------------------------------------------------------------- /lib/enums/friend_status_enum.dart: -------------------------------------------------------------------------------- 1 | /// 好友状态枚举 2 | enum FriendStatusEnum { 3 | /// 操作成功 4 | SUCC, 5 | 6 | /// 请求参数错误,请根据错误描述检查请求是否正确 7 | PARAM_INVALID, 8 | 9 | /// 加好友、响应好友时有效:自己的好友数已达系统上限 10 | SELF_FRIEND_FULL, 11 | 12 | /// 加好友、响应好友时有效:对方的好友数已达系统上限 13 | THEIR_FRIEND_FULL, 14 | 15 | /// 加好友时有效:被加好友在自己的黑名单中 16 | IN_SELF_BLACK_LIST, 17 | 18 | /// 加好友时有效:被加好友设置为禁止加好友 19 | FRIEND_SIDE_FORBID_ADD, 20 | 21 | /// 加好友时有效:已被被添加好友设置为黑名单 22 | IN_OTHER_SIDE_BLACK_LIST, 23 | 24 | /// 加好友时有效:等待好友审核同意 25 | PENDING 26 | } 27 | 28 | /// 枚举工具 29 | class FriendStatusEnumTool { 30 | /// 根据数标获得枚举 31 | static FriendStatusEnum? getEnumByIndex(index) { 32 | switch (index) { 33 | case 0: 34 | return FriendStatusEnum.SUCC; 35 | case 30001: 36 | return FriendStatusEnum.PARAM_INVALID; 37 | case 30010: 38 | return FriendStatusEnum.SELF_FRIEND_FULL; 39 | case 30014: 40 | return FriendStatusEnum.THEIR_FRIEND_FULL; 41 | case 30515: 42 | return FriendStatusEnum.IN_SELF_BLACK_LIST; 43 | case 30516: 44 | return FriendStatusEnum.FRIEND_SIDE_FORBID_ADD; 45 | case 30525: 46 | return FriendStatusEnum.IN_OTHER_SIDE_BLACK_LIST; 47 | case 30539: 48 | return FriendStatusEnum.PENDING; 49 | default: 50 | return null; 51 | } 52 | } 53 | 54 | /// 根据枚举获得数标 55 | static int? getIndexByEnum(e) { 56 | switch (e) { 57 | case FriendStatusEnum.SUCC: 58 | return 0; 59 | case FriendStatusEnum.PARAM_INVALID: 60 | return 30001; 61 | case FriendStatusEnum.SELF_FRIEND_FULL: 62 | return 30010; 63 | case FriendStatusEnum.THEIR_FRIEND_FULL: 64 | return 30514; 65 | case FriendStatusEnum.IN_SELF_BLACK_LIST: 66 | return 30515; 67 | case FriendStatusEnum.FRIEND_SIDE_FORBID_ADD: 68 | return 30516; 69 | case FriendStatusEnum.IN_OTHER_SIDE_BLACK_LIST: 70 | return 30525; 71 | case FriendStatusEnum.PENDING: 72 | return 30539; 73 | default: 74 | return null; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /lib/enums/friend_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// 好友类型枚举 2 | enum FriendTypeEnum { 3 | // 单项加好友 4 | Single, 5 | // 双向加好友 6 | Both, 7 | } 8 | 9 | /// 枚举工具 10 | class FriendTypeTool { 11 | /// 根据Int类型值获得枚举 12 | /// [index] Int常量 13 | /// [Return] 枚举对象 14 | static FriendTypeEnum getByInt(int index) => FriendTypeEnum.values[index - 1]; 15 | 16 | /// 将枚举转换为整型 17 | static int toInt(FriendTypeEnum level) => level.index + 1; 18 | } 19 | -------------------------------------------------------------------------------- /lib/enums/get_message_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// 获得消息类型枚举 2 | enum GetMessageTypeEnum { 3 | // 云端更老的消息 4 | GetCloudOlderMsg, 5 | // 云端更新的消息 6 | GetCloudNewerMsg, 7 | // 本地更老的消息 8 | GetLocalOlderMsg, 9 | // 本地更新的消息 10 | GetLocalNewerMsg, 11 | } 12 | 13 | /// 枚举工具 14 | class GetMessageTypeTool { 15 | /// 根据Int类型值获得枚举 16 | /// [index] Int常量 17 | /// [Return] 枚举对象 18 | static GetMessageTypeEnum getByInt(int index) => 19 | GetMessageTypeEnum.values[index - 1]; 20 | 21 | /// 将枚举转换为整型 22 | static int toInt(GetMessageTypeEnum level) => level.index + 1; 23 | } 24 | -------------------------------------------------------------------------------- /lib/enums/group_add_opt_enum.dart: -------------------------------------------------------------------------------- 1 | /// 加群选项 2 | enum GroupAddOptEnum { 3 | /// 禁止加群 4 | Forbid, 5 | 6 | /// 需要管理员审批 7 | Auth, 8 | 9 | /// 自由加入 10 | Any, 11 | } 12 | 13 | class GroupAddOptTool { 14 | /// 根据Int类型值获得枚举 15 | /// [index] Int常量 16 | /// [Return] 枚举对象 17 | static GroupAddOptEnum getByInt(int index) => GroupAddOptEnum.values[index]; 18 | 19 | /// 将枚举转换为整型 20 | static int toInt(GroupAddOptEnum level) => level.index; 21 | } 22 | -------------------------------------------------------------------------------- /lib/enums/group_application_handler_result_enum.dart: -------------------------------------------------------------------------------- 1 | /// 群申请处理结果枚举 2 | enum GroupApplicationHandlerResultEnum { 3 | /// 拒绝 4 | Refuse, 5 | 6 | /// 接收 7 | Agree, 8 | } 9 | 10 | class GroupApplicationHandlerResultTool { 11 | /// 根据Int类型值获得枚举 12 | /// [index] Int常量 13 | /// [Return] 枚举对象 14 | static GroupApplicationHandlerResultEnum getByInt(int index) => 15 | GroupApplicationHandlerResultEnum.values[index]; 16 | 17 | /// 将枚举转换为整型 18 | static int toInt(GroupApplicationHandlerResultEnum level) => level.index; 19 | } 20 | -------------------------------------------------------------------------------- /lib/enums/group_application_handler_status_enum.dart: -------------------------------------------------------------------------------- 1 | /// 群申请处理状态枚举 2 | enum GroupApplicationHandlerStatusEnum { 3 | /// 未处理 4 | Unhandled, 5 | 6 | /// 其他人处理 7 | ByOther, 8 | 9 | /// 自己已处理 10 | BySelf, 11 | } 12 | 13 | class GroupApplicationHandlerStatusTool { 14 | /// 根据Int类型值获得枚举 15 | /// [index] Int常量 16 | /// [Return] 枚举对象 17 | static GroupApplicationHandlerStatusEnum getByInt(int index) => 18 | GroupApplicationHandlerStatusEnum.values[index]; 19 | 20 | /// 将枚举转换为整型 21 | static int toInt(GroupApplicationHandlerStatusEnum level) => level.index; 22 | } 23 | -------------------------------------------------------------------------------- /lib/enums/group_application_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// 群申请类型枚举 2 | enum GroupApplicationTypeEnum { 3 | /// 主动申请 4 | Join, 5 | 6 | /// 被邀请 7 | Invite, 8 | } 9 | 10 | class GroupApplicationTypeTool { 11 | /// 根据Int类型值获得枚举 12 | /// [index] Int常量 13 | /// [Return] 枚举对象 14 | static GroupApplicationTypeEnum getByInt(int index) => 15 | GroupApplicationTypeEnum.values[index]; 16 | 17 | /// 将枚举转换为整型 18 | static int toInt(GroupApplicationTypeEnum level) => level.index; 19 | } 20 | -------------------------------------------------------------------------------- /lib/enums/group_at_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// 群@类型枚举 2 | enum GroupAtTypeEnum { 3 | /// 非法类型 4 | Unknown, 5 | 6 | /// @我 7 | AtMe, 8 | 9 | /// @所有人 10 | AtAll, 11 | 12 | /// @群里所有人,并单独@我 13 | AtAllAtMe 14 | } 15 | 16 | class GroupAtTypeTool { 17 | /// 根据Int类型值获得枚举 18 | /// [index] Int常量 19 | /// [Return] 枚举对象 20 | static GroupAtTypeEnum getByInt(int index) => GroupAtTypeEnum.values[index]; 21 | 22 | /// 将枚举转换为整型 23 | static int toInt(GroupAtTypeEnum level) => level.index; 24 | } 25 | -------------------------------------------------------------------------------- /lib/enums/group_info_changed_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// 群信息改变类型枚举 2 | enum GroupInfoChangedTypeEnum { 3 | /// 非法值 4 | Invalid, 5 | 6 | /// 群名 7 | Name, 8 | 9 | /// 群简介 10 | Introduction, 11 | 12 | /// 群公告 13 | Notification, 14 | 15 | /// 群头像 16 | FaceUrl, 17 | 18 | /// 群主 19 | Owner, 20 | 21 | /// 自定义字段 22 | Custom, 23 | } 24 | 25 | class GroupInfoChangedTypeTool { 26 | /// 根据Int类型值获得枚举 27 | /// [index] Int常量 28 | /// [Return] 枚举对象 29 | static GroupInfoChangedTypeEnum getByInt(int index) => 30 | GroupInfoChangedTypeEnum.values[index]; 31 | 32 | /// 将枚举转换为整型 33 | static int toInt(GroupInfoChangedTypeEnum level) => level.index; 34 | } 35 | -------------------------------------------------------------------------------- /lib/enums/group_member_filter_enum.dart: -------------------------------------------------------------------------------- 1 | /// 群成员过滤枚举 2 | enum GroupMemberFilterEnum { 3 | /// 所有类型 4 | All, 5 | 6 | /// 群主 7 | Owner, 8 | 9 | /// 群管理员 10 | Admin, 11 | 12 | /// 普通群成员 13 | Common, 14 | } 15 | 16 | class GroupMemberFilterTool { 17 | /// 根据Int类型值获得枚举 18 | /// [index] Int常量 19 | /// [Return] 枚举对象 20 | static GroupMemberFilterEnum getByInt(int index) { 21 | switch (index) { 22 | case 0: 23 | return GroupMemberFilterEnum.All; 24 | case 1: 25 | return GroupMemberFilterEnum.Owner; 26 | case 2: 27 | return GroupMemberFilterEnum.Admin; 28 | case 4: 29 | return GroupMemberFilterEnum.Common; 30 | } 31 | throw ArgumentError("参数异常"); 32 | } 33 | 34 | /// 将枚举转换为整型 35 | static int toInt(GroupMemberFilterEnum role) { 36 | switch (role) { 37 | case GroupMemberFilterEnum.All: 38 | return 0; 39 | case GroupMemberFilterEnum.Owner: 40 | return 1; 41 | case GroupMemberFilterEnum.Admin: 42 | return 2; 43 | case GroupMemberFilterEnum.Common: 44 | return 4; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/enums/group_member_role_enum.dart: -------------------------------------------------------------------------------- 1 | /// 群成员角色枚举 2 | enum GroupMemberRoleEnum { 3 | /// 未定义 4 | Undefined, 5 | 6 | /// 群成员 7 | Member, 8 | 9 | /// 群管理员 10 | Admin, 11 | 12 | /// 群主 13 | Owner, 14 | } 15 | 16 | class GroupMemberRoleTool { 17 | /// 根据Int类型值获得枚举 18 | /// [index] Int常量 19 | /// [Return] 枚举对象 20 | static GroupMemberRoleEnum getByInt(int index) { 21 | switch (index) { 22 | case 0: 23 | return GroupMemberRoleEnum.Undefined; 24 | case 200: 25 | return GroupMemberRoleEnum.Member; 26 | case 300: 27 | return GroupMemberRoleEnum.Admin; 28 | case 400: 29 | return GroupMemberRoleEnum.Owner; 30 | } 31 | throw ArgumentError("参数异常"); 32 | } 33 | 34 | /// 将枚举转换为整型 35 | static int toInt(GroupMemberRoleEnum role) { 36 | switch (role) { 37 | case GroupMemberRoleEnum.Undefined: 38 | return 0; 39 | case GroupMemberRoleEnum.Member: 40 | return 200; 41 | case GroupMemberRoleEnum.Admin: 42 | return 300; 43 | case GroupMemberRoleEnum.Owner: 44 | return 400; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/enums/group_system_type.dart: -------------------------------------------------------------------------------- 1 | /// 群系统提示类型 2 | enum GroupSystemType { 3 | INVALID, 4 | ADD_GROUP_REQUEST_TYPE, 5 | ADD_GROUP_ACCEPT_TYPE, 6 | ADD_GROUP_REFUSE_TYPE, 7 | KICK_OFF_FROM_GROUP_TYPE, 8 | DELETE_GROUP_TYPE, 9 | CREATE_GROUP_TYPE, 10 | INVITED_TO_GROUP_TYPE, 11 | QUIT_GROUP_TYPE, 12 | GRANT_ADMIN_TYPE, 13 | CANCEL_ADMIN_TYPE, 14 | REVOKE_GROUP_TYPE, 15 | INVITE_TO_GROUP_REQUEST_TYPE, 16 | INVITATION_ACCEPTED_TYPE, 17 | INVITATION_REFUSED_TYPE, 18 | CUSTOM_INFO, 19 | } 20 | 21 | class GroupSystemTypeTool { 22 | /// 根据int值获得枚举类型 23 | static GroupSystemType? intToGroupSystemType(int value) { 24 | switch (value) { 25 | case 0: 26 | return GroupSystemType.INVALID; 27 | case 1: 28 | return GroupSystemType.ADD_GROUP_REQUEST_TYPE; 29 | case 2: 30 | return GroupSystemType.ADD_GROUP_ACCEPT_TYPE; 31 | case 3: 32 | return GroupSystemType.ADD_GROUP_REFUSE_TYPE; 33 | case 4: 34 | return GroupSystemType.KICK_OFF_FROM_GROUP_TYPE; 35 | case 5: 36 | return GroupSystemType.DELETE_GROUP_TYPE; 37 | case 6: 38 | return GroupSystemType.CREATE_GROUP_TYPE; 39 | case 7: 40 | return GroupSystemType.INVITED_TO_GROUP_TYPE; 41 | case 8: 42 | return GroupSystemType.QUIT_GROUP_TYPE; 43 | case 9: 44 | return GroupSystemType.GRANT_ADMIN_TYPE; 45 | case 10: 46 | return GroupSystemType.CANCEL_ADMIN_TYPE; 47 | case 11: 48 | return GroupSystemType.REVOKE_GROUP_TYPE; 49 | case 12: 50 | return GroupSystemType.INVITE_TO_GROUP_REQUEST_TYPE; 51 | case 13: 52 | return GroupSystemType.INVITATION_ACCEPTED_TYPE; 53 | case 14: 54 | return GroupSystemType.INVITATION_REFUSED_TYPE; 55 | case 255: 56 | return GroupSystemType.CUSTOM_INFO; 57 | } 58 | return null; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /lib/enums/group_tips_group_info_type.dart: -------------------------------------------------------------------------------- 1 | /// 群资料变更消息类型 2 | enum GroupTipsGroupInfoType { 3 | /// 非法值 4 | Invalid, 5 | 6 | /// 修改群名称 7 | ModifyName, 8 | 9 | /// 修改群简介 10 | ModifyIntroduction, 11 | 12 | /// 修改群公告 13 | ModifyNotification, 14 | 15 | /// 修改群头像URL 16 | ModifyFaceUrl, 17 | 18 | /// 修改群主 19 | ModifyOwner, 20 | 21 | /// 修改群自定义字段 22 | ModifyCustom, 23 | } 24 | -------------------------------------------------------------------------------- /lib/enums/group_tips_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// 群组事件通知类型 2 | enum GroupTipsTypeEnum { 3 | /// 非法 4 | Invalid, 5 | 6 | /// 主动入群(memberList 加入群组,非 Work 群有效) 7 | Join, 8 | 9 | /// 被邀请入群(opMember 邀请 memberList 入群,Work 群有效) 10 | Invite, 11 | 12 | /// 退出群组 13 | Quit, 14 | 15 | /// 踢出群 (opMember 把 memberList 踢出群组) 16 | Kicked, 17 | 18 | /// 设置管理员 (opMember 把 memberList 设置为管理员) 19 | Admin, 20 | 21 | /// 取消管理员 (opMember 取消 memberList 管理员身份) 22 | CancelAdmin, 23 | 24 | /// 群资料变更 (opMember 修改群资料:groupName & introduction & notification & faceUrl & owner & custom) 25 | GroupInfoChange, 26 | 27 | /// 群成员资料变更 (opMember 修改群成员资料:muteTime) 28 | MemberInfoChange, 29 | } 30 | 31 | /// 枚举工具 32 | class GroupTipsTypeTool { 33 | /// 根据Int类型值获得枚举 34 | /// [index] Int常量 35 | /// [Return] 枚举对象 36 | static GroupTipsTypeEnum getByInt(int index) => 37 | GroupTipsTypeEnum.values[index]; 38 | 39 | /// 将枚举转换为整型 40 | static int toInt(GroupTipsTypeEnum data) => data.index; 41 | } 42 | -------------------------------------------------------------------------------- /lib/enums/group_type_enum.dart: -------------------------------------------------------------------------------- 1 | import 'package:tencent_im_plugin/utils/enum_util.dart'; 2 | 3 | /// 群类型 4 | enum GroupTypeEnum { 5 | /// 工作群 6 | Work, 7 | 8 | /// 公开群 9 | Public, 10 | 11 | /// 会议群 12 | Meeting, 13 | 14 | /// 直播群 15 | AVChatRoom, 16 | } 17 | 18 | class GroupTypeTool { 19 | /// 根据字符串类型值获得枚举 20 | /// [type] 字符串常量 21 | /// [Return] 枚举对象 22 | static GroupTypeEnum? getByString(String type) => 23 | EnumUtil.nameOf(GroupTypeEnum.values, type); 24 | 25 | /// 将枚举转换为整型 26 | static String toTypeString(GroupTypeEnum type) => EnumUtil.getEnumName(type); 27 | } 28 | -------------------------------------------------------------------------------- /lib/enums/image_type_enum.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | /// 图片类型 4 | /// 由于腾讯云 Android 和 IOS 的 V2TIMImageType 对象不相同,所以需要单独解析 5 | /// Android 的下标为 0、1、2,IOS的为 1、2、4 6 | enum ImageTypeEnum { 7 | /// 原图 8 | Original, 9 | 10 | /// 缩略图 11 | Thumb, 12 | 13 | /// 大图 14 | Large, 15 | } 16 | 17 | class ImageTypeTool { 18 | /// 根据Int类型值获得枚举 19 | /// [index] Int常量 20 | /// [Return] 枚举对象 21 | static ImageTypeEnum getByInt(int /*!*/ index) { 22 | // 单独解析Android 23 | if (Platform.isAndroid) { 24 | return ImageTypeEnum.values[index]; 25 | } 26 | 27 | switch (index) { 28 | case 1: 29 | return ImageTypeEnum.Original; 30 | case 2: 31 | return ImageTypeEnum.Thumb; 32 | case 4: 33 | return ImageTypeEnum.Large; 34 | } 35 | throw ArgumentError("参数异常"); 36 | } 37 | 38 | /// 将枚举转换为整型 39 | static int toInt(ImageTypeEnum data) { 40 | // 单独解析Android 41 | if (Platform.isAndroid) { 42 | return data.index; 43 | } 44 | 45 | switch (data) { 46 | case ImageTypeEnum.Original: 47 | return 1; 48 | case ImageTypeEnum.Thumb: 49 | return 2; 50 | case ImageTypeEnum.Large: 51 | return 4; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /lib/enums/log_print_level.dart: -------------------------------------------------------------------------------- 1 | /// 日志打印等级 2 | enum LogPrintLevel { 3 | none, 4 | debug, 5 | info, 6 | warn, 7 | error, 8 | } 9 | 10 | class LogPrintLevelTool { 11 | /// 将枚举转换为整型 12 | static int? toInt(LogPrintLevel level) { 13 | switch (level) { 14 | case LogPrintLevel.none: 15 | return 0; 16 | case LogPrintLevel.debug: 17 | return 3; 18 | case LogPrintLevel.info: 19 | return 4; 20 | case LogPrintLevel.warn: 21 | return 5; 22 | case LogPrintLevel.error: 23 | return 6; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/enums/login_status_enum.dart: -------------------------------------------------------------------------------- 1 | /// 登录状态枚举 2 | enum LoginStatusEnum { 3 | // 已登录 4 | Logined, 5 | // 登录中 6 | Logining, 7 | // 未登录 8 | Logout, 9 | } 10 | 11 | class LoginStatusTool { 12 | /// 根据Int类型值获得枚举 13 | /// [index] Int常量 14 | /// [Return] 枚举对象 15 | static LoginStatusEnum getByInt(int index) => 16 | LoginStatusEnum.values[index - 1]; 17 | } 18 | -------------------------------------------------------------------------------- /lib/enums/message_priority_enum.dart: -------------------------------------------------------------------------------- 1 | /// 消息优先级枚举 2 | enum MessagePriorityEnum { 3 | // 默认为普通优先级 4 | Default, 5 | // 高优先级,一般用于礼物等重要消息 6 | Hign, 7 | // 普通优先级,一般用于普通消息 8 | Normal, 9 | // 低优先级,一般用于点赞消息 10 | Low, 11 | // 未知,保留状态,Android部分场景会出现 12 | Unknown, 13 | } 14 | 15 | class MessagePriorityTool { 16 | /// 根据Int类型值获得枚举 17 | /// [index] Int常量 18 | /// [Return] 枚举对象 19 | static MessagePriorityEnum getByInt(int index) => MessagePriorityEnum.values[index]; 20 | 21 | /// 将枚举转换为整型 22 | static int toInt(MessagePriorityEnum level) => level.index; 23 | } 24 | -------------------------------------------------------------------------------- /lib/enums/message_status_enum.dart: -------------------------------------------------------------------------------- 1 | /// 消息状态 2 | enum MessageStatusEnum { 3 | /// 未知 4 | Unknown, 5 | 6 | /// 发送中 7 | Sending, 8 | 9 | /// 发送成功 10 | SendSucc, 11 | 12 | /// 发送失败 13 | SendFail, 14 | 15 | /// 删除 16 | HasDeleted, 17 | 18 | /// 导入到本地的消息 19 | Imported, 20 | 21 | /// 已撤回 22 | HasRevoked, 23 | } 24 | 25 | class MessageStatusTool { 26 | /// 根据Int类型值获得枚举 27 | /// [index] Int常量 28 | /// [Return] 枚举对象 29 | static MessageStatusEnum getByInt(int index) { 30 | switch (index) { 31 | case 0: 32 | return MessageStatusEnum.Unknown; 33 | case 1: 34 | return MessageStatusEnum.Sending; 35 | case 2: 36 | return MessageStatusEnum.SendSucc; 37 | case 3: 38 | return MessageStatusEnum.SendFail; 39 | case 4: 40 | return MessageStatusEnum.HasDeleted; 41 | case 5: 42 | return MessageStatusEnum.Imported; 43 | case 6: 44 | return MessageStatusEnum.HasRevoked; 45 | } 46 | throw ArgumentError("参数异常"); 47 | } 48 | 49 | /// 将枚举转换为整型 50 | static int toInt(MessageStatusEnum status) { 51 | switch (status) { 52 | case MessageStatusEnum.Unknown: 53 | return 0; 54 | case MessageStatusEnum.Sending: 55 | return 1; 56 | case MessageStatusEnum.SendSucc: 57 | return 2; 58 | case MessageStatusEnum.SendFail: 59 | return 3; 60 | case MessageStatusEnum.HasDeleted: 61 | return 4; 62 | case MessageStatusEnum.Imported: 63 | return 5; 64 | case MessageStatusEnum.HasRevoked: 65 | return 6; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/enums/operation_result_enum.dart: -------------------------------------------------------------------------------- 1 | /// 操作结果枚举 2 | enum OperationResultEnum { 3 | /// 操作失败 4 | Fail, 5 | 6 | /// 操作成功 7 | Succ, 8 | 9 | /// 无效操作 10 | Invalid, 11 | 12 | /// 等待处理 13 | Pending, 14 | } 15 | 16 | class OperationResultTool { 17 | /// 根据Int类型值获得枚举 18 | /// [index] Int常量 19 | /// [Return] 枚举对象 20 | static OperationResultEnum getByInt(int index) => 21 | OperationResultEnum.values[index]; 22 | 23 | /// 将枚举转换为整型 24 | static int toInt(OperationResultEnum level) => level.index; 25 | } 26 | -------------------------------------------------------------------------------- /lib/enums/pendency_examine_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// 未决审核类型枚举 2 | enum PendencyExamineTypeEnum { 3 | // 同意加好友(建立单向好友) 4 | AGREE, 5 | // 同意加好友并加对方为好友(建立双向好友) 6 | AGREE_AND_ADD, 7 | // 拒绝对方好友请求 8 | REJECT, 9 | } 10 | 11 | /// 枚举工具 12 | class PendencyExamineTypeEnumTool { 13 | /// 根据数标获得枚举 14 | static PendencyExamineTypeEnum? getEnumByIndex(index) { 15 | switch (index) { 16 | case 0: 17 | return PendencyExamineTypeEnum.AGREE; 18 | case 1: 19 | return PendencyExamineTypeEnum.AGREE_AND_ADD; 20 | case 2: 21 | return PendencyExamineTypeEnum.REJECT; 22 | default: 23 | return null; 24 | } 25 | } 26 | 27 | /// 根据枚举获得数标 28 | static int? getIndexByEnum(e) { 29 | switch (e) { 30 | case PendencyExamineTypeEnum.AGREE: 31 | return 0; 32 | case PendencyExamineTypeEnum.AGREE_AND_ADD: 33 | return 1; 34 | case PendencyExamineTypeEnum.REJECT: 35 | return 2; 36 | default: 37 | return null; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/enums/pendency_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// 未决类型 2 | enum PendencyTypeEnum { 3 | /// 别人发给我的未决请求 4 | COME_IN, 5 | 6 | /// 我发给别人的未决请求 7 | SEND_OUT, 8 | 9 | /// 别人发给我的以及我发给别人的所有未决请求,仅在拉取时有效。 10 | BOTH, 11 | } 12 | 13 | /// 枚举工具 14 | class PendencyTypeTool { 15 | /// 根据数标获得枚举 16 | static PendencyTypeEnum? getEnumByIndex(index) { 17 | switch (index) { 18 | case 1: 19 | return PendencyTypeEnum.COME_IN; 20 | case 2: 21 | return PendencyTypeEnum.SEND_OUT; 22 | case 3: 23 | return PendencyTypeEnum.BOTH; 24 | default: 25 | return null; 26 | } 27 | } 28 | 29 | /// 根据枚举获得数标 30 | static int? getIndexByEnum(e) { 31 | switch (e) { 32 | case PendencyTypeEnum.COME_IN: 33 | return 1; 34 | case PendencyTypeEnum.SEND_OUT: 35 | return 2; 36 | case PendencyTypeEnum.BOTH: 37 | return 3; 38 | default: 39 | return null; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/enums/receive_message_opt_enum.dart: -------------------------------------------------------------------------------- 1 | /// 接收消息选项 2 | enum ReceiveMessageOptEnum { 3 | /// 在线正常接收消息,离线时会有厂商的离线推送通知 4 | ReceiveAndNotify, 5 | 6 | /// 不会接收到消息 7 | NotReceive, 8 | 9 | /// 在线正常接收消息,离线不会有推送通知 10 | ReceiveNotNotify, 11 | } 12 | 13 | class ReceiveMessageOptTool { 14 | /// 根据Int类型值获得枚举 15 | /// [index] Int常量 16 | /// [Return] 枚举对象 17 | static ReceiveMessageOptEnum getByInt(int index) => ReceiveMessageOptEnum.values[index]; 18 | 19 | /// 将枚举转换为整型 20 | static int toInt(ReceiveMessageOptEnum level) => level.index; 21 | } -------------------------------------------------------------------------------- /lib/enums/signaling_action_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// 信令操作类型枚举 2 | enum SignalingActionTypeEnum { 3 | // 邀请方发起邀请 4 | Invite, 5 | // 邀请方取消邀请 6 | Cancel, 7 | // 被邀请方接受邀请 8 | Accept, 9 | // 被邀请方拒绝邀请 10 | Reject, 11 | // 邀请超时 12 | Timeout 13 | } 14 | 15 | class SignalingActionTypeTool { 16 | /// 根据Int类型值获得枚举 17 | /// [index] Int常量 18 | /// [Return] 枚举对象 19 | static SignalingActionTypeEnum getByInt(int index) => 20 | SignalingActionTypeEnum.values[index - 1]; 21 | 22 | /// 将枚举转换为整型 23 | static int toInt(SignalingActionTypeEnum level) => level.index + 1; 24 | } 25 | -------------------------------------------------------------------------------- /lib/enums/sns_tips_type.dart: -------------------------------------------------------------------------------- 1 | /// 关系链变更类型 2 | enum SnsTipsType { 3 | /// 未知 4 | INVALID, 5 | 6 | /// 增加好友消息 7 | ADD_FRIEND, 8 | 9 | /// 删除好友 10 | DEL_FRIEND, 11 | 12 | /// 增加好友申请 13 | ADD_FRIEND_REQ, 14 | 15 | /// 删除好友申请 16 | DEL_FRIEND_REQ, 17 | 18 | /// 添加黑名单 19 | ADD_BLACKLIST, 20 | 21 | /// 删除黑名单 22 | DEL_BLACKLIST, 23 | 24 | /// 未决已读上报 25 | PENDENCY_REPORT, 26 | 27 | /// 关系链资料变更 28 | SNS_PROFILE_CHANGE, 29 | 30 | /// 推荐数据增加 31 | ADD_RECOMMEND, 32 | 33 | /// 推荐数据减少 34 | DEL_RECOMMEND, 35 | 36 | /// 已决增加 37 | ADD_DECIDE, 38 | 39 | /// 已决减少 40 | DEL_DECIDE, 41 | 42 | /// 推荐已读上报 43 | RECOMMEND_REPORT, 44 | 45 | /// 已决已读上报 46 | DECIDE_REPORT 47 | } 48 | -------------------------------------------------------------------------------- /lib/enums/user_allow_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// 用户验证方式枚举 2 | enum UserAllowTypeEnum { 3 | // 允许任何人 4 | AllowAny, 5 | // 需要确认 6 | NeedConfirm, 7 | // 拒绝任何人 8 | DenyAny, 9 | } 10 | 11 | class UserAllowTypeTool { 12 | /// 根据Int类型值获得枚举 13 | /// [index] Int常量 14 | /// [Return] 枚举对象 15 | static UserAllowTypeEnum getByInt(int index) => 16 | UserAllowTypeEnum.values[index]; 17 | 18 | /// 将枚举转换为整型 19 | static int toInt(UserAllowTypeEnum level) => level.index; 20 | } 21 | -------------------------------------------------------------------------------- /lib/enums/user_gender_enum.dart: -------------------------------------------------------------------------------- 1 | /// 用户性别枚举 2 | enum UserGenderEnum { 3 | // 未知 4 | Unknown, 5 | // 男 6 | Male, 7 | // 女 8 | Female, 9 | } 10 | 11 | class UserGenderTool { 12 | /// 根据Int类型值获得枚举 13 | /// [index] Int常量 14 | /// [Return] 枚举对象 15 | static UserGenderEnum getByInt(int index) => UserGenderEnum.values[index]; 16 | 17 | /// 将枚举转换为整型 18 | static int toInt(UserGenderEnum level) => level.index; 19 | } 20 | -------------------------------------------------------------------------------- /lib/list_util.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'entity_factory.dart'; 4 | 5 | class ListUtil { 6 | /// 根据泛型生成集合 7 | static List generateOBJList(arr) { 8 | if (arr is String) { 9 | arr = jsonDecode(arr); 10 | } 11 | 12 | List data = []; 13 | for (var item in arr) { 14 | var d = EntityFactory.generateOBJ(item); 15 | if (d != null) { 16 | data.add(d); 17 | } 18 | } 19 | return data; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/message_node/custom_message_node.dart: -------------------------------------------------------------------------------- 1 | import 'package:tencent_im_plugin/enums/message_elem_type_enum.dart'; 2 | import 'package:tencent_im_plugin/message_node/message_node.dart'; 3 | 4 | /// 自定义消息节点 5 | class CustomMessageNode extends MessageNode { 6 | /// 自定义数据 7 | String? data; 8 | 9 | /// 描述信息 10 | String? desc; 11 | 12 | /// 扩展信息 13 | String? ext; 14 | 15 | CustomMessageNode({ 16 | required this.data, 17 | this.desc, 18 | this.ext, 19 | }) : super(MessageElemTypeEnum.Custom); 20 | 21 | CustomMessageNode.fromJson(Map json) : super(MessageElemTypeEnum.Custom) { 22 | if (json['data'] != null) data = json['data']; 23 | if (json['desc'] != null) desc = json['desc']; 24 | if (json['ext'] != null) ext = json['ext']; 25 | } 26 | 27 | @override 28 | Map toJson() { 29 | final Map data = super.toJson(); 30 | data["data"] = this.data; 31 | data["desc"] = this.desc; 32 | data["ext"] = this.ext; 33 | return data; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/message_node/face_message_node.dart: -------------------------------------------------------------------------------- 1 | import 'package:tencent_im_plugin/enums/message_elem_type_enum.dart'; 2 | import 'package:tencent_im_plugin/message_node/message_node.dart'; 3 | 4 | /// 表情消息节点 5 | class FaceMessageNode extends MessageNode { 6 | /// 索引 7 | late int index; 8 | 9 | /// 数据 10 | late String data; 11 | 12 | FaceMessageNode({ 13 | required this.index, 14 | required this.data, 15 | }) : super(MessageElemTypeEnum.Face); 16 | 17 | FaceMessageNode.fromJson(Map json) 18 | : super(MessageElemTypeEnum.Face) { 19 | if (json['index'] != null) this.index = json["index"]; 20 | if (json['data'] != null) this.data = json["data"]; 21 | } 22 | 23 | @override 24 | Map toJson() { 25 | final Map data = super.toJson(); 26 | data["index"] = this.index; 27 | data["data"] = this.data; 28 | return data; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/message_node/file_message_node.dart: -------------------------------------------------------------------------------- 1 | import 'package:tencent_im_plugin/enums/message_elem_type_enum.dart'; 2 | import 'package:tencent_im_plugin/message_node/message_node.dart'; 3 | 4 | /// 文件消息节点 5 | class FileMessageNode extends MessageNode { 6 | /// 文件路径 7 | String? filePath; 8 | 9 | /// 文件名 10 | String? fileName; 11 | 12 | /// 文件ID 13 | String? _uuid; 14 | 15 | /// 文件大小 16 | int? _size; 17 | 18 | FileMessageNode({ 19 | required this.filePath, 20 | required this.fileName, 21 | }) : super(MessageElemTypeEnum.File); 22 | 23 | FileMessageNode.fromJson(Map json) : super(MessageElemTypeEnum.File) { 24 | if (json['filePath'] != null) this.filePath = json["filePath"]; 25 | if (json['fileName'] != null) this.fileName = json["fileName"]; 26 | if (json['uuid'] != null) this._uuid = json["uuid"]; 27 | if (json['size'] != null) this._size = json["size"]; 28 | } 29 | 30 | /// 获得UUID 31 | String? get uuid => _uuid; 32 | 33 | /// 获得文件大小 34 | int? get size => _size; 35 | 36 | @override 37 | Map toJson() { 38 | final Map data = super.toJson(); 39 | data["filePath"] = this.filePath; 40 | data["fileName"] = this.fileName; 41 | return data; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/message_node/image_message_node.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:tencent_im_plugin/enums/image_type_enum.dart'; 3 | import 'package:tencent_im_plugin/enums/message_elem_type_enum.dart'; 4 | import 'package:tencent_im_plugin/message_node/message_node.dart'; 5 | 6 | /// 图片消息节点 7 | class ImageMessageNode extends MessageNode { 8 | /// 图片路径 9 | String? path; 10 | 11 | /// 图片列表,根据类型分开 12 | Map? _imageData; 13 | 14 | ImageMessageNode({ 15 | required this.path, 16 | }) : super(MessageElemTypeEnum.Image); 17 | 18 | ImageMessageNode.fromJson(Map json) 19 | : super(MessageElemTypeEnum.Image) { 20 | if (json['path'] != null) path = json['path']; 21 | if (json['imageData'] != null) { 22 | _imageData = Map(); 23 | (json['imageData'] as List).forEach((v) { 24 | ImageEntity imageEntity = ImageEntity.fromJson(v); 25 | _imageData![imageEntity.type!] = imageEntity; 26 | }); 27 | } 28 | } 29 | 30 | /// 获得图片列表 31 | Map? get imageData => _imageData; 32 | 33 | @override 34 | Map toJson() { 35 | final Map data = super.toJson(); 36 | data["path"] = this.path; 37 | return data; 38 | } 39 | } 40 | 41 | /// 图片实体 42 | class ImageEntity { 43 | /// 大小 44 | int? size; 45 | 46 | /// 宽度 47 | int? width; 48 | 49 | /// 类型 50 | ImageTypeEnum? type; 51 | 52 | /// uuid 53 | String? uuid; 54 | 55 | /// url 56 | String? url; 57 | 58 | /// 高度 59 | int? height; 60 | 61 | ImageEntity({ 62 | this.size, 63 | this.width, 64 | this.type, 65 | this.uuid, 66 | this.url, 67 | this.height, 68 | }); 69 | 70 | ImageEntity.fromJson(data) { 71 | Map json = 72 | data is Map ? data.cast() : jsonDecode(data); 73 | if (json['size'] != null) size = json['size']; 74 | if (json['width'] != null) width = json['width']; 75 | if (json['type'] != null) type = ImageTypeTool.getByInt(json["type"]); 76 | if (json['uUID'] != null) uuid = json['uUID']; 77 | if (json['url'] != null) url = json['url']; 78 | if (json['height'] != null) height = json['height']; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /lib/message_node/location_message_node.dart: -------------------------------------------------------------------------------- 1 | import 'package:tencent_im_plugin/enums/message_elem_type_enum.dart'; 2 | import 'package:tencent_im_plugin/message_node/message_node.dart'; 3 | 4 | /// 位置节点 5 | class LocationMessageNode extends MessageNode { 6 | /// 位置描述 7 | late String desc; 8 | 9 | /// 经度 10 | late double longitude; 11 | 12 | /// 纬度 13 | late double latitude; 14 | 15 | LocationMessageNode({ 16 | required this.desc, 17 | required this.longitude, 18 | required this.latitude, 19 | }) : super(MessageElemTypeEnum.Location); 20 | 21 | LocationMessageNode.fromJson(Map json) 22 | : super(MessageElemTypeEnum.Location) { 23 | if (json['desc'] != null) desc = json['desc']; 24 | if (json['longitude'] != null) longitude = json['longitude']; 25 | if (json['latitude'] != null) latitude = json['latitude']; 26 | } 27 | 28 | @override 29 | Map toJson() { 30 | final Map data = super.toJson(); 31 | data["desc"] = this.desc; 32 | data["longitude"] = this.longitude; 33 | data["latitude"] = this.latitude; 34 | return data; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/message_node/message_node.dart: -------------------------------------------------------------------------------- 1 | import 'package:tencent_im_plugin/enums/message_elem_type_enum.dart'; 2 | 3 | /// 消息节点 4 | class MessageNode { 5 | /// 新消息节点类型 6 | MessageElemTypeEnum nodeType; 7 | 8 | MessageNode(this.nodeType); 9 | 10 | Map toJson() { 11 | final Map data = new Map(); 12 | data["nodeType"] = MessageElemTypeTool.toInt(this.nodeType); 13 | return data; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/message_node/sound_message_node.dart: -------------------------------------------------------------------------------- 1 | import 'package:tencent_im_plugin/enums/message_elem_type_enum.dart'; 2 | import 'package:tencent_im_plugin/message_node/message_node.dart'; 3 | 4 | /// 语音消息节点 5 | class SoundMessageNode extends MessageNode { 6 | /// 语音ID 7 | String? _uuid; 8 | 9 | /// 路径 10 | String? path; 11 | 12 | /// 时长 13 | late int duration; 14 | 15 | /// 数据大小 16 | int? _dataSize; 17 | 18 | SoundMessageNode({ 19 | required this.path, 20 | required this.duration, 21 | }) : super(MessageElemTypeEnum.Sound); 22 | 23 | SoundMessageNode.fromJson(Map json) 24 | : super(MessageElemTypeEnum.Sound) { 25 | if (json['uuid'] != null) _uuid = json['uuid']; 26 | if (json['path'] != null) path = json['path']; 27 | if (json['duration'] != null) duration = json['duration']; 28 | if (json['dataSize'] != null) _dataSize = json['dataSize']; 29 | } 30 | 31 | /// 获得语音ID 32 | String? get uuid => _uuid; 33 | 34 | /// 获得数据大小 35 | int? get dataSize => _dataSize; 36 | 37 | @override 38 | Map toJson() { 39 | final Map data = super.toJson(); 40 | data["path"] = this.path; 41 | data["duration"] = this.duration; 42 | return data; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/message_node/text_message_node.dart: -------------------------------------------------------------------------------- 1 | import 'package:tencent_im_plugin/enums/message_elem_type_enum.dart'; 2 | import 'package:tencent_im_plugin/message_node/message_node.dart'; 3 | 4 | /// 文本消息节点 5 | class TextMessageNode extends MessageNode { 6 | /// 文本内容 7 | late String content; 8 | 9 | /// @的用户列表,只在群聊中有效 10 | List? _atUserList; 11 | 12 | /// 是否需要@所有人 13 | bool _atAll = false; 14 | 15 | TextMessageNode({ 16 | required this.content, 17 | List? atUserList, 18 | bool atAll: false, 19 | }) : this._atUserList = atUserList, 20 | this._atAll = atAll, 21 | super(MessageElemTypeEnum.Text); 22 | 23 | TextMessageNode.fromJson(Map json) : super(MessageElemTypeEnum.Text) { 24 | if (json['content'] != null) content = json['content']; 25 | } 26 | 27 | /// 设置@列表 28 | set atUserList(List value) => _atUserList = value; 29 | 30 | /// 设置@所有人 31 | set atAll(bool value) => _atAll = value; 32 | 33 | @override 34 | Map toJson() { 35 | final Map data = super.toJson(); 36 | data["content"] = this.content; 37 | data["atUserList"] = this._atUserList; 38 | data["atAll"] = this._atAll; 39 | return data; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/message_node/video_message_node.dart: -------------------------------------------------------------------------------- 1 | import 'package:tencent_im_plugin/enums/message_elem_type_enum.dart'; 2 | import 'package:tencent_im_plugin/message_node/message_node.dart'; 3 | 4 | /// 适配消息节点 5 | class VideoMessageNode extends MessageNode { 6 | /// 视频路径 7 | String? videoPath; 8 | 9 | /// 视频UUID 10 | String? _videoUuid; 11 | 12 | /// 视频大小 13 | int? _videoSize; 14 | 15 | /// 时长 16 | late int duration; 17 | 18 | /// 缩略图路径 19 | String? snapshotPath; 20 | 21 | /// 缩略图UUID 22 | String? _snapshotUuid; 23 | 24 | /// 缩略图大小 25 | int? _snapshotSize; 26 | 27 | /// 缩略图宽度 28 | int? _snapshotWidth; 29 | 30 | /// 缩略图高度 31 | int? _snapshotHeight; 32 | 33 | VideoMessageNode({ 34 | required this.videoPath, 35 | required this.duration, 36 | required this.snapshotPath, 37 | }) : super(MessageElemTypeEnum.Video); 38 | 39 | VideoMessageNode.fromJson(Map json) 40 | : super(MessageElemTypeEnum.Video) { 41 | if (json['videoPath'] != null) videoPath = json["videoPath"]; 42 | if (json['videoUuid'] != null) _videoUuid = json["videoUuid"]; 43 | if (json['videoSize'] != null) _videoSize = json["videoSize"]; 44 | if (json['duration'] != null) duration = json["duration"]; 45 | if (json['snapshotPath'] != null) snapshotPath = json["snapshotPath"]; 46 | if (json['snapshotUuid'] != null) _snapshotUuid = json["snapshotUuid"]; 47 | if (json['snapshotSize'] != null) _snapshotSize = json["snapshotSize"]; 48 | if (json['snapshotWidth'] != null) _snapshotWidth = json["snapshotWidth"]; 49 | if (json['snapshotHeight'] != null) 50 | _snapshotHeight = json["snapshotHeight"]; 51 | } 52 | 53 | /// 获得视频UUID 54 | String? get videoUuid => _videoUuid; 55 | 56 | /// 获得视频大小 57 | int? get videoSize => _videoSize; 58 | 59 | /// 获得缩略图UUID 60 | String? get snapshotUuid => _snapshotUuid; 61 | 62 | /// 获得缩略图大小 63 | int? get snapshotSize => _snapshotSize; 64 | 65 | /// 获得缩略图宽度 66 | int? get snapshotWidth => _snapshotWidth; 67 | 68 | /// 获得缩略图高度 69 | int? get snapshotHeight => _snapshotHeight; 70 | 71 | @override 72 | Map toJson() { 73 | final Map data = super.toJson(); 74 | data["videoPath"] = this.videoPath; 75 | data["duration"] = this.duration; 76 | data["snapshotPath"] = this.snapshotPath; 77 | return data; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /lib/utils/enum_util.dart: -------------------------------------------------------------------------------- 1 | /// 枚举工具类 2 | class EnumUtil { 3 | /// 获得枚举的名称(不包含前缀) 4 | static String getEnumName(enumObj) { 5 | var es = enumObj.toString().split("."); 6 | return es[es.length - 1]; 7 | } 8 | 9 | /// 根据名字获得枚举 10 | static T? nameOf(List array, String name) { 11 | for (var item in array) { 12 | if (EnumUtil.getEnumName(item) == name) { 13 | return item; 14 | } 15 | } 16 | return null; 17 | } 18 | } 19 | --------------------------------------------------------------------------------