├── .gitignore ├── README.md ├── im_flutter_sdk ├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── example │ ├── .gitignore │ ├── .metadata │ ├── README.md │ ├── analysis_options.yaml │ ├── android │ │ ├── .gitignore │ │ ├── app │ │ │ ├── build.gradle.kts │ │ │ └── src │ │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── com │ │ │ │ │ │ └── example │ │ │ │ │ │ └── example │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── res │ │ │ │ │ ├── drawable-v21 │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── 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-night │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values │ │ │ │ │ └── styles.xml │ │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ └── gradle-wrapper.properties │ │ └── settings.gradle.kts │ ├── ios │ │ ├── .gitignore │ │ ├── Flutter │ │ │ ├── AppFrameworkInfo.plist │ │ │ ├── Debug.xcconfig │ │ │ └── Release.xcconfig │ │ ├── Podfile │ │ ├── Podfile.lock │ │ ├── Runner.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcshareddata │ │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ │ └── WorkspaceSettings.xcsettings │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ ├── Runner.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ ├── 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 │ │ └── RunnerTests │ │ │ └── RunnerTests.swift │ ├── lib │ │ └── main.dart │ ├── pubspec.lock │ └── pubspec.yaml ├── lib │ ├── im_flutter_sdk.dart │ └── src │ │ ├── chat_manager.dart │ │ ├── chat_room_manager.dart │ │ ├── chat_thread_manager.dart │ │ ├── client.dart │ │ ├── contact_manager.dart │ │ ├── group_manager.dart │ │ ├── presence_manager.dart │ │ ├── push_manager.dart │ │ └── user_info_manager.dart └── pubspec.yaml ├── im_flutter_sdk_android ├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── android │ ├── .gitignore │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── easemob │ │ └── im_flutter_sdk │ │ ├── ChatManagerWrapper.java │ │ ├── ChatRoomManagerWrapper.java │ │ ├── ChatThreadManagerWrapper.java │ │ ├── ClientWrapper.java │ │ ├── CommonUtil.java │ │ ├── ContactManagerWrapper.java │ │ ├── ConversationWrapper.java │ │ ├── EMHelper.java │ │ ├── EnumTools.java │ │ ├── GroupManagerWrapper.java │ │ ├── HelpTool.java │ │ ├── ImFlutterSdkPlugin.java │ │ ├── ListenerHandle.java │ │ ├── MessageWrapper.java │ │ ├── MethodKey.java │ │ ├── PresenceManagerWrapper.java │ │ ├── ProgressManager.java │ │ ├── PushManagerWrapper.java │ │ ├── UserInfoManagerWrapper.java │ │ └── Wrapper.java ├── lib │ ├── im_flutter_sdk_android.dart │ └── src │ │ ├── chat_manager_android.dart │ │ ├── chat_room_manager_android.dart │ │ ├── chat_thread_manager_android.dart │ │ ├── client_android.dart │ │ ├── contact_manager_android.dart │ │ ├── group_manager_android.dart │ │ ├── presence_manager_android.dart │ │ ├── push_manager_android.dart │ │ └── user_info_manager_android.dart └── pubspec.yaml ├── im_flutter_sdk_interface ├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── lib │ ├── im_flutter_sdk_interface.dart │ ├── interface │ │ ├── manager_mixin.dart │ │ ├── method_channel │ │ │ └── default_channels.dart │ │ └── platform_interface │ │ │ ├── chat_manager.dart │ │ │ ├── chat_room_manager.dart │ │ │ ├── chat_thread_manager.dart │ │ │ ├── client.dart │ │ │ ├── contact_manager.dart │ │ │ ├── group_manager.dart │ │ │ ├── presence_manager.dart │ │ │ ├── progress_manager.dart │ │ │ ├── push_manager.dart │ │ │ └── user_info_manager.dart │ └── src │ │ ├── event_handler │ │ └── manager_event_handler.dart │ │ ├── internal │ │ ├── chat_method_keys.dart │ │ ├── em_channel_manager.dart │ │ ├── em_event_keys.dart │ │ ├── em_push_config.dart │ │ ├── em_transform_tools.dart │ │ └── inner_headers.dart │ │ ├── models │ │ ├── chat_silent_mode.dart │ │ ├── conversation_fetch_options.dart │ │ ├── em_chat_enums.dart │ │ ├── em_chat_room.dart │ │ ├── em_chat_thread.dart │ │ ├── em_contact.dart │ │ ├── em_conversation.dart │ │ ├── em_cursor_result.dart │ │ ├── em_device_info.dart │ │ ├── em_download_callback.dart │ │ ├── em_error.dart │ │ ├── em_group.dart │ │ ├── em_group_message_ack.dart │ │ ├── em_group_options.dart │ │ ├── em_group_shared_file.dart │ │ ├── em_message.dart │ │ ├── em_message_reaction.dart │ │ ├── em_options.dart │ │ ├── em_page_result.dart │ │ ├── em_presence.dart │ │ ├── em_push_configs.dart │ │ ├── em_translate_language.dart │ │ ├── em_user_info.dart │ │ ├── fetch_message_options.dart │ │ ├── login_extension_info.dart │ │ ├── message_pin_info.dart │ │ ├── message_search_options.dart │ │ ├── reaction_operation.dart │ │ └── recall_message_info.dart │ │ └── tools │ │ ├── chat_area_code.dart │ │ ├── em_extension.dart │ │ ├── em_log.dart │ │ └── em_tools.dart └── pubspec.yaml └── im_flutter_sdk_ios ├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── ios ├── .gitignore ├── Assets │ └── .gitkeep ├── Classes │ ├── ChatHeaders.h │ ├── ChatManagerWrapper.h │ ├── ChatManagerWrapper.m │ ├── ChatroomHelper.h │ ├── ChatroomHelper.m │ ├── ChatroomManagerWrapper.h │ ├── ChatroomManagerWrapper.m │ ├── ClientWrapper.h │ ├── ClientWrapper.m │ ├── ContactHelper.h │ ├── ContactHelper.m │ ├── ContactManagerWrapper.h │ ├── ContactManagerWrapper.m │ ├── ConversationFilterHelper.h │ ├── ConversationFilterHelper.m │ ├── ConversationHelper.h │ ├── ConversationHelper.m │ ├── ConversationWrapper.h │ ├── ConversationWrapper.m │ ├── CursorResultHelper.h │ ├── CursorResultHelper.m │ ├── DeviceConfigHelper.h │ ├── DeviceConfigHelper.m │ ├── EnumTools.h │ ├── EnumTools.m │ ├── ErrorHelper.h │ ├── ErrorHelper.m │ ├── FetchServerMessagesOptionHelper.h │ ├── FetchServerMessagesOptionHelper.m │ ├── GroupHelper.h │ ├── GroupHelper.m │ ├── GroupManagerWrapper.h │ ├── GroupManagerWrapper.m │ ├── GroupMessageAckHelper.h │ ├── GroupMessageAckHelper.m │ ├── Header.h │ ├── Helper.h │ ├── Helper.m │ ├── ImFlutterSdkPlugin.h │ ├── ImFlutterSdkPlugin.m │ ├── ListenerHandle.h │ ├── ListenerHandle.m │ ├── LoginExtensionInfoHelper.h │ ├── LoginExtensionInfoHelper.m │ ├── MessageHelper.h │ ├── MessageHelper.m │ ├── MessagePinInfoHelper.h │ ├── MessagePinInfoHelper.m │ ├── MessageReactionChangeHelper.h │ ├── MessageReactionChangeHelper.m │ ├── MessageReactionHelper.h │ ├── MessageReactionHelper.m │ ├── MessageReactionOperationHelper.h │ ├── MessageReactionOperationHelper.m │ ├── MessageWrapper.h │ ├── MessageWrapper.m │ ├── MethodKeys.h │ ├── ModeToJson.h │ ├── NSArray+Helper.h │ ├── NSArray+Helper.m │ ├── OptionsHelper.h │ ├── OptionsHelper.m │ ├── PageResultHelper.h │ ├── PageResultHelper.m │ ├── PresenceHelper.h │ ├── PresenceHelper.m │ ├── PresenceManagerWrapper.h │ ├── PresenceManagerWrapper.m │ ├── ProgressManager.h │ ├── ProgressManager.m │ ├── PushManagerWrapper.h │ ├── PushManagerWrapper.m │ ├── PushOptionsHelper.h │ ├── PushOptionsHelper.m │ ├── RecallInfoHelper.h │ ├── RecallInfoHelper.m │ ├── SilentModeParamHelper.h │ ├── SilentModeParamHelper.m │ ├── SilentModeResultHelper.h │ ├── SilentModeResultHelper.m │ ├── SilentModeTimeHelper.h │ ├── SilentModeTimeHelper.m │ ├── ThreadEventHelper.h │ ├── ThreadEventHelper.m │ ├── ThreadHelper.h │ ├── ThreadHelper.m │ ├── ThreadManagerWrapper.h │ ├── ThreadManagerWrapper.m │ ├── TranslateLanguageHelper.h │ ├── TranslateLanguageHelper.m │ ├── UserInfoHelper.h │ ├── UserInfoHelper.m │ ├── UserInfoManagerWrapper.h │ ├── UserInfoManagerWrapper.m │ ├── Wrapper.h │ └── Wrapper.m └── im_flutter_sdk_ios.podspec ├── lib ├── im_flutter_sdk_ios.dart └── src │ ├── chat_manager_ios.dart │ ├── chat_room_manager_ios.dart │ ├── chat_thread_manager_ios.dart │ ├── client_ios.dart │ ├── contact_manager_ios.dart │ ├── group_manager_ios.dart │ ├── presence_manager_ios.dart │ ├── push_manager_ios.dart │ └── user_info_manager_ios.dart └── pubspec.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | .vscode 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Symbolication related 36 | app.*.symbols 37 | 38 | # Obfuscation related 39 | app.*.map.json 40 | 41 | # Android Studio will place build artifacts here 42 | /android/app/debug 43 | /android/app/profile 44 | /android/app/release 45 | 46 | # FVM Version Cache 47 | .fvm/ 48 | .fvmrc 49 | /scripts/shengwang_chat_sdk 50 | /scripts/agora_chat_sdk 51 | /scripts/im_flutter_sdk -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 环信 im flutter sdk 项目介绍 2 | 3 | 1. 使用联合插件的方式开发,支持安卓,iOS,鸿蒙 三个平台; 4 | 2. sdk readme 在 [README](/im_flutter_sdk/README.md); 5 | 6 | 7 | 8 | ## 如何添加鸿蒙支持 9 | 10 | 11 | 1. 使用鸿蒙版 flutter `https://gitee.com/harmonycommando_flutter/flutter` 12 | 13 | 2. 在项目 pubspec.yaml 中添加: 14 | ```dart 15 | im_flutter_sdk: ^4.13.0 16 | im_flutter_sdk_ohos: 17 | git: 18 | url: "https://github.com/easemob/im_flutter_sdk_oh.git" 19 | ref: 1.5.3 20 | ``` 21 | 其中具体的 `ref` 可以去 `https://github.com/easemob/im_flutter_sdk_oh/releases` 查看最新版本号; 22 | 23 | 1. 执行 `flutter pub get`; -------------------------------------------------------------------------------- /im_flutter_sdk/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 26 | /pubspec.lock 27 | **/doc/api/ 28 | .dart_tool/ 29 | build/ 30 | -------------------------------------------------------------------------------- /im_flutter_sdk/.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: "dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668" 8 | channel: "stable" 9 | 10 | project_type: plugin 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668 17 | base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668 18 | - platform: android 19 | create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668 20 | base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668 21 | - platform: ios 22 | create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668 23 | base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668 24 | 25 | # User provided section 26 | 27 | # List of Local paths (relative to this file) that should be 28 | # ignored by the migrate tool. 29 | # 30 | # Files that are not part of the templates will be ignored by default. 31 | unmanaged_files: 32 | - 'lib/main.dart' 33 | - 'ios/Runner.xcodeproj/project.pbxproj' 34 | -------------------------------------------------------------------------------- /im_flutter_sdk/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /im_flutter_sdk/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | # Additional information about this file can be found at 4 | # https://dart.dev/guides/language/analysis-options 5 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .build/ 9 | .buildlog/ 10 | .history 11 | .svn/ 12 | .swiftpm/ 13 | migrate_working_dir/ 14 | 15 | # IntelliJ related 16 | *.iml 17 | *.ipr 18 | *.iws 19 | .idea/ 20 | 21 | # The .vscode folder contains launch configuration and tasks you configure in 22 | # VS Code which you may wish to be included in version control, so this line 23 | # is commented out by default. 24 | #.vscode/ 25 | 26 | # Flutter/Dart/Pub related 27 | **/doc/api/ 28 | **/ios/Flutter/.last_build_id 29 | .dart_tool/ 30 | .flutter-plugins 31 | .flutter-plugins-dependencies 32 | .pub-cache/ 33 | .pub/ 34 | /build/ 35 | 36 | # Symbolication related 37 | app.*.symbols 38 | 39 | # Obfuscation related 40 | app.*.map.json 41 | 42 | # Android Studio will place build artifacts here 43 | /android/app/debug 44 | /android/app/profile 45 | /android/app/release 46 | -------------------------------------------------------------------------------- /im_flutter_sdk/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: "35c388afb57ef061d06a39b537336c87e0e3d1b1" 8 | channel: "stable" 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 35c388afb57ef061d06a39b537336c87e0e3d1b1 17 | base_revision: 35c388afb57ef061d06a39b537336c87e0e3d1b1 18 | - platform: android 19 | create_revision: 35c388afb57ef061d06a39b537336c87e0e3d1b1 20 | base_revision: 35c388afb57ef061d06a39b537336c87e0e3d1b1 21 | - platform: ios 22 | create_revision: 35c388afb57ef061d06a39b537336c87e0e3d1b1 23 | base_revision: 35c388afb57ef061d06a39b537336c87e0e3d1b1 24 | 25 | # User provided section 26 | 27 | # List of Local paths (relative to this file) that should be 28 | # ignored by the migrate tool. 29 | # 30 | # Files that are not part of the templates will be ignored by default. 31 | unmanaged_files: 32 | - 'lib/main.dart' 33 | - 'ios/Runner.xcodeproj/project.pbxproj' 34 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/README.md: -------------------------------------------------------------------------------- 1 | # example 2 | 3 | A new Flutter project. 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://docs.flutter.dev/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) 13 | 14 | For help getting started with Flutter development, view the 15 | [online documentation](https://docs.flutter.dev/), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at https://dart.dev/lints. 17 | # 18 | # Instead of disabling a lint rule for the entire project in the 19 | # section below, it can also be suppressed for a single line of code 20 | # or a specific dart file by using the `// ignore: name_of_lint` and 21 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 22 | # producing the lint. 23 | rules: 24 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 25 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 26 | 27 | # Additional information about this file can be found at 28 | # https://dart.dev/guides/language/analysis-options 29 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | .cxx/ 9 | 10 | # Remember to never publicly share your keystore. 11 | # See https://flutter.dev/to/reference-keystore 12 | key.properties 13 | **/*.keystore 14 | **/*.jks 15 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/app/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.application") 3 | id("kotlin-android") 4 | // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. 5 | id("dev.flutter.flutter-gradle-plugin") 6 | } 7 | 8 | android { 9 | namespace = "com.example.example" 10 | compileSdk = flutter.compileSdkVersion 11 | ndkVersion = flutter.ndkVersion 12 | 13 | compileOptions { 14 | sourceCompatibility = JavaVersion.VERSION_11 15 | targetCompatibility = JavaVersion.VERSION_11 16 | } 17 | 18 | kotlinOptions { 19 | jvmTarget = JavaVersion.VERSION_11.toString() 20 | } 21 | 22 | defaultConfig { 23 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 24 | applicationId = "com.example.example" 25 | // You can update the following values to match your application needs. 26 | // For more information, see: https://flutter.dev/to/review-gradle-config. 27 | minSdk = flutter.minSdkVersion 28 | targetSdk = flutter.targetSdkVersion 29 | versionCode = flutter.versionCode 30 | versionName = flutter.versionName 31 | } 32 | 33 | buildTypes { 34 | release { 35 | // TODO: Add your own signing config for the release build. 36 | // Signing with the debug keys for now, so `flutter run --release` works. 37 | signingConfig = signingConfigs.getByName("debug") 38 | } 39 | } 40 | } 41 | 42 | flutter { 43 | source = "../.." 44 | } 45 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 34 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity : FlutterActivity() 6 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/build.gradle.kts: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get() 9 | rootProject.layout.buildDirectory.value(newBuildDir) 10 | 11 | subprojects { 12 | val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) 13 | project.layout.buildDirectory.value(newSubprojectBuildDir) 14 | } 15 | subprojects { 16 | project.evaluationDependsOn(":app") 17 | } 18 | 19 | tasks.register("clean") { 20 | delete(rootProject.layout.buildDirectory) 21 | } 22 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip 6 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/android/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | val flutterSdkPath = run { 3 | val properties = java.util.Properties() 4 | file("local.properties").inputStream().use { properties.load(it) } 5 | val flutterSdkPath = properties.getProperty("flutter.sdk") 6 | require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } 7 | flutterSdkPath 8 | } 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | plugins { 20 | id("dev.flutter.flutter-plugin-loader") version "1.0.0" 21 | id("com.android.application") version "8.7.0" apply false 22 | id("org.jetbrains.kotlin.android") version "1.8.22" apply false 23 | } 24 | 25 | include(":app") 26 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '12.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | 33 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 34 | target 'RunnerTests' do 35 | inherit! :search_paths 36 | end 37 | end 38 | 39 | post_install do |installer| 40 | installer.pods_project.targets.each do |target| 41 | flutter_additional_ios_build_settings(target) 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AgoraInfra_iOS (1.2.13) 3 | - Flutter (1.0.0) 4 | - HyphenateChat (4.13.0): 5 | - AgoraInfra_iOS (= 1.2.13) 6 | - im_flutter_sdk_ios (0.0.1): 7 | - Flutter 8 | - HyphenateChat (= 4.13.0) 9 | 10 | DEPENDENCIES: 11 | - Flutter (from `Flutter`) 12 | - im_flutter_sdk_ios (from `.symlinks/plugins/im_flutter_sdk_ios/ios`) 13 | 14 | SPEC REPOS: 15 | trunk: 16 | - AgoraInfra_iOS 17 | - HyphenateChat 18 | 19 | EXTERNAL SOURCES: 20 | Flutter: 21 | :path: Flutter 22 | im_flutter_sdk_ios: 23 | :path: ".symlinks/plugins/im_flutter_sdk_ios/ios" 24 | 25 | SPEC CHECKSUMS: 26 | AgoraInfra_iOS: 65e11a2183ab7836258768868d06058c22701b13 27 | Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 28 | HyphenateChat: c2ecd32ae5328c027d8e270bdbe63c0902cfc828 29 | im_flutter_sdk_ios: 989968246d61b7472044cd19c93ff2bb70194a10 30 | 31 | PODFILE CHECKSUM: 4305caec6b40dde0ae97be1573c53de1882a07e5 32 | 33 | COCOAPODS: 1.15.2 34 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 43 | 49 | 50 | 51 | 52 | 53 | 64 | 66 | 72 | 73 | 74 | 75 | 81 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | 4 | @main 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 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /im_flutter_sdk/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 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /im_flutter_sdk/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. -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Base.lproj/LaunchScreen.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 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /im_flutter_sdk/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 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | example 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | CADisableMinimumFrameDurationOnPhone 45 | 46 | UIApplicationSupportsIndirectInputEvents 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/ios/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /im_flutter_sdk/example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: example 2 | description: "A new Flutter project." 3 | # The following line prevents the package from being accidentally published to 4 | # pub.dev using `flutter pub publish`. This is preferred for private packages. 5 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 6 | 7 | # The following defines the version and build number for your application. 8 | # A version number is three numbers separated by dots, like 1.2.43 9 | # followed by an optional build number separated by a +. 10 | # Both the version and the builder number may be overridden in flutter 11 | # build by specifying --build-name and --build-number, respectively. 12 | # In Android, build-name is used as versionName while build-number used as versionCode. 13 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 14 | # In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. 15 | # Read more about iOS versioning at 16 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 17 | # In Windows, build-name is used as the major, minor, and patch parts 18 | # of the product and file versions while build-number is used as the build suffix. 19 | version: 1.0.0+1 20 | 21 | 22 | 23 | environment: 24 | sdk: ^3.4.0 25 | 26 | # Dependencies specify other packages that your package needs in order to work. 27 | # To automatically upgrade your package dependencies to the latest versions 28 | # consider running `flutter pub upgrade --major-versions`. Alternatively, 29 | # dependencies can be manually updated by changing the version numbers below to 30 | # the latest version available on pub.dev. To see which dependencies have newer 31 | # versions available, run `flutter pub outdated`. 32 | dependencies: 33 | flutter: 34 | sdk: flutter 35 | 36 | # The following adds the Cupertino Icons font to your application. 37 | # Use with the CupertinoIcons class for iOS style icons. 38 | cupertino_icons: ^1.0.8 39 | 40 | im_flutter_sdk: 41 | path: ../ 42 | 43 | dependency_overrides: 44 | 45 | # im_flutter_sdk_interface: 46 | # path: ../../im_flutter_sdk_interface 47 | 48 | # im_flutter_sdk_ios: 49 | # path: ../../im_flutter_sdk_ios 50 | 51 | # im_flutter_sdk_android: 52 | # path: ../../im_flutter_sdk_android 53 | 54 | dev_dependencies: 55 | flutter_test: 56 | sdk: flutter 57 | 58 | # The "flutter_lints" package below contains a set of recommended lints to 59 | # encourage good coding practices. The lint set provided by the package is 60 | # activated in the `analysis_options.yaml` file located at the root of your 61 | # package. See that file for information about deactivating specific lint 62 | # rules and activating additional ones. 63 | flutter_lints: ^4.0.0 64 | 65 | # For information on the generic Dart part of this file, see the 66 | # following page: https://dart.dev/tools/pub/pubspec 67 | 68 | # The following section is specific to Flutter packages. 69 | flutter: 70 | 71 | # The following line ensures that the Material Icons font is 72 | # included with your application, so that you can use the icons in 73 | # the material Icons class. 74 | uses-material-design: true 75 | 76 | # To add assets to your application, add an assets section, like this: 77 | # assets: 78 | # - images/a_dot_burr.jpeg 79 | # - images/a_dot_ham.jpeg 80 | 81 | # An image asset can refer to one or more resolution-specific "variants", see 82 | # https://flutter.dev/to/resolution-aware-images 83 | 84 | # For details regarding adding assets from package dependencies, see 85 | # https://flutter.dev/to/asset-from-package 86 | 87 | # To add custom fonts to your application, add a fonts section here, 88 | # in this "flutter" section. Each entry in this list should have a 89 | # "family" key with the font family name, and a "fonts" key with a 90 | # list giving the asset and other descriptors for the font. For 91 | # example: 92 | # fonts: 93 | # - family: Schyler 94 | # fonts: 95 | # - asset: fonts/Schyler-Regular.ttf 96 | # - asset: fonts/Schyler-Italic.ttf 97 | # style: italic 98 | # - family: Trajan Pro 99 | # fonts: 100 | # - asset: fonts/TrajanPro.ttf 101 | # - asset: fonts/TrajanPro_Bold.ttf 102 | # weight: 700 103 | # 104 | # For details regarding fonts from package dependencies, 105 | # see https://flutter.dev/to/font-from-package 106 | -------------------------------------------------------------------------------- /im_flutter_sdk/lib/im_flutter_sdk.dart: -------------------------------------------------------------------------------- 1 | export 'package:im_flutter_sdk_interface/im_flutter_sdk_interface.dart' 2 | show 3 | EMConnectionEventHandler, 4 | EMMultiDeviceEventHandler, 5 | EMChatEventHandler, 6 | EMChatRoomEventHandler, 7 | EMChatThreadEventHandler, 8 | EMPresenceEventHandler, 9 | EMContactEventHandler, 10 | EMGroupEventHandler, 11 | ChatSilentModeParam, 12 | ConversationFetchOptions, 13 | ChatMessageEvent, 14 | EMGroupStyle, 15 | EMConversationType, 16 | EMTextMessageBody, 17 | EMImageMessageBody, 18 | EMVoiceMessageBody, 19 | EMVideoMessageBody, 20 | EMLocationMessageBody, 21 | EMFileMessageBody, 22 | EMCustomMessageBody, 23 | EMCmdMessageBody, 24 | EMCombineMessageBody, 25 | EMMessageBody, 26 | ChatType, 27 | MessageDirection, 28 | MessageStatus, 29 | DownloadStatus, 30 | MessageType, 31 | EMGroupPermissionType, 32 | EMChatRoomPermissionType, 33 | EMSearchDirection, 34 | EMMultiDevicesEvent, 35 | EMChatThreadOperation, 36 | DisplayStyle, 37 | ChatSilentModeParamType, 38 | ChatPushRemindType, 39 | ChatRoomMessagePriority, 40 | ReactionOperate, 41 | LeaveReason, 42 | MessagePinOperation, 43 | MessageSearchScope, 44 | ConversationMarkType, 45 | EMChatRoom, 46 | EMChatThread, 47 | EMContact, 48 | EMConversation, 49 | EMCursorResult, 50 | EMDeviceInfo, 51 | EMDownloadCallback, 52 | EMError, 53 | EMGroupMessageAck, 54 | EMGroupOptions, 55 | EMGroupSharedFile, 56 | EMGroup, 57 | EMMessageReaction, 58 | EMMessage, 59 | EMOptions, 60 | ExtSettings, 61 | EMPageResult, 62 | EMPresence, 63 | EMPushConfigs, 64 | EMTranslateLanguage, 65 | EMUserInfo, 66 | FetchMessageOptions, 67 | ReactionOperation, 68 | RecallMessageInfo, 69 | EMMessageReactionEvent, 70 | EMGroupInfo, 71 | ChatSilentModeResult, 72 | EMChatThreadEvent, 73 | ChatSilentModeTime, 74 | MessagePinInfo, 75 | LoginExtensionInfo, 76 | MessageSearchOptions, 77 | ChatAreaCode; 78 | 79 | export 'src/chat_manager.dart'; 80 | export 'src/chat_room_manager.dart'; 81 | export 'src/chat_thread_manager.dart'; 82 | export 'src/client.dart'; 83 | export 'src/contact_manager.dart'; 84 | export 'src/group_manager.dart'; 85 | export 'src/presence_manager.dart'; 86 | export 'src/push_manager.dart'; 87 | export 'src/user_info_manager.dart'; 88 | -------------------------------------------------------------------------------- /im_flutter_sdk/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: im_flutter_sdk 2 | description: Integrate the Chat SDK to enjoy the global IM services with high reliability, ultra-low latency, and high concurrency. 3 | version: 4.13.0+1 4 | homepage: https://www.easemob.com 5 | 6 | environment: 7 | sdk: '>=3.3.0 <4.0.0' 8 | flutter: '>=3.3.0' 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | im_flutter_sdk_interface: ^4.13.0+1 15 | 16 | im_flutter_sdk_ios: ^4.13.0+1 17 | 18 | im_flutter_sdk_android: ^4.13.0+1 19 | 20 | 21 | dev_dependencies: 22 | flutter_lints: ^4.0.0 23 | 24 | 25 | flutter: 26 | plugin: 27 | platforms: 28 | ios: 29 | default_package: im_flutter_sdk_ios 30 | android: 31 | default_package: im_flutter_sdk_android 32 | ohos: 33 | default_package: im_flutter_sdk_ohos 34 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 26 | /pubspec.lock 27 | **/doc/api/ 28 | .dart_tool/ 29 | build/ 30 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/.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: "7f2ea2ea242b1ae845ad5eaf5b210c2c67da9b78" 8 | channel: "oh-3.22.0" 9 | 10 | project_type: plugin 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 7f2ea2ea242b1ae845ad5eaf5b210c2c67da9b78 17 | base_revision: 7f2ea2ea242b1ae845ad5eaf5b210c2c67da9b78 18 | - platform: android 19 | create_revision: 7f2ea2ea242b1ae845ad5eaf5b210c2c67da9b78 20 | base_revision: 7f2ea2ea242b1ae845ad5eaf5b210c2c67da9b78 21 | 22 | # User provided section 23 | 24 | # List of Local paths (relative to this file) that should be 25 | # ignored by the migrate tool. 26 | # 27 | # Files that are not part of the templates will be ignored by default. 28 | unmanaged_files: 29 | - 'lib/main.dart' 30 | - 'ios/Runner.xcodeproj/project.pbxproj' 31 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 4.13.0+1 2 | 3 | - 修复收到 `onAnnouncementChangedFromChatRoom` 回调时,`announcement` 为空导致的崩溃问题。 4 | - 修复收到 `onAnnouncementChangedFromGroup` 回调时,`announcement` 为空导致的崩溃问题。 5 | 6 | ## 4.13.0 7 | 8 | * 更新原生sdk为 4.13.0 9 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /im_flutter_sdk_android/README.md: -------------------------------------------------------------------------------- 1 | # im_flutter_sdk_android 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter 8 | [plug-in package](https://flutter.dev/developing-packages/), 9 | a specialized package that includes platform-specific implementation code for 10 | Android and/or iOS. 11 | 12 | For help getting started with Flutter development, view the 13 | [online documentation](https://flutter.dev/docs), which offers tutorials, 14 | samples, guidance on mobile development, and a full API reference. 15 | 16 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | # Additional information about this file can be found at 4 | # https://dart.dev/guides/language/analysis-options 5 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.easemob.im_flutter_sdk' 2 | version '1.0-SNAPSHOT' 3 | 4 | 5 | buildscript { 6 | repositories { 7 | google() 8 | mavenCentral() 9 | } 10 | 11 | dependencies { 12 | classpath("com.android.tools.build:gradle:7.3.0") 13 | } 14 | } 15 | 16 | allprojects { 17 | repositories { 18 | google() 19 | mavenCentral() 20 | } 21 | } 22 | 23 | apply plugin: 'com.android.library' 24 | 25 | android { 26 | 27 | if (project.android.hasProperty("namespace")) { 28 | namespace = "com.easemob.im_flutter_sdk" 29 | } 30 | 31 | compileSdk = 34 32 | 33 | compileOptions { 34 | sourceCompatibility = JavaVersion.VERSION_1_8 35 | targetCompatibility = JavaVersion.VERSION_1_8 36 | } 37 | 38 | defaultConfig { 39 | minSdk = 21 40 | } 41 | } 42 | 43 | tasks.withType(JavaCompile){ 44 | options.encoding = "UTF-8" 45 | } 46 | 47 | dependencies { 48 | api 'androidx.appcompat:appcompat:1.1.0' 49 | // implementation 'cn.shengwang:chat-sdk:1.3.2' 50 | implementation 'io.hyphenate:hyphenate-chat:4.13.0' 51 | implementation fileTree(dir: 'libs', include: ['*.jar']) 52 | } 53 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk_android/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /im_flutter_sdk_android/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Oct 01 18:32:53 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 | distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.5-all.zip -------------------------------------------------------------------------------- /im_flutter_sdk_android/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'im_flutter_sdk' 2 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/android/src/main/java/com/easemob/im_flutter_sdk/CommonUtil.java: -------------------------------------------------------------------------------- 1 | package com.easemob.im_flutter_sdk; 2 | 3 | import org.json.JSONException; 4 | import org.json.JSONObject; 5 | 6 | import java.util.Map; 7 | 8 | public class CommonUtil { 9 | 10 | static public void putObjectToMap(Map map, String key, Object value) { 11 | if (value != null) 12 | { 13 | map.put(key, value); 14 | } 15 | } 16 | 17 | static Object getValueFromMap(Map map, String key) { 18 | if (map.containsKey(key)) { 19 | return map.get(key); 20 | } 21 | return null; 22 | } 23 | 24 | static Object getValueFromJsonObject(JSONObject jo, String key) { 25 | if (jo.has(key)) { 26 | try { 27 | return jo.get(key); 28 | } catch (JSONException e) { 29 | e.printStackTrace(); 30 | } 31 | } 32 | return null; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/android/src/main/java/com/easemob/im_flutter_sdk/HelpTool.java: -------------------------------------------------------------------------------- 1 | package com.easemob.im_flutter_sdk; 2 | import com.hyphenate.chat.EMMessage; 3 | import org.json.JSONArray; 4 | import org.json.JSONException; 5 | import org.json.JSONObject; 6 | import java.util.Map; 7 | public class HelpTool { 8 | public static void mergeMessage(EMMessage msg, EMMessage dbMsg) throws JSONException { 9 | dbMsg.setMsgTime(msg.getMsgTime()); 10 | dbMsg.setLocalTime(msg.localTime()); 11 | dbMsg.setStatus(msg.status()); 12 | dbMsg.setAcked(msg.isAcked()); 13 | dbMsg.setIsChatThreadMessage(msg.isChatThreadMessage()); 14 | dbMsg.setIsNeedGroupAck(msg.isNeedGroupAck()); 15 | dbMsg.setDeliverAcked(msg.isDelivered()); 16 | dbMsg.setUnread(msg.isUnread()); 17 | dbMsg.setListened(msg.isListened()); 18 | dbMsg.setReceiverList(msg.receiverList()); 19 | dbMsg.deliverOnlineOnly(msg.isDeliverOnlineOnly()); 20 | Map list = msg.getAttributes(); 21 | if (!list.isEmpty()) { 22 | JSONObject jsonParams = new JSONObject(list); 23 | for (Map.Entry entry : list.entrySet()) { 24 | String key = entry.getKey(); 25 | Object result = entry.getValue(); 26 | if (result.getClass().getSimpleName().equals("Integer")) { 27 | dbMsg.setAttribute(key, (Integer)result); 28 | } else if (result.getClass().getSimpleName().equals("Boolean")) { 29 | dbMsg.setAttribute(key, (Boolean)result); 30 | } else if (result.getClass().getSimpleName().equals("Long")) { 31 | dbMsg.setAttribute(key, (Long)result); 32 | } else if (result.getClass().getSimpleName().equals("Double") || 33 | result.getClass().getSimpleName().equals("Float")) { 34 | dbMsg.setAttribute(key, (Double)result); 35 | } else if (result.getClass().getSimpleName().equals("JSONObject")) { 36 | dbMsg.setAttribute(key, (JSONObject)result); 37 | } else if (result.getClass().getSimpleName().equals("JSONArray")) { 38 | dbMsg.setAttribute(key, (JSONArray)result); 39 | } else { 40 | dbMsg.setAttribute(key, jsonParams.getString(key)); 41 | } 42 | } 43 | } 44 | dbMsg.setBody(msg.getBody()); 45 | } 46 | } -------------------------------------------------------------------------------- /im_flutter_sdk_android/android/src/main/java/com/easemob/im_flutter_sdk/ListenerHandle.java: -------------------------------------------------------------------------------- 1 | package com.easemob.im_flutter_sdk; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class ListenerHandle { 7 | 8 | static private ListenerHandle handle; 9 | 10 | private List emActionHandle; 11 | 12 | private boolean hasReady; 13 | 14 | 15 | public static ListenerHandle getInstance() { 16 | if (handle == null) { 17 | handle = new ListenerHandle(); 18 | } 19 | return handle; 20 | } 21 | 22 | private ListenerHandle(){ 23 | emActionHandle = new ArrayList<>(); 24 | } 25 | 26 | void addHandle(Runnable runnable) { 27 | emActionHandle.add(runnable); 28 | if (hasReady) { 29 | runHandle(); 30 | } 31 | } 32 | 33 | void runHandle() { 34 | synchronized (emActionHandle){ 35 | List tmp = emActionHandle; 36 | for (Runnable action : tmp) { 37 | action.run(); 38 | } 39 | emActionHandle.clear(); 40 | } 41 | } 42 | 43 | void startCallback(){ 44 | hasReady = true; 45 | runHandle(); 46 | } 47 | 48 | void clearHandle(){ 49 | hasReady = false; 50 | synchronized (emActionHandle) { 51 | emActionHandle.clear(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/android/src/main/java/com/easemob/im_flutter_sdk/MessageWrapper.java: -------------------------------------------------------------------------------- 1 | package com.easemob.im_flutter_sdk; 2 | 3 | import com.hyphenate.chat.EMClient; 4 | import com.hyphenate.chat.EMMessage; 5 | import com.hyphenate.chat.EMMessageReaction; 6 | 7 | import org.json.JSONException; 8 | import org.json.JSONObject; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 15 | import io.flutter.plugin.common.MethodCall; 16 | import io.flutter.plugin.common.MethodChannel; 17 | 18 | public class MessageWrapper extends Wrapper implements MethodChannel.MethodCallHandler { 19 | public MessageWrapper(FlutterPlugin.FlutterPluginBinding flutterPluginBinding, String channelName) { 20 | super(flutterPluginBinding, channelName); 21 | } 22 | 23 | 24 | @Override 25 | public void onMethodCall(MethodCall call, MethodChannel.Result result) { 26 | 27 | JSONObject param = (JSONObject)call.arguments; 28 | 29 | try { 30 | if (MethodKey.getReactionList.equals(call.method)) { 31 | reactionList(param, call.method, result); 32 | }else if (MethodKey.groupAckCount.equals(call.method)){ 33 | getAckCount(param, call.method, result); 34 | }else if (MethodKey.getChatThread.equals(call.method)) { 35 | getChatThread(param, call.method, result); 36 | } 37 | // 450 38 | else if (MethodKey.getPinInfo.equals(call.method)) { 39 | getPinInfo(param, call.method, result); 40 | } 41 | else 42 | { 43 | super.onMethodCall(call, result); 44 | } 45 | } catch (JSONException e) { 46 | e.printStackTrace(); 47 | } 48 | } 49 | 50 | 51 | private void reactionList(JSONObject params, String channelName, MethodChannel.Result result) throws JSONException { 52 | String msgId = params.getString("msgId"); 53 | EMMessage msg = getMessageWithId(msgId); 54 | ArrayList> list = new ArrayList<>(); 55 | if (msg != null) { 56 | List reactions = msg.getMessageReaction(); 57 | if (reactions != null) { 58 | for (int i = 0; i < reactions.size(); i++) { 59 | list.add(MessageReactionHelper.toJson(reactions.get(i))); 60 | } 61 | } 62 | } 63 | onSuccess(result, channelName, list); 64 | } 65 | 66 | 67 | private void getAckCount(JSONObject params, String channelName, MethodChannel.Result result) throws JSONException { 68 | String msgId = params.getString("msgId"); 69 | EMMessage msg = getMessageWithId(msgId); 70 | asyncRunnable(()->{ 71 | onSuccess(result, channelName, msg != null ? msg.groupAckCount() : 0); 72 | }); 73 | } 74 | 75 | private void getChatThread(JSONObject params, String channelName, MethodChannel.Result result) throws JSONException { 76 | String msgId = params.getString("msgId"); 77 | EMMessage msg = getMessageWithId(msgId); 78 | asyncRunnable(()->{ 79 | if (msg != null) { 80 | onSuccess(result, channelName, msg.getChatThread() != null ? ChatThreadHelper.toJson(msg.getChatThread()) : null); 81 | }else { 82 | onSuccess(result, channelName, null); 83 | } 84 | }); 85 | } 86 | private void getPinInfo(JSONObject params, String channelName, MethodChannel.Result result) throws JSONException { 87 | String msgId = params.getString("msgId"); 88 | EMMessage msg = getMessageWithId(msgId); 89 | asyncRunnable(()->{ 90 | if (msg != null) { 91 | onSuccess(result, channelName, msg.pinnedInfo() != null ? MessagePinInfoHelper.toJson(msg.pinnedInfo()) : null); 92 | }else { 93 | onSuccess(result, channelName, null); 94 | } 95 | }); 96 | } 97 | 98 | private EMMessage getMessageWithId(String msgId) { 99 | return EMClient.getInstance().chatManager().getMessage(msgId); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/android/src/main/java/com/easemob/im_flutter_sdk/ProgressManager.java: -------------------------------------------------------------------------------- 1 | package com.easemob.im_flutter_sdk; 2 | 3 | import com.hyphenate.exceptions.HyphenateException; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 9 | import io.flutter.plugin.common.MethodChannel; 10 | 11 | public class ProgressManager extends Wrapper implements MethodChannel.MethodCallHandler { 12 | 13 | public ProgressManager(FlutterPlugin.FlutterPluginBinding flutterPluginBinding, String channelName) { 14 | super(flutterPluginBinding, channelName); 15 | } 16 | 17 | public void sendDownloadProgressToFlutter(String fileId, int progress){ 18 | HashMap data = new HashMap<>(); 19 | data.put("fileId", fileId); 20 | data.put("progress", progress); 21 | post(()->{ 22 | channel.invokeMethod("onProgress", data); 23 | }); 24 | } 25 | 26 | public void sendDownloadSuccessToFlutter(String fileId, String savePath) { 27 | HashMap data = new HashMap<>(); 28 | data.put("fileId", fileId); 29 | data.put("savePath", savePath); 30 | post(()->{ 31 | channel.invokeMethod("onSuccess", data); 32 | }); 33 | } 34 | 35 | public void sendDownloadErrorToFlutter(String fileId, HyphenateException e) { 36 | Map error = new HashMap<>(); 37 | error.put("code", e.getErrorCode()); 38 | error.put("description", e.getDescription()); 39 | HashMap data = new HashMap<>(); 40 | data.put("fileId", fileId); 41 | data.put("error", error); 42 | post(()->{ 43 | channel.invokeMethod("onError", data); 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/android/src/main/java/com/easemob/im_flutter_sdk/Wrapper.java: -------------------------------------------------------------------------------- 1 | package com.easemob.im_flutter_sdk; 2 | 3 | import android.content.Context; 4 | 5 | import com.hyphenate.exceptions.HyphenateException; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | import java.util.concurrent.ExecutorService; 10 | import java.util.concurrent.Executors; 11 | 12 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 13 | import io.flutter.plugin.common.JSONMethodCodec; 14 | import io.flutter.plugin.common.MethodCall; 15 | import io.flutter.plugin.common.MethodChannel; 16 | 17 | 18 | public class Wrapper implements MethodChannel.MethodCallHandler { 19 | 20 | private static final String CHANNEL_PREFIX = "com.chat.im/"; 21 | 22 | private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); 23 | private final ExecutorService cachedThreadPool = Executors.newFixedThreadPool(CPU_COUNT + 1); 24 | 25 | public Wrapper(FlutterPlugin.FlutterPluginBinding flutterPluginBinding, String channelName) { 26 | this.context = flutterPluginBinding.getApplicationContext(); 27 | this.binging = flutterPluginBinding; 28 | this.channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), CHANNEL_PREFIX + channelName, JSONMethodCodec.INSTANCE); 29 | channel.setMethodCallHandler(this); 30 | } 31 | 32 | public Context context; 33 | public FlutterPlugin.FlutterPluginBinding binging; 34 | public MethodChannel channel; 35 | 36 | 37 | public void post(Runnable runnable) { 38 | ImFlutterSdkPlugin.handler.post(runnable); 39 | } 40 | 41 | public void asyncRunnable(Runnable runnable) { 42 | cachedThreadPool.execute(runnable); 43 | } 44 | 45 | public void onSuccess(MethodChannel.Result result, String channelName, Object object) { 46 | post(()-> { 47 | Map data = new HashMap<>(); 48 | if (object != null) { 49 | data.put(channelName, object); 50 | } 51 | result.success(data); 52 | }); 53 | } 54 | 55 | public void unRegisterEaseListener() {} 56 | 57 | public void onError(MethodChannel.Result result, HyphenateException e) { 58 | post(()-> { 59 | Map data = new HashMap<>(); 60 | data.put("error", HyphenateExceptionHelper.toJson(e)); 61 | result.success(data); 62 | }); 63 | } 64 | 65 | @Override 66 | public void onMethodCall(MethodCall call, MethodChannel.Result result) { 67 | result.notImplemented(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/lib/im_flutter_sdk_android.dart: -------------------------------------------------------------------------------- 1 | export 'src/client_android.dart'; 2 | -------------------------------------------------------------------------------- /im_flutter_sdk_android/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: im_flutter_sdk_android 2 | description: Integrate the Chat SDK to enjoy the global IM services with high reliability, ultra-low latency, and high concurrency. 3 | version: 4.13.0+1 4 | homepage: https://www.easemob.com 5 | 6 | environment: 7 | sdk: '>=3.3.0 <4.0.0' 8 | flutter: '>=3.3.0' 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | im_flutter_sdk_interface: ^4.13.0+1 15 | 16 | dev_dependencies: 17 | flutter_test: 18 | sdk: flutter 19 | flutter_lints: ^3.0.0 20 | 21 | flutter: 22 | 23 | plugin: 24 | implements: im_flutter_sdk 25 | platforms: 26 | android: 27 | dartPluginClass: ClientAndroid 28 | package: com.easemob.im_flutter_sdk 29 | pluginClass: ImFlutterSdkPlugin 30 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 26 | /pubspec.lock 27 | **/doc/api/ 28 | .dart_tool/ 29 | build/ 30 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/.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: "7f2ea2ea242b1ae845ad5eaf5b210c2c67da9b78" 8 | channel: "oh-3.22.0" 9 | 10 | project_type: plugin 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 7f2ea2ea242b1ae845ad5eaf5b210c2c67da9b78 17 | base_revision: 7f2ea2ea242b1ae845ad5eaf5b210c2c67da9b78 18 | 19 | # User provided section 20 | 21 | # List of Local paths (relative to this file) that should be 22 | # ignored by the migrate tool. 23 | # 24 | # Files that are not part of the templates will be ignored by default. 25 | unmanaged_files: 26 | - 'lib/main.dart' 27 | - 'ios/Runner.xcodeproj/project.pbxproj' 28 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 4.13.0+1 2 | 3 | - 增加 `EMMultiDevicesEvent.UnKnow` 类型,防止新增多设备事件时无法解析; 4 | 5 | ## 4.13.0 6 | 7 | * 首次修改为联合插件模式 8 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /im_flutter_sdk_interface/README.md: -------------------------------------------------------------------------------- 1 | # im_flutter_sdk_interface 2 | 3 | A new Flutter plugin project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter 8 | [plug-in package](https://flutter.dev/developing-packages/), 9 | a specialized package that includes platform-specific implementation code for 10 | Android and/or iOS. 11 | 12 | For help getting started with Flutter development, view the 13 | [online documentation](https://flutter.dev/docs), which offers tutorials, 14 | samples, guidance on mobile development, and a full API reference. 15 | 16 | The plugin project was generated without specifying the `--platforms` flag, no platforms are currently supported. 17 | To add platforms, run `flutter create -t plugin --platforms .` in this directory. 18 | You can also find a detailed instruction on how to add platforms in the `pubspec.yaml` at https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin-platforms. 19 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | # Additional information about this file can be found at 4 | # https://dart.dev/guides/language/analysis-options 5 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/im_flutter_sdk_interface.dart: -------------------------------------------------------------------------------- 1 | export 'package:im_flutter_sdk_interface/interface/platform_interface/client.dart'; 2 | export 'package:im_flutter_sdk_interface/interface/platform_interface/chat_manager.dart'; 3 | export 'package:im_flutter_sdk_interface/interface/platform_interface/chat_room_manager.dart'; 4 | export 'package:im_flutter_sdk_interface/interface/platform_interface/chat_thread_manager.dart'; 5 | export 'package:im_flutter_sdk_interface/interface/platform_interface/contact_manager.dart'; 6 | export 'package:im_flutter_sdk_interface/interface/platform_interface/group_manager.dart'; 7 | export 'package:im_flutter_sdk_interface/interface/platform_interface/presence_manager.dart'; 8 | export 'package:im_flutter_sdk_interface/interface/platform_interface/push_manager.dart'; 9 | export 'package:im_flutter_sdk_interface/interface/platform_interface/user_info_manager.dart'; 10 | export 'package:im_flutter_sdk_interface/interface/platform_interface/progress_manager.dart'; 11 | 12 | export 'src/models/em_group_message_ack.dart'; 13 | export 'src/models/em_chat_room.dart'; 14 | export 'src/models/em_conversation.dart'; 15 | export 'src/models/em_cursor_result.dart'; 16 | export 'src/models/em_contact.dart'; 17 | export 'src/models/em_device_info.dart'; 18 | export 'src/models/em_error.dart'; 19 | export 'src/models/em_group.dart'; 20 | export 'src/models/em_translate_language.dart'; 21 | export 'src/models/em_presence.dart'; 22 | export 'src/models/login_extension_info.dart'; 23 | export 'src/models/message_search_options.dart'; 24 | 25 | export 'src/models/em_options.dart'; 26 | export 'src/models/em_push_configs.dart'; 27 | export 'src/models/em_page_result.dart'; 28 | export 'src/models/em_user_info.dart'; 29 | export 'src/models/em_group_shared_file.dart'; 30 | export 'src/models/em_group_options.dart'; 31 | export 'src/models/fetch_message_options.dart'; 32 | export 'src/models/em_chat_enums.dart'; 33 | export 'src/models/reaction_operation.dart'; 34 | export 'src/models/message_pin_info.dart'; 35 | 36 | export 'src/models/em_message.dart'; 37 | export 'src/models/em_download_callback.dart'; 38 | export 'src/models/em_message_reaction.dart'; 39 | export 'src/models/em_chat_thread.dart'; 40 | export 'src/models/chat_silent_mode.dart'; 41 | export 'src/event_handler/manager_event_handler.dart'; 42 | export 'src/tools/chat_area_code.dart'; 43 | export 'src/models/conversation_fetch_options.dart'; 44 | export 'src/models/recall_message_info.dart'; 45 | 46 | export 'src/internal/chat_method_keys.dart'; 47 | export 'src/internal/em_channel_manager.dart'; 48 | export 'src/internal/em_event_keys.dart'; 49 | export 'src/internal/em_push_config.dart'; 50 | export 'src/internal/em_transform_tools.dart'; 51 | export 'src/internal/inner_headers.dart'; 52 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/interface/manager_mixin.dart: -------------------------------------------------------------------------------- 1 | mixin ManagerMixin { 2 | void initHandler(); 3 | } 4 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/interface/method_channel/default_channels.dart: -------------------------------------------------------------------------------- 1 | import 'package:im_flutter_sdk_interface/interface/platform_interface/chat_manager.dart'; 2 | import 'package:im_flutter_sdk_interface/interface/platform_interface/chat_room_manager.dart'; 3 | import 'package:im_flutter_sdk_interface/interface/platform_interface/chat_thread_manager.dart'; 4 | import 'package:im_flutter_sdk_interface/interface/platform_interface/contact_manager.dart'; 5 | import 'package:im_flutter_sdk_interface/interface/platform_interface/group_manager.dart'; 6 | import 'package:im_flutter_sdk_interface/interface/platform_interface/presence_manager.dart'; 7 | import 'package:im_flutter_sdk_interface/interface/platform_interface/push_manager.dart'; 8 | import 'package:im_flutter_sdk_interface/interface/platform_interface/user_info_manager.dart'; 9 | 10 | import '../platform_interface/client.dart'; 11 | import '../platform_interface/progress_manager.dart'; 12 | 13 | class ClientDefault extends Client { 14 | @override 15 | void initHandler() {} 16 | } 17 | 18 | class ChatManagerDefault extends ChatManager {} 19 | 20 | class ChatRoomManagerDefault extends ChatRoomManager {} 21 | 22 | class ChatThreadManagerDefault extends ChatThreadManager {} 23 | 24 | class ContactManagerDefault extends ContactManager {} 25 | 26 | class GroupManagerDefault extends GroupManager {} 27 | 28 | class PresenceManagerDefault extends PresenceManager {} 29 | 30 | class PushManagerDefault extends PushManager {} 31 | 32 | class UserInfoManagerDefault extends UserInfoManager {} 33 | 34 | class ProgressManagerDefault extends ProgressManager {} 35 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/interface/platform_interface/progress_manager.dart: -------------------------------------------------------------------------------- 1 | import 'package:im_flutter_sdk_interface/im_flutter_sdk_interface.dart'; 2 | import 'package:im_flutter_sdk_interface/interface/manager_mixin.dart'; 3 | 4 | class ProgressManager with ManagerMixin { 5 | @override 6 | void initHandler() { 7 | ProgressChannel.setMethodCallHandler((call) async { 8 | Map? arg = call.arguments; 9 | if (arg != null) { 10 | if (call.method == "onSuccess") { 11 | _onSuccess(arg); 12 | } else if (call.method == "onProgress") { 13 | _onProgress(arg); 14 | } else if (call.method == "onError") { 15 | _onError(arg); 16 | } 17 | } 18 | }); 19 | } 20 | 21 | Future _onSuccess(Map map) async { 22 | String fileId = map["fileId"]; 23 | String path = map["savePath"]; 24 | Client.instance.groupManager.downloadCallback?.onSuccess 25 | ?.call(fileId, path); 26 | } 27 | 28 | Future? _onProgress(Map map) async { 29 | String fileId = map["fileId"]; 30 | int progress = map["progress"]; 31 | Client.instance.groupManager.downloadCallback?.onProgress 32 | ?.call(fileId, progress); 33 | } 34 | 35 | Future? _onError(Map map) async { 36 | String fileId = map["fileId"]; 37 | EMError err = EMError.fromJson(map["error"]); 38 | Client.instance.groupManager.downloadCallback?.onError?.call(fileId, err); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/internal/em_channel_manager.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: constant_identifier_names 2 | 3 | import 'package:flutter/services.dart'; 4 | 5 | const channelPrefix = 'com.chat.im'; 6 | 7 | const MethodChannel ChatChannel = MethodChannel( 8 | '$channelPrefix/chat_manager', 9 | JSONMethodCodec(), 10 | ); 11 | 12 | const MethodChannel ChatRoomChannel = MethodChannel( 13 | '$channelPrefix/chat_room_manager', 14 | JSONMethodCodec(), 15 | ); 16 | 17 | const MethodChannel ThreadChannel = MethodChannel( 18 | '$channelPrefix/chat_thread_manager', 19 | JSONMethodCodec(), 20 | ); 21 | 22 | const MethodChannel ContactChannel = MethodChannel( 23 | '$channelPrefix/chat_contact_manager', 24 | JSONMethodCodec(), 25 | ); 26 | 27 | const MethodChannel GroupChannel = MethodChannel( 28 | '$channelPrefix/chat_group_manager', 29 | JSONMethodCodec(), 30 | ); 31 | 32 | const MethodChannel PresenceChannel = MethodChannel( 33 | '$channelPrefix/chat_presence_manager', 34 | JSONMethodCodec(), 35 | ); 36 | 37 | const MethodChannel ProgressChannel = MethodChannel( 38 | "$channelPrefix/file_progress_manager", 39 | JSONMethodCodec(), 40 | ); 41 | 42 | const MethodChannel ClientChannel = MethodChannel( 43 | '$channelPrefix/chat_client', 44 | JSONMethodCodec(), 45 | ); 46 | 47 | const MethodChannel PushChannel = MethodChannel( 48 | '$channelPrefix/chat_push_manager', 49 | JSONMethodCodec(), 50 | ); 51 | 52 | const MethodChannel UserInfoChannel = MethodChannel( 53 | '$channelPrefix/chat_userInfo_manager', 54 | JSONMethodCodec(), 55 | ); 56 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/internal/em_event_keys.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: constant_identifier_names 2 | 3 | class EMContactChangeEvent { 4 | static const String CONTACT_ADD = 'onContactAdded'; 5 | static const String CONTACT_DELETE = 'onContactDeleted'; 6 | static const String INVITED = 'onContactInvited'; 7 | static const String INVITATION_ACCEPTED = 'onFriendRequestAccepted'; 8 | static const String INVITATION_DECLINED = 'onFriendRequestDeclined'; 9 | } 10 | 11 | class EMChatRoomEvent { 12 | static const String ON_CHAT_ROOM_DESTROYED = "onRoomDestroyed"; 13 | static const String ON_MEMBER_JOINED = "onRoomMemberJoined"; 14 | static const String ON_MEMBER_EXITED = "onRoomMemberExited"; 15 | static const String ON_REMOVED_FROM_CHAT_ROOM = "onRoomRemoved"; 16 | static const String ON_MUTE_LIST_ADDED = "onRoomMuteListAdded"; 17 | static const String ON_MUTE_LIST_REMOVED = "onRoomMuteListRemoved"; 18 | static const String ON_ADMIN_ADDED = "onRoomAdminAdded"; 19 | static const String ON_ADMIN_REMOVED = "onRoomAdminRemoved"; 20 | static const String ON_OWNER_CHANGED = "onRoomOwnerChanged"; 21 | static const String ON_ANNOUNCEMENT_CHANGED = "onRoomAnnouncementChanged"; 22 | static const String ON_WHITE_LIST_REMOVED = "onRoomWhiteListRemoved"; 23 | static const String ON_WHITE_LIST_ADDED = "onRoomWhiteListAdded"; 24 | static const String ON_ALL_MEMBER_MUTE_STATE_CHANGED = 25 | "onRoomAllMemberMuteStateChanged"; 26 | static const String ON_SPECIFICATION_CHANGED = "onRoomSpecificationChanged"; 27 | static const String ON_ATTRIBUTES_UPDATED = "onRoomAttributesDidUpdated"; 28 | static const String ON_ATTRIBUTES_REMOVED = "onRoomAttributesDidRemoved"; 29 | } 30 | 31 | class EMGroupChangeEvent { 32 | static const String ON_INVITATION_RECEIVED = "onGroupInvitationReceived"; 33 | static const String ON_INVITATION_ACCEPTED = "onGroupInvitationAccepted"; 34 | static const String ON_INVITATION_DECLINED = "onGroupInvitationDeclined"; 35 | static const String ON_AUTO_ACCEPT_INVITATION = "onGroupAutoAcceptInvitation"; 36 | static const String ON_USER_REMOVED = "onGroupUserRemoved"; 37 | static const String ON_REQUEST_TO_JOIN_RECEIVED = 38 | "onGroupRequestToJoinReceived"; 39 | static const String ON_REQUEST_TO_JOIN_DECLINED = 40 | "onGroupRequestToJoinDeclined"; 41 | static const String ON_REQUEST_TO_JOIN_ACCEPTED = 42 | "onGroupRequestToJoinAccepted"; 43 | static const String ON_GROUP_DESTROYED = "onGroupDestroyed"; 44 | static const String ON_MUTE_LIST_ADDED = "onGroupMuteListAdded"; 45 | static const String ON_MUTE_LIST_REMOVED = "onGroupMuteListRemoved"; 46 | static const String ON_ADMIN_ADDED = "onGroupAdminAdded"; 47 | static const String ON_ADMIN_REMOVED = "onGroupAdminRemoved"; 48 | static const String ON_OWNER_CHANGED = "onGroupOwnerChanged"; 49 | static const String ON_MEMBER_JOINED = "onGroupMemberJoined"; 50 | static const String ON_MEMBER_EXITED = "onGroupMemberExited"; 51 | static const String ON_ANNOUNCEMENT_CHANGED = "onGroupAnnouncementChanged"; 52 | static const String ON_SHARED_FILE_ADDED = "onGroupSharedFileAdded"; 53 | static const String ON_SHARED_FILE__DELETED = "onGroupSharedFileDeleted"; 54 | static const String ON_WHITE_LIST_REMOVED = "onGroupWhiteListRemoved"; 55 | static const String ON_WHITE_LIST_ADDED = "onGroupWhiteListAdded"; 56 | static const String ON_ALL_MEMBER_MUTE_STATE_CHANGED = 57 | "onGroupAllMemberMuteStateChanged"; 58 | static const String ON_SPECIFICATION_DID_UPDATE = 59 | "onGroupSpecificationDidUpdate"; 60 | static const String ON_STATE_CHANGED = "onGroupStateChanged"; 61 | static const String ON_ATTRIBUTES_CHANGED_OF_MEMBER = 62 | "onGroupAttributesChangedOfMember"; 63 | } 64 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/internal/em_push_config.dart: -------------------------------------------------------------------------------- 1 | import 'inner_headers.dart'; 2 | 3 | /// ~english 4 | /// The push configuration class, which contains the push configuration information, such as the push style. 5 | /// ~end 6 | class EMPushConfig { 7 | String mzAppId = ''; 8 | String mzAppKey = ''; 9 | 10 | String oppoAppKey = ''; 11 | String oppoAppSecret = ''; 12 | 13 | String miAppId = ''; 14 | String miAppKey = ''; 15 | 16 | String fcmId = ''; 17 | 18 | String apnsCertName = ''; 19 | 20 | bool enableMeiZuPush = false; 21 | bool enableOppoPush = false; 22 | bool enableMiPush = false; 23 | 24 | bool enableFCM = false; 25 | 26 | bool enableVivoPush = false; 27 | bool agreePrivacyStatement = false; 28 | bool enableHWPush = false; 29 | bool enableHonorPush = false; 30 | bool enableAPNS = false; 31 | 32 | EMPushConfig(); 33 | 34 | void updateFromJson(Map json) { 35 | miAppId = json["mzAppId"]; 36 | mzAppKey = json["mzAppKey"]; 37 | oppoAppKey = json["oppoAppKey"]; 38 | oppoAppSecret = json["oppoAppSecret"]; 39 | miAppId = json["miAppId"]; 40 | miAppKey = json["miAppKey"]; 41 | fcmId = json["fcmId"]; 42 | apnsCertName = json["apnsCertName"]; 43 | enableMeiZuPush = json.boolValue('enableMeiZuPush'); 44 | enableOppoPush = json.boolValue('enableOppoPush'); 45 | enableMiPush = json.boolValue('enableMiPush'); 46 | enableFCM = json.boolValue('enableFCM'); 47 | enableVivoPush = json.boolValue('enableVivoPush'); 48 | agreePrivacyStatement = json.boolValue('agreePrivacyStatement'); 49 | enableHWPush = json.boolValue('enableHWPush'); 50 | enableAPNS = json.boolValue('enableAPNS'); 51 | enableHonorPush = json.boolValue('enableHonorPush'); 52 | } 53 | 54 | Map toJson() { 55 | final Map data = {}; 56 | data.putIfNotNull("mzAppId", mzAppId); 57 | data.putIfNotNull("mzAppKey", mzAppKey); 58 | data.putIfNotNull("oppoAppKey", oppoAppKey); 59 | data.putIfNotNull("oppoAppSecret", oppoAppSecret); 60 | data.putIfNotNull("miAppId", miAppId); 61 | data.putIfNotNull("miAppKey", miAppKey); 62 | data.putIfNotNull("fcmId", fcmId); 63 | data.putIfNotNull("apnsCertName", apnsCertName); 64 | data.putIfNotNull("enableMeiZuPush", enableMeiZuPush); 65 | data.putIfNotNull("enableOppoPush", enableOppoPush); 66 | data.putIfNotNull("enableMiPush", enableMiPush); 67 | data.putIfNotNull("enableFCM", enableFCM); 68 | data.putIfNotNull("enableHWPush", enableHWPush); 69 | data.putIfNotNull("enableVivoPush", enableVivoPush); 70 | data.putIfNotNull('agreePrivacyStatement', agreePrivacyStatement); 71 | data.putIfNotNull("enableAPNS", enableAPNS); 72 | data.putIfNotNull("enableHonorPush", enableHonorPush); 73 | 74 | return data; 75 | } 76 | 77 | @override 78 | String toString() { 79 | return toJson().toString(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/internal/em_transform_tools.dart: -------------------------------------------------------------------------------- 1 | import 'inner_headers.dart'; 2 | 3 | EMMultiDevicesEvent? convertIntToEMMultiDevicesEvent(int? i) { 4 | switch (i) { 5 | case -1: 6 | return EMMultiDevicesEvent.UnKnow; 7 | case 2: 8 | return EMMultiDevicesEvent.CONTACT_REMOVE; 9 | case 3: 10 | return EMMultiDevicesEvent.CONTACT_ACCEPT; 11 | case 4: 12 | return EMMultiDevicesEvent.CONTACT_DECLINE; 13 | case 5: 14 | return EMMultiDevicesEvent.CONTACT_BAN; 15 | case 6: 16 | return EMMultiDevicesEvent.CONTACT_ALLOW; 17 | case 10: 18 | return EMMultiDevicesEvent.GROUP_CREATE; 19 | case 11: 20 | return EMMultiDevicesEvent.GROUP_DESTROY; 21 | case 12: 22 | return EMMultiDevicesEvent.GROUP_JOIN; 23 | case 13: 24 | return EMMultiDevicesEvent.GROUP_LEAVE; 25 | case 14: 26 | return EMMultiDevicesEvent.GROUP_APPLY; 27 | case 15: 28 | return EMMultiDevicesEvent.GROUP_APPLY_ACCEPT; 29 | case 16: 30 | return EMMultiDevicesEvent.GROUP_APPLY_DECLINE; 31 | case 17: 32 | return EMMultiDevicesEvent.GROUP_INVITE; 33 | case 18: 34 | return EMMultiDevicesEvent.GROUP_INVITE_ACCEPT; 35 | case 19: 36 | return EMMultiDevicesEvent.GROUP_INVITE_DECLINE; 37 | case 20: 38 | return EMMultiDevicesEvent.GROUP_KICK; 39 | case 21: 40 | return EMMultiDevicesEvent.GROUP_BAN; 41 | case 22: 42 | return EMMultiDevicesEvent.GROUP_ALLOW; 43 | case 23: 44 | return EMMultiDevicesEvent.GROUP_BLOCK; 45 | case 24: 46 | return EMMultiDevicesEvent.GROUP_UNBLOCK; 47 | case 25: 48 | return EMMultiDevicesEvent.GROUP_ASSIGN_OWNER; 49 | case 26: 50 | return EMMultiDevicesEvent.GROUP_ADD_ADMIN; 51 | case 27: 52 | return EMMultiDevicesEvent.GROUP_REMOVE_ADMIN; 53 | case 28: 54 | return EMMultiDevicesEvent.GROUP_ADD_MUTE; 55 | case 29: 56 | return EMMultiDevicesEvent.GROUP_REMOVE_MUTE; 57 | case 40: 58 | return EMMultiDevicesEvent.CHAT_THREAD_CREATE; 59 | case 41: 60 | return EMMultiDevicesEvent.CHAT_THREAD_DESTROY; 61 | case 42: 62 | return EMMultiDevicesEvent.CHAT_THREAD_JOIN; 63 | case 43: 64 | return EMMultiDevicesEvent.CHAT_THREAD_LEAVE; 65 | case 44: 66 | return EMMultiDevicesEvent.CHAT_THREAD_KICK; 67 | case 45: 68 | return EMMultiDevicesEvent.CHAT_THREAD_UPDATE; 69 | case 52: 70 | return EMMultiDevicesEvent.GROUP_MEMBER_ATTRIBUTES_CHANGED; 71 | case 60: 72 | return EMMultiDevicesEvent.CONVERSATION_PINNED; 73 | case 61: 74 | return EMMultiDevicesEvent.CONVERSATION_UNPINNED; 75 | case 62: 76 | return EMMultiDevicesEvent.CONVERSATION_DELETE; 77 | case 63: 78 | return EMMultiDevicesEvent.CONVERSATION_UPDATE_MARK; 79 | case 64: 80 | return EMMultiDevicesEvent.CONVERSATION_MUTE_INFO_CHANGED; 81 | } 82 | return null; 83 | } 84 | 85 | EMGroupStyle groupStyleTypeFromInt(int? type) { 86 | EMGroupStyle ret = EMGroupStyle.PrivateOnlyOwnerInvite; 87 | switch (type) { 88 | case 0: 89 | { 90 | ret = EMGroupStyle.PrivateOnlyOwnerInvite; 91 | } 92 | break; 93 | case 1: 94 | { 95 | ret = EMGroupStyle.PrivateMemberCanInvite; 96 | } 97 | break; 98 | case 2: 99 | { 100 | ret = EMGroupStyle.PublicJoinNeedApproval; 101 | } 102 | break; 103 | case 3: 104 | { 105 | ret = EMGroupStyle.PublicOpenJoin; 106 | } 107 | break; 108 | } 109 | return ret; 110 | } 111 | 112 | int groupStyleTypeToInt(EMGroupStyle? type) { 113 | int ret = 0; 114 | if (type == null) return ret; 115 | switch (type) { 116 | case EMGroupStyle.PrivateOnlyOwnerInvite: 117 | { 118 | ret = 0; 119 | } 120 | break; 121 | case EMGroupStyle.PrivateMemberCanInvite: 122 | { 123 | ret = 1; 124 | } 125 | break; 126 | case EMGroupStyle.PublicJoinNeedApproval: 127 | { 128 | ret = 2; 129 | } 130 | break; 131 | case EMGroupStyle.PublicOpenJoin: 132 | { 133 | ret = 3; 134 | } 135 | break; 136 | } 137 | return ret; 138 | } 139 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/internal/inner_headers.dart: -------------------------------------------------------------------------------- 1 | export 'chat_method_keys.dart'; 2 | export 'em_channel_manager.dart'; 3 | export 'em_event_keys.dart'; 4 | export 'em_push_config.dart'; 5 | export 'em_transform_tools.dart'; 6 | 7 | export '../models/em_chat_enums.dart'; 8 | export '../models/em_chat_room.dart'; 9 | export '../models/em_chat_thread.dart'; 10 | export '../models/em_conversation.dart'; 11 | export '../models/em_cursor_result.dart'; 12 | export '../models/em_device_info.dart'; 13 | export '../models/em_download_callback.dart'; 14 | export '../models/em_error.dart'; 15 | export '../models/em_group_message_ack.dart'; 16 | export '../models/em_group_options.dart'; 17 | export '../models/em_group_shared_file.dart'; 18 | export '../models/em_group.dart'; 19 | export '../models/em_message_reaction.dart'; 20 | export '../models/reaction_operation.dart'; 21 | export '../models/em_message.dart'; 22 | export '../models/em_options.dart'; 23 | export '../models/em_page_result.dart'; 24 | export '../models/em_presence.dart'; 25 | export '../models/em_push_configs.dart'; 26 | export '../models/em_translate_language.dart'; 27 | export '../models/em_user_info.dart'; 28 | export '../models/chat_silent_mode.dart'; 29 | export '../models/recall_message_info.dart'; 30 | export '../models/message_pin_info.dart'; 31 | export '../models/login_extension_info.dart'; 32 | export '../models/message_search_options.dart'; 33 | export '../tools/em_extension.dart'; 34 | export '../tools/em_log.dart'; 35 | 36 | export '../../interface/platform_interface/chat_manager.dart'; 37 | export '../../interface/platform_interface/chat_room_manager.dart'; 38 | export '../../interface/platform_interface/chat_thread_manager.dart'; 39 | export '../../interface/platform_interface/client.dart'; 40 | export '../../interface/platform_interface/contact_manager.dart'; 41 | export '../../interface/platform_interface/group_manager.dart'; 42 | export '../../interface/platform_interface/progress_manager.dart'; 43 | 44 | export '../../interface/platform_interface/presence_manager.dart'; 45 | export '../../interface/platform_interface/push_manager.dart'; 46 | export '../../interface/platform_interface/user_info_manager.dart'; 47 | export '../event_handler/manager_event_handler.dart'; 48 | export '../tools/chat_area_code.dart'; 49 | export '../tools/em_tools.dart'; 50 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/em_contact.dart: -------------------------------------------------------------------------------- 1 | import '../internal/inner_headers.dart'; 2 | 3 | class EMContact { 4 | final String userId; 5 | final String remark; 6 | 7 | EMContact(Map map) 8 | : userId = map["userId"], 9 | remark = map["remark"]; 10 | 11 | Map toJson() { 12 | Map data = {}; 13 | data.putIfNotNull("userId", userId); 14 | data.putIfNotNull("remark", remark); 15 | 16 | return data; 17 | } 18 | 19 | factory EMContact.fromJson(Map map) { 20 | return EMContact(map); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/em_cursor_result.dart: -------------------------------------------------------------------------------- 1 | typedef CursorResultCallback = Object Function(dynamic obj); 2 | 3 | /// ~english 4 | /// The EMCursorResult class, which specifies the cursor from which to query results. 5 | /// When querying using this class, the SDK returns the queried instance and the cursor. 6 | /// 7 | /// ```dart 8 | /// String? cursor; 9 | /// EMCursorResult result = await EMClient.getInstance.groupManager.fetchPublicGroupsFromServer(pageSize: 10, cursor: cursor); 10 | /// List? group = result.data; 11 | /// cursor = result.cursor; 12 | /// ``` 13 | /// ~end 14 | /// 15 | /// ~chinese 16 | /// 带游标及分页获取结果的泛型类。 17 | /// 做为分页获取且含有游标的返回对象。 18 | /// 19 | /// 示例代码如下: 20 | /// ```dart 21 | /// String? cursor; 22 | /// EMCursorResult result = await EMClient.getInstance.groupManager.getPublicGroupsFromServer(pageSize: 10, cursor: cursor); 23 | /// List? group = result.data; 24 | /// cursor = result.cursor; 25 | /// ``` 26 | /// ~end 27 | class EMCursorResult { 28 | EMCursorResult( 29 | this.cursor, 30 | this.data, 31 | ); 32 | 33 | factory EMCursorResult.fromJson(Map map, 34 | {dataItemCallback = CursorResultCallback}) { 35 | List list = []; 36 | for (var element in (map['list'] as List)) { 37 | list.add(dataItemCallback(element)); 38 | } 39 | EMCursorResult result = EMCursorResult(map['cursor'], list); 40 | 41 | return result; 42 | } 43 | 44 | /// ~english 45 | /// Gets the cursor. 46 | /// ~end 47 | /// 48 | /// ~chinese 49 | /// 获取游标。 50 | /// ~end 51 | final String? cursor; 52 | 53 | /// ~english 54 | /// Gets the data list. 55 | /// ~end 56 | /// 57 | /// ~chinese 58 | /// 获取一页数据列表。 59 | /// ~end 60 | final List data; 61 | } 62 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/em_device_info.dart: -------------------------------------------------------------------------------- 1 | import 'package:im_flutter_sdk_interface/im_flutter_sdk_interface.dart'; 2 | 3 | /// ~english 4 | /// The EMDeviceInfo class, which contains the multi-device information. 5 | /// ~end 6 | /// 7 | /// ~chinese 8 | /// 多设备登录信息类。 9 | /// ~end 10 | class EMDeviceInfo { 11 | EMDeviceInfo( 12 | this.resource, 13 | this.deviceUUID, 14 | this.deviceName, 15 | ); 16 | 17 | Map toJson() { 18 | Map data = {}; 19 | data.putIfNotNull("resource", resource); 20 | data.putIfNotNull("deviceUUID", deviceUUID); 21 | data.putIfNotNull("deviceName", deviceName); 22 | 23 | return data; 24 | } 25 | 26 | factory EMDeviceInfo.fromJson(Map map) { 27 | return EMDeviceInfo( 28 | map["resource"], 29 | map["deviceUUID"], 30 | map["deviceName"], 31 | ); 32 | } 33 | 34 | /// ~english 35 | /// The information of other login devices. 36 | /// ~end 37 | /// 38 | /// ~chinese 39 | /// 登录的其他设备的信息。 40 | /// ~end 41 | final String? resource; 42 | 43 | /// ~english 44 | /// The UUID of the device. 45 | /// ~end 46 | /// 47 | /// ~chinese 48 | /// 设备的 UUID(唯一标识码)。 49 | /// ~end 50 | final String? deviceUUID; 51 | 52 | /// ~english 53 | /// The device type. For example: "Pixel 6 Pro". 54 | /// ~end 55 | /// 56 | /// ~chinese 57 | /// 设备型号,如 "Pixel 6 Pro"。 58 | /// ~end 59 | final String? deviceName; 60 | } 61 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/em_download_callback.dart: -------------------------------------------------------------------------------- 1 | import '../internal/inner_headers.dart'; 2 | 3 | /// ~english 4 | /// The group shared download callback. 5 | /// ~end 6 | /// 7 | /// ~chinese 8 | /// 群文件下载回调。 9 | /// ~end 10 | class EMDownloadCallback { 11 | /// ~english 12 | /// Download success callback. 13 | /// ~end 14 | /// 15 | /// ~chinese 16 | /// 群文件下载成功回调。 17 | /// ~end 18 | final void Function(String fileId, String path)? onSuccess; 19 | 20 | /// ~english 21 | /// Download error callback. 22 | /// ~end 23 | /// 24 | /// ~chinese 25 | /// 群文件下载失败回调。 26 | /// ~end 27 | final void Function(String fileId, EMError error)? onError; 28 | 29 | /// ~english 30 | /// Download progress callback. 31 | /// ~end 32 | /// 33 | /// ~chinese 34 | /// 群文件下载进度。取值范围 [0,100]。 35 | /// ~end 36 | final void Function(String fileId, int progress)? onProgress; 37 | 38 | /// ~english 39 | /// Create a group shared file download callback. 40 | /// ~end 41 | /// 42 | /// ~chinese 43 | /// 创建文件下载对象。 44 | /// ~end 45 | EMDownloadCallback({ 46 | this.onSuccess, 47 | this.onError, 48 | this.onProgress, 49 | }); 50 | } 51 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/em_error.dart: -------------------------------------------------------------------------------- 1 | /// ~english 2 | /// The error class defined by the SDK. 3 | /// ~end 4 | /// 5 | /// ~chinese 6 | /// SDK 定义的错误类。 7 | /// ~end 8 | class EMError { 9 | EMError(this.code, this.description); 10 | 11 | /// ~english 12 | /// The error code. 13 | /// ~end 14 | /// 15 | /// ~chinese 16 | /// 错误码。 17 | /// ~end 18 | final int code; 19 | 20 | /// ~english 21 | /// The error description. 22 | /// ~end 23 | /// 24 | /// ~chinese 25 | /// 错误描述。 26 | /// ~end 27 | final String description; 28 | 29 | factory EMError.fromJson(Map map) { 30 | return EMError(map['code'], map['description']); 31 | } 32 | 33 | static hasErrorFromResult(Map map) { 34 | if (map['error'] == null) { 35 | return; 36 | } else { 37 | try { 38 | throw (EMError.fromJson(map['error'])); 39 | // ignore: empty_catches 40 | } on Exception {} 41 | } 42 | } 43 | 44 | @override 45 | String toString() { 46 | return "code: $code desc: $description"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/em_group_message_ack.dart: -------------------------------------------------------------------------------- 1 | /// ~english 2 | /// The class for group message read receipts. 3 | /// 4 | /// To get the chat group message receipts, call [EMChatManager.fetchGroupAcks]. 5 | /// 6 | /// ```dart 7 | /// EMCursorResult result = await EMClient.getInstance.chatManager.fetchGroupAcks("msgId"); 8 | /// ``` 9 | /// ~end 10 | /// 11 | /// ~chinese 12 | /// 群组消息回执类。 13 | /// 14 | /// 调用 [EMChatManager.fetchGroupAcks] 方法,示例代码如下: 15 | /// 16 | /// ```dart 17 | /// EMCursorResult result = await EMClient.getInstance.chatManager.fetchGroupAcks("msgId"); 18 | /// ``` 19 | /// ~end 20 | class EMGroupMessageAck { 21 | /// ~english 22 | /// Gets the group message ID. 23 | /// 24 | /// **Return** The group message ID. 25 | /// ~end 26 | /// 27 | /// ~chinese 28 | /// 群组消息 ID。 29 | /// ~end 30 | final String messageId; 31 | 32 | /// ~english 33 | /// Gets the ID of the group message read receipt. 34 | /// 35 | /// **Return** The read receipt ID. 36 | /// ~end 37 | /// 38 | /// ~chinese 39 | /// 群组消息已读回执 ID。 40 | /// ~end 41 | final String? ackId; 42 | 43 | /// ~english 44 | /// Gets the username of the user who sends the read receipt. 45 | /// 46 | /// **Return** The username of the read receipt sender. 47 | /// ~end 48 | /// 49 | /// ~chinese 50 | /// 发送已读回执的用户 ID。 51 | /// ~end 52 | final String from; 53 | 54 | /// ~english 55 | /// Gets the read receipt extension. 56 | /// 57 | /// For how to set the extension, see [EMChatManager.sendGroupMessageReadAck]. 58 | /// 59 | /// **Return** The read receipt extension. 60 | /// ~end 61 | /// 62 | /// ~chinese 63 | /// 已读回执扩展内容。 64 | /// 65 | /// 设定该扩展内容详见 [EMChatManager.sendGroupMessageReadAck].。 66 | /// ~end 67 | final String? content; 68 | 69 | /// ~english 70 | /// Gets the number read receipts of group messages. 71 | /// 72 | /// **Return** The count in which read receipts of group messages are sent. 73 | /// ~end 74 | /// 75 | /// ~chinese 76 | /// 群组消息已读回执数量。 77 | /// ~end 78 | final int readCount; 79 | 80 | /// ~english 81 | /// Gets the timestamp of sending read receipts of group messages. 82 | /// 83 | /// **Return** The timestamp of sending read receipts of group messages. 84 | /// ~end 85 | /// 86 | /// ~chinese 87 | /// 发送已读回执的时间戳。 88 | /// ~end 89 | final int timestamp; 90 | 91 | factory EMGroupMessageAck.fromJson(Map map) { 92 | EMGroupMessageAck ack = EMGroupMessageAck( 93 | ackId: map["ack_id"], 94 | messageId: map["msg_id"] as String, 95 | from: map["from"] as String, 96 | content: map["content"], 97 | readCount: map["count"] ?? 0, 98 | timestamp: map["timestamp"] ?? 0, 99 | ); 100 | 101 | return ack; 102 | } 103 | 104 | EMGroupMessageAck({ 105 | this.ackId, 106 | required this.messageId, 107 | required this.from, 108 | required this.content, 109 | required this.readCount, 110 | required this.timestamp, 111 | }); 112 | } 113 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/em_group_shared_file.dart: -------------------------------------------------------------------------------- 1 | import '../internal/inner_headers.dart'; 2 | 3 | /// ~english 4 | /// The EMGroupSharedFile class, which manages the chat group shared files. 5 | /// 6 | /// To get the information of the chat group shared file, call [EMGroupManager.fetchGroupFileListFromServer]. 7 | /// 8 | /// ```dart 9 | /// List? list = await EMClient.getInstance.groupManager.fetchGroupFileListFromServer(groupId); 10 | /// ``` 11 | /// ~end 12 | /// 13 | /// ~chinese 14 | /// 群组共享文件类。 15 | /// 16 | /// 可以通过 [EMGroupManager.fetchGroupFileListFromServer] 方法获取共享文件信息,示例如下: 17 | /// 18 | /// ```dart 19 | /// List list = await EMClient.getInstance.groupManager.fetchGroupFileListFromServer(groupId); 20 | /// ``` 21 | /// ~end 22 | class EMGroupSharedFile { 23 | EMGroupSharedFile._private(); 24 | 25 | String? _fileId; 26 | String? _fileName; 27 | String? _fileOwner; 28 | int? _createTime; 29 | int? _fileSize; 30 | 31 | /// ~english 32 | /// Gets the shared file ID. 33 | /// 34 | /// **Return** The shared file ID. 35 | /// ~end 36 | /// 37 | /// ~chinese 38 | /// 共享文件 ID。 39 | /// ~end 40 | String? get fileId => _fileId; 41 | 42 | /// ~english 43 | /// Gets the shared file name. 44 | /// 45 | /// **Return** The shared file name. 46 | /// ~end 47 | /// 48 | /// ~chinese 49 | /// 共享文件名称。 50 | /// ~end 51 | String? get fileName => _fileName; 52 | 53 | /// ~english 54 | /// Gets the username that uploads the shared file. 55 | /// 56 | /// **Return** The username that uploads the shared file. 57 | /// ~end 58 | /// 59 | /// ~chinese 60 | /// 上传共享文件的成员用户 ID。 61 | /// ~end 62 | String? get fileOwner => _fileOwner; 63 | 64 | /// ~english 65 | /// Gets the Unix timestamp for uploading the shared file, in milliseconds. 66 | /// 67 | /// **Return** The Unix timestamp for uploading the shared file, in milliseconds. 68 | /// ~end 69 | /// 70 | /// ~chinese 71 | /// 共享文件的上传时间戳,单位为毫秒。 72 | /// ~end 73 | int? get createTime => _createTime; 74 | 75 | /// ~english 76 | /// Gets the data length of the shared file, in bytes. 77 | /// 78 | /// **Return** The data length of the shared file, in bytes. 79 | /// ~end 80 | /// 81 | /// ~chinese 82 | /// 共享文件大小,单位为字节。 83 | /// ~end 84 | int? get fileSize => _fileSize; 85 | 86 | factory EMGroupSharedFile.fromJson(Map? map) { 87 | return EMGroupSharedFile._private() 88 | .._fileId = map?["fileId"] 89 | .._fileName = map?["name"] 90 | .._fileOwner = map?["owner"] 91 | .._createTime = map?["createTime"] 92 | .._fileSize = map?["fileSize"]; 93 | } 94 | 95 | Map toJson() { 96 | Map data = {}; 97 | data.putIfNotNull("fileId", _fileId); 98 | data.putIfNotNull("name", _fileName); 99 | data.putIfNotNull("owner", _fileOwner); 100 | data.putIfNotNull("createTime", _createTime); 101 | data.putIfNotNull("fileSize", _fileSize); 102 | return data; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/em_page_result.dart: -------------------------------------------------------------------------------- 1 | typedef PageResultCallback = Object Function(dynamic obj); 2 | 3 | /// ~english 4 | /// The EMPageResult class, which is returned when calling the methods that fetch data by pagination. 5 | /// The SDK also returns the number of remaining pages and the data count of the next page. If the dada count is less than the count you set, there is no more data on server. 6 | /// 7 | /// Param [T] Generics. 8 | /// ~end 9 | /// 10 | /// ~chinese 11 | /// 分页类。 12 | /// 该类包含下次查询的页码以及相应页面上的数据条数。 13 | /// 该对象在分页获取数据时返回。 14 | /// 15 | /// Param [T] 泛型类型 T。 16 | /// ~end 17 | class EMPageResult { 18 | EMPageResult(); 19 | 20 | factory EMPageResult.fromJson(Map map, 21 | {dataItemCallback = PageResultCallback}) { 22 | EMPageResult result = EMPageResult(); 23 | result._pageCount = map['count']; 24 | result._data = []; 25 | 26 | for (var element in (map['list'] as List)) { 27 | result._data.add( 28 | dataItemCallback(element), 29 | ); 30 | } 31 | 32 | return result; 33 | } 34 | 35 | int? _pageCount; 36 | List _data = []; 37 | 38 | /// ~english 39 | /// The page count. 40 | /// ~end 41 | /// 42 | /// ~chinese 43 | /// 当前页面上的数据条数。若 `PageCount` 小于传入的每页要获取的数量,表示当前是最后一页。 44 | /// ~end 45 | get pageCount => _pageCount; 46 | 47 | /// ~english 48 | /// The result data. 49 | /// ~end 50 | /// 51 | /// ~chinese 52 | /// 获取 泛型数据。 53 | /// ~end 54 | List? get data => _data; 55 | } 56 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/em_presence.dart: -------------------------------------------------------------------------------- 1 | /// ~english 2 | /// The presence property class that contains presence properties, including the publisher's user ID and current presence state, and the platform used by the online device, as well as the presence's extension information, update time, and subscription expiration time. 3 | /// ~end 4 | /// 5 | /// ~chinese 6 | /// 在线状态属性类,包含发布者的用户名、在线设备使用的平台、当前在线状态以及在线状态的扩展信息、更新时间和到期时间。 7 | /// ~end 8 | class EMPresence { 9 | /// ~english 10 | /// The user ID of the presence publisher. 11 | /// ~end 12 | /// 13 | /// ~chinese 14 | /// 在线状态发布者的用户 ID。 15 | /// ~end 16 | final String publisher; 17 | 18 | /// ~english 19 | /// The presence description information. 20 | /// ~end 21 | /// 22 | /// ~chinese 23 | /// 自定义在线状态,例如忙碌、离开和隐身等。 24 | /// ~end 25 | final String statusDescription; 26 | 27 | /// ~english 28 | /// The presence update time, which is generated by the server. 29 | /// ~end 30 | /// 31 | /// ~chinese 32 | /// 在线状态更新 Unix 时间戳,单位为秒。 33 | /// ~end 34 | final int lastTime; 35 | 36 | /// ~english 37 | /// The expiration time of the presence subscription. 38 | /// ~end 39 | /// 40 | /// ~chinese 41 | /// 在线状态订阅到期 Unix 时间戳,单位为秒。 42 | /// ~end 43 | final int expiryTime; 44 | 45 | /// ~english 46 | /// The details of the current presence state. 47 | /// ~end 48 | /// 49 | /// ~chinese 50 | /// 该用户的当前在线状态详情。 51 | /// ~end 52 | Map? statusDetails; 53 | 54 | EMPresence( 55 | this.publisher, 56 | this.statusDescription, 57 | this.statusDetails, 58 | this.lastTime, 59 | this.expiryTime, 60 | ); 61 | 62 | factory EMPresence.fromJson(Map map) { 63 | String publisher = map["publisher"] ?? ""; 64 | String statusDescription = map["statusDescription"] ?? ""; 65 | int latestTime = map["lastTime"] ?? 0; 66 | int expiryTime = map["expiryTime"] ?? 0; 67 | Map? statusDetails = map["statusDetails"]?.cast(); 68 | return EMPresence( 69 | publisher, statusDescription, statusDetails, latestTime, expiryTime); 70 | } 71 | } 72 | 73 | /// ~english 74 | /// The presence details, including the platform used by the publisher's current online device and the current presence state. 75 | /// ~end 76 | /// 77 | /// ~chinese 78 | /// 用户在线状态详情。 79 | /// ~end 80 | class EMPresenceStatusDetail { 81 | /// ~english 82 | /// The platform used by the current online device of the publisher, which can be "ios", "android", "linux", "win", or "webim". 83 | /// ~end 84 | /// 85 | /// ~chinese 86 | /// 发布在线设备,可能是 "ios", "android", "linux", "win", "webim"。 87 | /// ~end 88 | final String device; 89 | 90 | /// ~english 91 | /// The current presence state of the publisher. 92 | /// ~end 93 | /// 94 | /// ~chinese 95 | /// 发布的在线状态。 96 | /// ~end 97 | final int status; 98 | 99 | EMPresenceStatusDetail._private( 100 | this.device, 101 | this.status, 102 | ); 103 | 104 | factory EMPresenceStatusDetail.fromJson(Map map) { 105 | String device = map["device"]; 106 | int status = map["status"] ?? 0; 107 | return EMPresenceStatusDetail._private(device, status); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/em_push_configs.dart: -------------------------------------------------------------------------------- 1 | import '../internal/inner_headers.dart'; 2 | 3 | /// ~english 4 | /// The push configuration class. 5 | /// ~end 6 | /// 7 | /// ~chinese 8 | /// 推送设置类。 9 | /// ~end 10 | class EMPushConfigs { 11 | EMPushConfigs({ 12 | this.displayStyle = DisplayStyle.Simple, 13 | this.displayName, 14 | }); 15 | 16 | /// ~english 17 | /// The display type of push notifications. 18 | /// ~end 19 | /// 20 | /// ~chinese 21 | /// 获取推送显示类型。 22 | /// ~end 23 | final DisplayStyle displayStyle; 24 | 25 | /// ~english 26 | /// The user's nickname to be displayed in the notification. 27 | /// ~end 28 | /// 29 | /// ~chinese 30 | /// 通知中显示的用户昵称。 31 | /// ~end 32 | final String? displayName; 33 | 34 | factory EMPushConfigs.fromJson(Map map) { 35 | return EMPushConfigs( 36 | displayStyle: 37 | map['pushStyle'] == 0 ? DisplayStyle.Simple : DisplayStyle.Summary, 38 | displayName: map["displayName"], 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/em_translate_language.dart: -------------------------------------------------------------------------------- 1 | /// ~english 2 | /// The translation language class, which contains the information of the translation languages. 3 | /// ~end 4 | /// 5 | /// ~chinese 6 | /// 翻译语言类,包含翻译语言相关信息。 7 | /// ~end 8 | class EMTranslateLanguage { 9 | /// ~english 10 | /// The code of a target language. For example, the code for simplified Chinese is "zh-Hans". 11 | /// ~end 12 | /// 13 | /// ~chinese 14 | /// 目标语言代码,如中文简体为 "zh-Hans"。 15 | /// ~end 16 | final String languageCode; 17 | 18 | /// ~english 19 | /// The language name. For example, the code for simplified Chinese is "Chinese Simplified". 20 | /// ~end 21 | /// 22 | /// ~chinese 23 | /// 语言名称,如中文简体为 "Chinese Simplified"。 24 | /// ~end 25 | final String languageName; 26 | 27 | /// ~english 28 | /// The native name of the language. For example, the native name of simplified Chinese is "Chinese (Simplified)". 29 | /// ~end 30 | /// 31 | /// ~chinese 32 | /// 语言的原生名称,如中文简体为 "中文 (简体)"。 33 | /// ~end 34 | final String languageNativeName; 35 | 36 | EMTranslateLanguage({ 37 | required this.languageCode, 38 | required this.languageName, 39 | required this.languageNativeName, 40 | }); 41 | 42 | factory EMTranslateLanguage.fromJson(Map map) { 43 | String code = map["code"]; 44 | String name = map["name"]; 45 | String nativeName = map["nativeName"]; 46 | return EMTranslateLanguage( 47 | languageCode: code, 48 | languageName: name, 49 | languageNativeName: nativeName, 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/em_user_info.dart: -------------------------------------------------------------------------------- 1 | /// ~english 2 | /// The EMUserInfo class, which contains the user attributes, such as the nickname, description, and avatar. 3 | /// ~end 4 | /// 5 | /// ~chinese 6 | /// 用户属性类。 7 | /// ~end 8 | class EMUserInfo { 9 | /// ~english 10 | /// Creates a user attribute. 11 | /// ~end 12 | /// 13 | /// ~chinese 14 | /// 创建用户属性。 15 | /// ~end 16 | EMUserInfo( 17 | this.userId, { 18 | this.nickName, 19 | this.avatarUrl, 20 | this.mail, 21 | this.phone, 22 | this.gender = 0, 23 | this.sign, 24 | this.birth, 25 | this.ext, 26 | }); 27 | 28 | factory EMUserInfo.fromJson(Map map) { 29 | EMUserInfo info = EMUserInfo( 30 | map["userId"], 31 | nickName: map["nickName"], 32 | avatarUrl: map["avatarUrl"], 33 | mail: map["mail"], 34 | phone: map["phone"], 35 | gender: map["gender"] ?? 0, 36 | sign: map["sign"], 37 | birth: map["birth"], 38 | ext: map["ext"], 39 | ); 40 | return info; 41 | } 42 | 43 | Map toJson() { 44 | Map data = {}; 45 | data['userId'] = userId; 46 | if (nickName != null) { 47 | data['nickName'] = nickName; 48 | } 49 | if (avatarUrl != null) { 50 | data['avatarUrl'] = avatarUrl; 51 | } 52 | if (mail != null) { 53 | data['mail'] = mail; 54 | } 55 | if (phone != null) { 56 | data['phone'] = phone; 57 | } 58 | data['gender'] = gender; 59 | if (sign != null) { 60 | data['sign'] = sign; 61 | } 62 | if (birth != null) { 63 | data['birth'] = birth; 64 | } 65 | if (ext != null) { 66 | data['ext'] = ext; 67 | } 68 | 69 | return data; 70 | } 71 | 72 | /// ~english 73 | /// Gets the userId. 74 | /// ~end 75 | /// 76 | /// ~chinese 77 | /// 用户 ID。 78 | /// ~end 79 | final String userId; 80 | 81 | /// ~english 82 | /// Gets the user's nickname. 83 | /// ~end 84 | /// 85 | /// ~chinese 86 | /// 用户昵称。 87 | /// ~end 88 | final String? nickName; 89 | 90 | /// ~english 91 | /// Gets the avatar URL of the user. 92 | /// ~end 93 | /// 94 | /// ~chinese 95 | /// 用户头像。 96 | /// ~end 97 | final String? avatarUrl; 98 | 99 | /// ~english 100 | /// Gets the email address of the user. 101 | /// ~end 102 | /// 103 | /// ~chinese 104 | /// 用户邮箱。 105 | /// ~end 106 | final String? mail; 107 | 108 | /// ~english 109 | /// Gets the mobile numbers of the user. 110 | /// ~end 111 | /// 112 | /// ~chinese 113 | /// 用户手机号。 114 | /// ~end 115 | final String? phone; 116 | 117 | /// ~english 118 | /// Gets the user's gender. 119 | /// 120 | /// The user's gender: 121 | /// - `0`: (Default) UnKnow; 122 | /// - `1`: Male; 123 | /// - `2`: Female. 124 | /// ~end 125 | /// 126 | /// ~chinese 127 | /// 用户性别。 128 | /// - (默认) `0`:未知; 129 | /// - `1`: 男; 130 | /// - `2`: 女。 131 | /// ~end 132 | final int gender; 133 | 134 | /// ~english 135 | /// Gets the user's signature. 136 | /// ~end 137 | /// 138 | /// ~chinese 139 | /// 用户签名。 140 | /// ~end 141 | final String? sign; 142 | 143 | /// ~english 144 | /// Gets the user's data of birth. 145 | /// ~end 146 | /// 147 | /// ~chinese 148 | /// 用户生日。 149 | /// ~end 150 | final String? birth; 151 | 152 | /// ~english 153 | /// Gets the user's extension information. 154 | /// ~end 155 | /// 156 | /// ~chinese 157 | /// 用户自定义属性字段。 158 | /// ~end 159 | final String? ext; 160 | 161 | /// ~english 162 | /// Gets the time period(seconds) when the user attributes in the cache expire. 163 | /// If the interval between two callers is less than or equal to the value you set in the parameter, 164 | /// user attributes are obtained directly from the local cache; otherwise, they are obtained from the server. 165 | /// For example, if you set this parameter to 120(2 minutes), once this method is called again within 2 minutes, 166 | /// the SDK returns the attributes obtained last time. 167 | /// ~end 168 | /// 169 | /// ~chinese 170 | /// 获取缓存中的用户属性到期时的时间段(秒)。如果两个调用者之间的间隔小于或等于参数中设置的值,则直接从本地缓存获取用户属性; 171 | /// 否则,从服务器获取。例如,如果将该参数设置为120(2分钟),则在2分钟内再次调用该方法,SDK将返回上次获取的属性。 172 | /// ~end 173 | final int expireTime = DateTime.now().millisecondsSinceEpoch; 174 | } 175 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/login_extension_info.dart: -------------------------------------------------------------------------------- 1 | class LoginExtensionInfo { 2 | factory LoginExtensionInfo.fromJson(Map json) { 3 | String? ext; 4 | if (json['ext'] != null) { 5 | ext = json['ext'] as String; 6 | } 7 | return LoginExtensionInfo(json['deviceName'] as String, ext: ext); 8 | } 9 | 10 | const LoginExtensionInfo(this.deviceName, {this.ext}); 11 | 12 | /// ~english 13 | /// The device name. 14 | /// ~end 15 | /// ~chinese 16 | /// 设备名称。 17 | /// ~end 18 | final String deviceName; 19 | 20 | /// ~english 21 | /// The extension information contained in the notification sent to device A that is kicked offline due to the user's login to device B. 22 | /// ~end 23 | /// ~chinese 24 | /// 设备 B 登录时,将设备 A 踢下线携带的扩展信息。 25 | /// ~end 26 | final String? ext; 27 | } 28 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/message_pin_info.dart: -------------------------------------------------------------------------------- 1 | /// ~english 2 | /// The message pinning information. 3 | /// ~end 4 | /// 5 | /// ~chinese 6 | /// 消息置顶信息。 7 | /// ~end 8 | class MessagePinInfo { 9 | /// ~english 10 | /// The time when the message is pinned. 11 | /// ~end 12 | /// ~chinese 13 | /// 置顶时间。 14 | /// ~end 15 | final int pinTime; 16 | 17 | /// ~english 18 | /// The user ID of the operator that pins the message. 19 | /// ~end 20 | /// ~chinese 21 | /// 置顶的操作者的用户 ID。 22 | /// ~end 23 | final String operatorId; 24 | 25 | /// ~english 26 | /// Constructor of MessagePinInfo. 27 | /// 28 | /// param [pinTime] The time when the message is pinned. 29 | /// param [operatorId] The user ID of the operator that pins the message. 30 | /// ~end 31 | /// 32 | /// ~chinese 33 | /// MessagePinInfo 的构造函数。 34 | /// 35 | /// 参数 [pinTime] 消息置顶时间。 36 | /// 参数 [operatorId] 置顶的操作者的用户 ID。 37 | /// ~end 38 | MessagePinInfo({ 39 | required this.pinTime, 40 | required this.operatorId, 41 | }); 42 | 43 | factory MessagePinInfo.fromJson(Map map) { 44 | return MessagePinInfo( 45 | pinTime: map['pinTime'] as int, 46 | operatorId: map['operatorId'] as String, 47 | ); 48 | } 49 | 50 | Map toMap() { 51 | return { 52 | 'pinTime': pinTime, 53 | 'operatorId': operatorId, 54 | }; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/message_search_options.dart: -------------------------------------------------------------------------------- 1 | import '../internal/inner_headers.dart'; 2 | 3 | class MessageSearchOptions { 4 | const MessageSearchOptions({ 5 | required this.types, 6 | this.from, 7 | this.ts = -1, 8 | this.count = 10, 9 | this.direction = EMSearchDirection.Up, 10 | }); 11 | 12 | /// ~english 13 | /// Message types list 14 | /// ~end 15 | /// ~chinese 16 | /// 消息类型列表 17 | /// ~end 18 | final List types; 19 | 20 | /// ~english 21 | /// The message sender. 22 | /// ~end 23 | /// ~chinese 24 | /// 消息发送方。 25 | /// ~end 26 | final String? from; 27 | 28 | /// ~english 29 | /// The message timestamp threshold for loading. 30 | /// ~end 31 | /// ~chinese 32 | /// 参考时间戳。 33 | /// ~end 34 | final int ts; 35 | 36 | /// ~english 37 | /// The number of messages to load, max 400. 38 | /// ~end 39 | /// ~chinese 40 | /// 获取的消息条数。最大为400。 41 | /// ~end 42 | final int count; 43 | 44 | /// ~english 45 | /// The message search direction. 46 | /// ~end 47 | /// ~chinese 48 | /// 消息搜索方向。 49 | /// ~end 50 | final EMSearchDirection direction; 51 | } 52 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/reaction_operation.dart: -------------------------------------------------------------------------------- 1 | import 'em_chat_enums.dart'; 2 | 3 | /// ~english 4 | /// Reaction operation. 5 | /// ~end 6 | /// 7 | /// ~chinese 8 | /// Reaction 操作。 9 | /// ~end 10 | class ReactionOperation { 11 | /// ~english 12 | /// Reaction operation. 13 | /// 14 | /// Param [userId] The user ID of the operator. 15 | /// 16 | /// Param [reaction] Changed Reaction. 17 | /// 18 | /// Param [operate] The Reaction operation type. 19 | /// ~end 20 | /// 21 | /// ~chinese 22 | /// Reaction 操作。 23 | /// 24 | /// Param [userId] 操作者的用户 ID。 25 | /// 26 | /// Param [reaction] 发生变化的 Reaction。 27 | /// 28 | /// Param [operate] 具体 Reaction 操作类型。 29 | /// ~end 30 | const ReactionOperation( 31 | this.userId, 32 | this.reaction, 33 | this.operate, 34 | ); 35 | 36 | /// ~english 37 | /// The user ID of the operator. 38 | /// ~end 39 | /// 40 | /// ~chinese 41 | /// 操作者的用户 ID。 42 | /// ~end 43 | final String userId; 44 | 45 | /// ~english 46 | /// Changed Reaction. 47 | /// ~end 48 | /// 49 | /// ~chinese 50 | /// 发生变化的 Reaction。 51 | /// ~end 52 | final String reaction; 53 | 54 | /// ~english 55 | /// The Reaction operation type. 56 | /// ~end 57 | /// 58 | /// ~chinese 59 | /// Reaction 操作类型。 60 | /// ~end 61 | final ReactionOperate operate; 62 | 63 | factory ReactionOperation.fromJson(Map map) { 64 | String userId = map["userId"]; 65 | String reaction = map["reaction"]; 66 | 67 | ReactionOperate operate = ReactionOperate.values[map["operate"]]; 68 | return ReactionOperation(userId, reaction, operate); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/models/recall_message_info.dart: -------------------------------------------------------------------------------- 1 | import '../internal/inner_headers.dart'; 2 | 3 | class RecallMessageInfo { 4 | factory RecallMessageInfo.fromJson(Map map) { 5 | return RecallMessageInfo( 6 | recallMessageId: map['recallMsgId'], 7 | recallBy: map['recallBy'], 8 | conversationId: map['conversationId'], 9 | recallMessage: map.getValue( 10 | "msg", 11 | callback: (map) { 12 | if (map == null) { 13 | return null; 14 | } 15 | return EMMessage.fromJson(map); 16 | }, 17 | ), 18 | ext: map.getValue('ext', callback: (ext) => ext as String?), 19 | ); 20 | } 21 | 22 | const RecallMessageInfo({ 23 | required this.recallBy, 24 | required this.recallMessageId, 25 | this.recallMessage, 26 | this.conversationId, 27 | this.ext, 28 | }); 29 | 30 | /// ~english 31 | /// The ID of the recalled message. 32 | /// ~end 33 | /// ~chinese 34 | /// 撤回消息的id 35 | /// ~end 36 | final String recallMessageId; 37 | 38 | /// ~english 39 | /// The recalled message. 40 | /// 41 | /// The value of this property is nil if the recipient is offline during message recall. 42 | /// ~end 43 | /// ~chinese 44 | /// 撤回的消息,离线撤回会为空。 45 | /// ~end 46 | final EMMessage? recallMessage; 47 | 48 | /// ~english 49 | /// The extension field of the recalled message. 50 | /// ~end 51 | /// ~chinese 52 | /// 撤回消息时要透传的信息。 53 | /// ~end 54 | final String? ext; 55 | 56 | /// ~english 57 | /// The user who recalled the message. 58 | /// ~end 59 | /// ~chinese 60 | /// 撤回消息的用户。 61 | /// ~end 62 | final String recallBy; 63 | 64 | /// ~english 65 | /// The conversation ID of the recalled message. 66 | /// ~end 67 | /// 68 | /// ~chinese 69 | /// 撤回消息的会话ID。 70 | /// ~end 71 | final String? conversationId; 72 | } 73 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/tools/chat_area_code.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: constant_identifier_names 2 | 3 | class ChatAreaCode { 4 | static const int CN = 1; 5 | static const int NA = 2; 6 | static const int EU = 4; 7 | static const int AS = 8; 8 | static const int JP = 16; 9 | static const int IN = 32; 10 | static const int GLOB = -1; 11 | } 12 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/tools/em_extension.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert' as convert; 2 | 3 | Type typeOf() => T; 4 | 5 | typedef MapResultCallback = T Function(dynamic obj); 6 | 7 | extension MapExtension on Map { 8 | bool boolValue(String key) { 9 | if (!containsKey(key)) { 10 | return false; 11 | } else if (this[key] is int) { 12 | return this[key] == 0 ? false : true; 13 | } else if (this[key] is String) { 14 | return this[key].toString().isEmpty ? false : true; 15 | } else if (this[key] is bool) { 16 | return this[key]; 17 | } else { 18 | return false; 19 | } 20 | } 21 | 22 | void putIfNotNull(String key, dynamic value) { 23 | if (value == null) { 24 | return; 25 | } 26 | this[key] = value; 27 | } 28 | 29 | Map? getMapValue(String key, 30 | {Map? defaultValue}) { 31 | Map? ret = {}; 32 | if (containsKey(key)) { 33 | Map tmpMap = this[key]; 34 | for (var tmpKey in tmpMap.keys) { 35 | dynamic value = tmpMap[tmpKey]; 36 | if (value is String && (value.startsWith("{") && value.endsWith("}")) || 37 | value is String && (value.startsWith("[") && value.endsWith("]"))) { 38 | do { 39 | try { 40 | dynamic data = convert.jsonDecode(value); 41 | value = data; 42 | break; 43 | // ignore: empty_catches 44 | } on FormatException {} 45 | } while (false); 46 | ret[tmpKey] = value; 47 | } else { 48 | ret[tmpKey] = value; 49 | } 50 | } 51 | } 52 | if (ret.isEmpty) { 53 | ret = defaultValue; 54 | } 55 | return ret; 56 | } 57 | 58 | List? getList(String key, {MapResultCallback? valueCallback}) { 59 | List? ret; 60 | if (containsKey(key)) { 61 | List list = this[key]; 62 | 63 | List typeList = []; 64 | for (var item in list) { 65 | if (valueCallback != null) { 66 | typeList.add(valueCallback(item)); 67 | } else { 68 | if (item is T) { 69 | typeList.add(item); 70 | } 71 | } 72 | } 73 | if (typeList.isNotEmpty) { 74 | ret = typeList; 75 | } 76 | } 77 | return ret; 78 | } 79 | 80 | T? getValue( 81 | String key, { 82 | required MapResultCallback callback, 83 | }) { 84 | if (!containsKey(key)) { 85 | return null; 86 | } 87 | return callback.call(this[key]); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/tools/em_log.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | 3 | class EMLog { 4 | // ignore: non_constant_identifier_names 5 | static String TAG = 'Chat'; 6 | 7 | static bool debugAble = kReleaseMode ? false : true; 8 | static bool enableCallBackLog = false; 9 | 10 | /// Error级别的log 11 | static void e(Object object, {String? tag}) { 12 | _printLog(tag, ' | E | ', object); 13 | } 14 | 15 | /// Verbose级别的log 16 | static void v(Object object, {String? tag}) { 17 | if (debugAble) { 18 | _printLog(tag, ' | V | ', object); 19 | } 20 | } 21 | 22 | static void d(Object object, {String? tag}) { 23 | if (enableCallBackLog) { 24 | _printLog(tag, ' | CallBack | ', object); 25 | } 26 | } 27 | 28 | static void _printLog(String? tag, String stag, Object object) { 29 | StringBuffer sb = StringBuffer(); 30 | sb.write((tag == null || tag.isEmpty) ? TAG : tag); 31 | sb.write(stag); 32 | sb.write(object); 33 | if (kDebugMode) { 34 | print(sb.toString()); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/lib/src/tools/em_tools.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | class EMTools { 4 | static String get randomId => 5 | DateTime.now().millisecondsSinceEpoch.toString() + 6 | Random().nextInt(99999).toString(); 7 | 8 | static int get millisecondsSinceEpoch => 9 | DateTime.now().millisecondsSinceEpoch; 10 | } 11 | -------------------------------------------------------------------------------- /im_flutter_sdk_interface/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: im_flutter_sdk_interface 2 | description: Integrate the Chat SDK to enjoy the global IM services with high reliability, ultra-low latency, and high concurrency. 3 | version: 4.13.0+1 4 | homepage: https://www.easemob.com 5 | 6 | environment: 7 | sdk: '>=3.3.0 <4.0.0' 8 | flutter: '>=3.3.0' 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | plugin_platform_interface: ^2.1.7 14 | 15 | dev_dependencies: 16 | flutter_lints: ^3.0.0 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 26 | /pubspec.lock 27 | **/doc/api/ 28 | .dart_tool/ 29 | build/ 30 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/.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: "7f2ea2ea242b1ae845ad5eaf5b210c2c67da9b78" 8 | channel: "oh-3.22.0" 9 | 10 | project_type: plugin 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 7f2ea2ea242b1ae845ad5eaf5b210c2c67da9b78 17 | base_revision: 7f2ea2ea242b1ae845ad5eaf5b210c2c67da9b78 18 | - platform: ios 19 | create_revision: 7f2ea2ea242b1ae845ad5eaf5b210c2c67da9b78 20 | base_revision: 7f2ea2ea242b1ae845ad5eaf5b210c2c67da9b78 21 | 22 | # User provided section 23 | 24 | # List of Local paths (relative to this file) that should be 25 | # ignored by the migrate tool. 26 | # 27 | # Files that are not part of the templates will be ignored by default. 28 | unmanaged_files: 29 | - 'lib/main.dart' 30 | - 'ios/Runner.xcodeproj/project.pbxproj' 31 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 4.13.0+1 2 | 3 | - 修复收到 `onAnnouncementChangedFromChatRoom` 回调时,`announcement` 为空导致的崩溃问题。 4 | - 修复收到 `onAnnouncementChangedFromGroup` 回调时,`announcement` 为空导致的崩溃问题。 5 | 6 | ## 4.13.0 7 | 8 | * 更新原生sdk为 4.13.0 9 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /im_flutter_sdk_ios/README.md: -------------------------------------------------------------------------------- 1 | # im_flutter_sdk_ios 2 | 3 | A new Flutter plugin project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter 8 | [plug-in package](https://flutter.dev/developing-packages/), 9 | a specialized package that includes platform-specific implementation code for 10 | Android and/or iOS. 11 | 12 | For help getting started with Flutter development, view the 13 | [online documentation](https://flutter.dev/docs), which offers tutorials, 14 | samples, guidance on mobile development, and a full API reference. 15 | 16 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | # Additional information about this file can be found at 4 | # https://dart.dev/guides/language/analysis-options 5 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/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/ephemeral/ 38 | /Flutter/flutter_export_environment.sh 39 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easemob/im_flutter_sdk/dcf594fac2b9abc6ff1cbd1b11ef765cd34d9c13/im_flutter_sdk_ios/ios/Assets/.gitkeep -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ChatManagerWrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMChatManagerWrapper.h 3 | // 4 | // 5 | // Created by 杜洁鹏 on 2019/10/8. 6 | // 7 | 8 | #import "Wrapper.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface ChatManagerWrapper : Wrapper 13 | 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ChatroomHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMChatroom+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/27. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMChatroom (Helper) 14 | - (NSDictionary *)toJson; 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ChatroomHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMChatroom+Flutter.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/27. 6 | // 7 | 8 | #import "ChatroomHelper.h" 9 | #import "EnumTools.h" 10 | 11 | @implementation EMChatroom (Helper) 12 | - (NSDictionary *)toJson { 13 | NSMutableDictionary *ret = [NSMutableDictionary dictionary]; 14 | ret[@"roomId"] = self.chatroomId; 15 | ret[@"name"] = self.subject; 16 | ret[@"desc"] = self.description; 17 | ret[@"owner"] = self.owner; 18 | ret[@"maxUsers"] = @(self.maxOccupantsCount); 19 | ret[@"memberCount"] = @(self.occupantsCount); 20 | ret[@"adminList"] = self.adminList; 21 | ret[@"memberList"] = self.memberList; 22 | ret[@"blockList"] = self.blacklist; 23 | ret[@"muteList"] = self.muteList; 24 | ret[@"isAllMemberMuted"] = @(self.isMuteAllMembers); 25 | ret[@"announcement"] = self.announcement; 26 | ret[@"permissionType"] = [NSNumber numberWithInteger:[EnumTools chatRoomPermissionTypeToInt:self.permissionType]]; 27 | ret[@"muteExpireTimestamp"] = @(self.muteExpireTimestamp); 28 | ret[@"isInWhitelist"] = @(self.isInWhitelist); 29 | ret[@"createTimestamp"] = @(self.createTimestamp); 30 | 31 | return ret; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ChatroomManagerWrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMChatroomManagerWrapper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by easemob-DN0164 on 2019/10/18. 6 | // 7 | 8 | #import "Wrapper.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | @interface ChatroomManagerWrapper : Wrapper 12 | 13 | @end 14 | 15 | NS_ASSUME_NONNULL_END 16 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ClientWrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMClientWrapper.h 3 | // 4 | // 5 | // Created by 杜洁鹏 on 2019/10/8. 6 | // 7 | 8 | #import "Wrapper.h" 9 | #import "ProgressManager.h" 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface ClientWrapper : Wrapper 13 | 14 | - (void)sendDataToFlutter:(NSDictionary *)aData; 15 | - (ProgressManager *)progressManager; 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ContactHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMContact+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2023/11/13. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMContact (Helper) 14 | + (EMContact *)fromJson:(NSDictionary *)aJson; 15 | - (NSDictionary *)toJson; 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ContactHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMContact+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2023/11/13. 6 | // 7 | 8 | #import "ContactHelper.h" 9 | 10 | @implementation EMContact (Helper) 11 | + (EMContact *)fromJson:(NSDictionary *)aJson { 12 | EMContact *contact = [[EMContact alloc] initWithUserId:aJson[@"userId"] 13 | remark:aJson[@"remark"]]; 14 | return contact; 15 | } 16 | - (NSDictionary *)toJson { 17 | NSMutableDictionary *data = [NSMutableDictionary dictionary]; 18 | data[@"userId"] = self.userId; 19 | data[@"remark"] = self.remark; 20 | return data; 21 | } 22 | @end 23 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ContactManagerWrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMContactManagerWrapper.h 3 | // 4 | // 5 | // Created by 杜洁鹏 on 2019/10/8. 6 | // 7 | 8 | #import "Wrapper.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface ContactManagerWrapper : Wrapper 13 | @end 14 | 15 | NS_ASSUME_NONNULL_END 16 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ConversationFilterHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMConversationFilter+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/28. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | 13 | @interface EMConversationFilter (Helper) 14 | + (EMConversationFilter *)fromJson:(NSDictionary *)dict; 15 | // 不需要提供toJson 16 | //- (NSDictionary *)toJson; 17 | + (NSString *)getCursor:(NSDictionary *)dict; 18 | + (BOOL)getPinned:(NSDictionary *)dict; 19 | + (BOOL)hasMark:(NSDictionary *)dict; 20 | + (NSInteger)pageSize:(NSDictionary *)dict; 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ConversationFilterHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMConversationFilter+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/28. 6 | // 7 | 8 | #import "ConversationFilterHelper.h" 9 | 10 | 11 | @implementation EMConversationFilter (Helper) 12 | // 不需要提供toJson 13 | //- (NSDictionary *)toJson { 14 | // NSMutableDictionary *ret = [NSMutableDictionary new]; 15 | // ret[@"mark"] = @(self.mark); 16 | // ret[@"pageSize"] = @(self.pageSize); 17 | // return ret; 18 | //} 19 | 20 | + (EMConversationFilter *)fromJson:(NSDictionary *)dict { 21 | EMConversationFilter *filter = [[EMConversationFilter alloc] init]; 22 | filter.mark = (EMMarkType)[dict[@"mark"] integerValue]; 23 | filter.pageSize = [dict[@"pageSize"] intValue]; 24 | return filter; 25 | } 26 | 27 | + (NSString *)getCursor:(NSDictionary *)dict { 28 | return dict[@"cursor"]; 29 | } 30 | 31 | + (BOOL)getPinned:(NSDictionary *)dict { 32 | return [dict[@"pinned"] boolValue]; 33 | } 34 | 35 | + (BOOL)hasMark:(NSDictionary *)dict { 36 | return dict[@"mark"] != nil; 37 | } 38 | 39 | + (NSInteger)pageSize:(NSDictionary *)dict { 40 | return [dict[@"pageSize"] intValue]; 41 | } 42 | 43 | @end 44 | 45 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ConversationHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMConversation+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/21. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMConversation (Helper) 14 | - (NSDictionary *)toJson; 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ConversationHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMConversation+Flutter.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/21. 6 | // 7 | 8 | #import "ConversationHelper.h" 9 | #import "MessageHelper.h" 10 | #import "EnumTools.h" 11 | 12 | @implementation EMConversation (Helper) 13 | - (NSDictionary *)toJson { 14 | NSMutableDictionary *ret = [NSMutableDictionary dictionary]; 15 | ret[@"convId"] = self.conversationId; 16 | ret[@"type"] = [NSNumber numberWithInteger:[EnumTools conversationTypeFromInt:self.type]]; 17 | ret[@"ext"] = self.ext; 18 | ret[@"isThread"] = @(self.isChatThread); 19 | ret[@"isPinned"] = @(self.isPinned); 20 | ret[@"pinnedTime"] = @(self.pinnedTime); 21 | ret[@"marks"] = self.marks; 22 | return ret; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ConversationWrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMConversationWrapper.h 3 | // 4 | // 5 | // Created by 杜洁鹏 on 2019/10/8. 6 | // 7 | 8 | #import 9 | #import "Wrapper.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ConversationWrapper : Wrapper 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/CursorResultHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMCursorResult+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/27. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMCursorResult (Helper) 14 | - (NSDictionary *)toJson; 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/CursorResultHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMCursorResult+Flutter.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/27. 6 | // 7 | 8 | #import "CursorResultHelper.h" 9 | 10 | @implementation EMCursorResult (Helper) 11 | - (NSDictionary *)toJson { 12 | NSMutableDictionary *data = [NSMutableDictionary dictionary]; 13 | NSMutableArray *dataList = [NSMutableArray array]; 14 | 15 | for (id obj in self.list) { 16 | if ([obj respondsToSelector:@selector(toJson)]) { 17 | [dataList addObject:[obj toJson]]; 18 | }else if ([obj isKindOfClass:[NSString class]]){ 19 | [dataList addObject:obj]; 20 | } 21 | } 22 | 23 | data[@"list"] = dataList; 24 | data[@"cursor"] = self.cursor; 25 | 26 | return data; 27 | } 28 | @end 29 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/DeviceConfigHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMDeviceConfig+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/10/12. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface EMDeviceConfig (Helper) 13 | - (NSDictionary *)toJson; 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/DeviceConfigHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMDeviceConfig+Flutter.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/10/12. 6 | // 7 | 8 | #import "DeviceConfigHelper.h" 9 | 10 | @implementation EMDeviceConfig (Helper) 11 | - (NSDictionary *)toJson { 12 | return @{ 13 | @"resource": self.resource, 14 | @"deviceUUID":self.deviceUUID, 15 | @"deviceName":self.deviceName, 16 | }; 17 | } 18 | @end 19 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/EnumTools.h: -------------------------------------------------------------------------------- 1 | // 2 | // EnumTools.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2024/10/23. 6 | // 7 | 8 | #import 9 | #import "ChatHeaders.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EnumTools : NSObject 14 | +(NSInteger)messageBodyTypeToInt:(EMMessageBodyType)value; 15 | +(EMMessageBodyType)messageBodyTypeFromInt:(NSInteger)value; 16 | +(NSInteger)downloadStatusToInt:(EMDownloadStatus)value; 17 | +(EMDownloadStatus)downloadStatusFromInt:(NSInteger)value; 18 | +(NSInteger)chatTypeToInt:(EMChatType)value; 19 | +(EMChatType)chatTypeFromInt:(NSInteger)value; 20 | +(NSInteger)chatRoomPermissionTypeToInt:(EMChatroomPermissionType)value; 21 | +(NSInteger)groupPermissionTypeToInt:(EMGroupPermissionType)value; 22 | +(NSInteger)searchDirectionToInt:(EMMessageSearchDirection)value; 23 | +(EMMessageSearchDirection)searchDirectionFromInt:(NSInteger)value; 24 | +(NSInteger)conversationTypeToInt:(EMConversationType)value; 25 | +(EMConversationType)conversationTypeFromInt:(NSInteger)value; 26 | +(NSInteger)silentModeParamTypeToInt:(EMSilentModeParamType)value; 27 | +(EMSilentModeParamType)silentModeParamTypeFromInt:(NSInteger)value; 28 | +(NSInteger)remindTypeToInt:(EMPushRemindType)value; 29 | +(EMPushRemindType)remindTypeFromInt:(NSInteger)value; 30 | +(NSInteger)messageStatusToInt:(EMMessageStatus)value; 31 | +(EMMessageStatus)messageStatusFromInt:(NSInteger)value; 32 | +(NSInteger)messageDirectToInt:(EMMessageDirection)value; 33 | +(EMMessageDirection)messageDirectFromInt:(NSInteger)value; 34 | +(NSInteger)threadOperationToInt:(EMThreadOperation)value; 35 | +(EMThreadOperation)threadOperationFromInt:(NSInteger)value; 36 | +(NSInteger)reactionOperationToInt:(EMMessageReactionOperate)value; 37 | +(EMMessageReactionOperate)recationOperationFromInt:(NSInteger)value; 38 | @end 39 | 40 | NS_ASSUME_NONNULL_END 41 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ErrorHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMError+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/23. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMError (Helper) 14 | - (NSDictionary *)toJson; 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ErrorHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMError+Flutter.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/23. 6 | // 7 | 8 | #import "ErrorHelper.h" 9 | 10 | @implementation EMError (Helper) 11 | - (NSDictionary *)toJson { 12 | return @{ 13 | @"code": @(self.code), 14 | @"description":self.errorDescription, 15 | }; 16 | } 17 | @end 18 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/FetchServerMessagesOptionHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMFetchServerMessagesOption+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2023/5/15. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface EMFetchServerMessagesOption (Helper) 13 | + (EMFetchServerMessagesOption *)fromJson:(NSDictionary *)dict; 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/FetchServerMessagesOptionHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMFetchServerMessagesOption+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2023/5/15. 6 | // 7 | 8 | #import "FetchServerMessagesOptionHelper.h" 9 | #import "ConversationHelper.h" 10 | #import "EnumTools.h" 11 | 12 | @implementation EMFetchServerMessagesOption (Helper) 13 | + (EMFetchServerMessagesOption *)fromJson:(NSDictionary *)dict { 14 | EMFetchServerMessagesOption *options = [[EMFetchServerMessagesOption alloc] init]; 15 | options.direction = [EnumTools searchDirectionFromInt:[dict[@"direction"] integerValue]]; 16 | options.startTime = [dict[@"startTs"] longValue]; 17 | options.endTime = [dict[@"endTs"] longValue]; 18 | options.from = dict[@"from"]; 19 | options.isSave = [dict[@"needSave"] boolValue]; 20 | NSArray *types = dict[@"msgTypes"]; 21 | NSMutableArray *list = [NSMutableArray new]; 22 | if(types) { 23 | for (int i = 0; i < types.count; i++) { 24 | EMMessageBodyType type = [EnumTools messageBodyTypeFromInt:[types[i] integerValue]]; 25 | [list addObject: [NSNumber numberWithInteger:type]]; 26 | } 27 | } 28 | 29 | if(list.count > 0) { 30 | options.msgTypes = list; 31 | } 32 | 33 | return options; 34 | } 35 | @end 36 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/GroupHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMGroup+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/28. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMGroup (Helper) 14 | - (NSDictionary *)toJson; 15 | @end 16 | 17 | @interface EMGroupOptions (Helper) 18 | + (EMGroupOptions *)fromJson:(NSDictionary *)dict; 19 | - (NSDictionary *)toJson; 20 | + (EMGroupStyle)styleFromInt:(int)style; 21 | + (int)styleToInt:(EMGroupStyle)style; 22 | @end 23 | 24 | @interface EMGroupSharedFile (Helper) 25 | - (NSDictionary *)toJson; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/GroupManagerWrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMGroupManagerWrapper.h 3 | // FlutterTest 4 | // 5 | // Created by 杜洁鹏 on 2019/10/17. 6 | // Copyright © 2019 Easemob. All rights reserved. 7 | // 8 | 9 | #import "Wrapper.h" 10 | #import "ClientWrapper.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface GroupManagerWrapper : Wrapper 15 | @property (nonatomic, weak) ClientWrapper *clientWrapper; 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/GroupMessageAckHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMGroupMessageAck+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2021/11/25. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMGroupMessageAck (Helper) 14 | - (NSDictionary *)toJson; 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/GroupMessageAckHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMGroupMessageAck+Flutter.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2021/11/25. 6 | // 7 | 8 | #import "GroupMessageAckHelper.h" 9 | 10 | @implementation EMGroupMessageAck (Helper) 11 | - (NSDictionary *)toJson{ 12 | NSMutableDictionary *data = [NSMutableDictionary dictionary]; 13 | data[@"msg_id"] = self.messageId; 14 | data[@"ack_id"] = self.readAckId; 15 | data[@"from"] = self.from; 16 | data[@"content"] = self.content; 17 | data[@"count"] = @(self.readCount); 18 | data[@"timestamp"] = @(self.timestamp); 19 | return data; 20 | } 21 | @end 22 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Header.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2024/12/25. 6 | // 7 | 8 | #ifndef Header_h 9 | #define Header_h 10 | 11 | 12 | #endif /* Header_h */ 13 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/Helper.h: -------------------------------------------------------------------------------- 1 | // 2 | // Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2025/2/17. 6 | // 7 | 8 | #import 9 | #import "ChatHeaders.h" 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface Helper : NSObject 13 | + (void)mergeMessage:(EMChatMessage *)msg withDBMessage:(EMChatMessage *)dbMsg; 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/Helper.m: -------------------------------------------------------------------------------- 1 | // 2 | // Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2025/2/17. 6 | // 7 | 8 | #import "Helper.h" 9 | 10 | @implementation Helper 11 | + (void)mergeMessage:(EMChatMessage *)msg withDBMessage:(EMChatMessage *)dbMsg { 12 | dbMsg.timestamp = msg.timestamp; 13 | dbMsg.localTime = msg.localTime; 14 | dbMsg.status = msg.status; 15 | dbMsg.isReadAcked = msg.isReadAcked; 16 | dbMsg.isChatThreadMessage = msg.isChatThreadMessage; 17 | dbMsg.isNeedGroupAck = msg.isNeedGroupAck; 18 | dbMsg.isDeliverAcked = msg.isDeliverAcked; 19 | dbMsg.isRead = msg.isRead; 20 | dbMsg.isListened = msg.isListened; 21 | dbMsg.receiverList = msg.receiverList; 22 | dbMsg.priority = msg.priority; 23 | dbMsg.deliverOnlineOnly = msg.deliverOnlineOnly; 24 | dbMsg.ext = msg.ext; 25 | dbMsg.body = msg.body; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ImFlutterSdkPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface ImFlutterSdkPlugin : NSObject 4 | @end 5 | 6 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ImFlutterSdkPlugin.m: -------------------------------------------------------------------------------- 1 | #import "ImFlutterSdkPlugin.h" 2 | 3 | #import "ChatManagerWrapper.h" 4 | #import "ClientWrapper.h" 5 | #import "ContactManagerWrapper.h" 6 | #import "ConversationWrapper.h" 7 | #import "GroupManagerWrapper.h" 8 | #import "ChatroomManagerWrapper.h" 9 | #import "ChatHeaders.h" 10 | #import 11 | 12 | 13 | @implementation ImFlutterSdkPlugin 14 | 15 | + (void)registerWithRegistrar:(NSObject*)registrar { 16 | ClientWrapper *wrapper = [[ClientWrapper alloc] initWithChannelName:EMChannelName(@"chat_client") registrar:registrar]; 17 | [registrar publish:wrapper]; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ListenerHandle.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMListenerHandle.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/4/24. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | 13 | typedef void (^ListenerHandleCallback)(void); 14 | 15 | @interface ListenerHandle : NSObject 16 | + (ListenerHandle *)sharedInstance; 17 | - (void)addHandle:(ListenerHandleCallback)handle; 18 | - (void)startCallback; 19 | - (void)clearHandle; 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ListenerHandle.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMListenerHandle.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/4/24. 6 | // 7 | 8 | #import "ListenerHandle.h" 9 | 10 | 11 | @interface ListenerHandle () 12 | { 13 | NSMutableArray *_handleList; 14 | BOOL _hasReady; 15 | } 16 | @end 17 | 18 | @implementation ListenerHandle 19 | 20 | + (ListenerHandle *)sharedInstance { 21 | static ListenerHandle *handle = nil; 22 | static dispatch_once_t onceToken; 23 | dispatch_once(&onceToken, ^{ 24 | handle = [[ListenerHandle alloc] init]; 25 | }); 26 | return handle; 27 | } 28 | 29 | - (instancetype)init { 30 | if (self = [super init]) { 31 | _handleList = [NSMutableArray array]; 32 | } 33 | 34 | return self; 35 | } 36 | 37 | - (void)addHandle:(ListenerHandleCallback)handle { 38 | [_handleList addObject:handle]; 39 | if (_hasReady) { 40 | [self _runHandle]; 41 | } 42 | } 43 | 44 | - (void)_runHandle { 45 | @synchronized(self){ 46 | NSArray *ary = _handleList; 47 | for (ListenerHandleCallback callback in ary) { 48 | callback(); 49 | } 50 | [_handleList removeAllObjects]; 51 | } 52 | } 53 | 54 | - (void)startCallback { 55 | _hasReady = YES; 56 | [self _runHandle]; 57 | } 58 | 59 | - (void)clearHandle { 60 | _hasReady = NO; 61 | @synchronized(self){ 62 | [_handleList removeAllObjects]; 63 | } 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/LoginExtensionInfoHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMLoginExtensionInfo+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2024/8/22. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface EMLoginExtensionInfo (Helper) 13 | - (NSDictionary *)toJson; 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/LoginExtensionInfoHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMLoginExtensionInfo+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2024/8/22. 6 | // 7 | 8 | #import "LoginExtensionInfoHelper.h" 9 | 10 | @implementation EMLoginExtensionInfo (Helper) 11 | - (NSDictionary *)toJson{ 12 | NSMutableDictionary *data = [NSMutableDictionary dictionary]; 13 | data[@"deviceName"] = self.deviceName; 14 | data[@"ext"] = self.extensionInfo; 15 | 16 | return data; 17 | } 18 | @end 19 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/MessageHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMChatMessage+Helper.h 3 | // Pods 4 | // 5 | // Created by 杜洁鹏 on 2020/9/11. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMChatMessage (Helper) 14 | + (EMChatMessage *)fromJson:(NSDictionary *)aJson; 15 | - (NSDictionary *)toJson; 16 | 17 | @end 18 | 19 | @interface EMMessageBody (Helper) 20 | + (EMMessageBody *)fromJson:(NSDictionary *)aJson; 21 | - (NSDictionary *)toJson; 22 | @end 23 | 24 | @interface EMTextMessageBody (Helper) 25 | + (EMTextMessageBody *)fromJson:(NSDictionary *)aJson; 26 | - (NSDictionary *)toJson; 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/MessagePinInfoHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMMessagePinInfo+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/28. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | 14 | @interface EMMessagePinInfo (Helper) 15 | + (EMMessagePinInfo *)fromJson:(NSDictionary *)dict; 16 | - (NSDictionary *)toJson; 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/MessagePinInfoHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMMessagePinInfo+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/28. 6 | // 7 | 8 | #import "MessagePinInfoHelper.h" 9 | 10 | 11 | @implementation EMMessagePinInfo (Helper) 12 | - (NSDictionary *)toJson { 13 | NSMutableDictionary *ret = [NSMutableDictionary new]; 14 | ret[@"operatorId"] = self.operatorId; 15 | ret[@"pinTime"] = @(self.pinTime); 16 | return ret; 17 | } 18 | 19 | + (EMMessagePinInfo *)fromJson:(NSDictionary *)dict { 20 | EMMessagePinInfo *info = [[EMMessagePinInfo alloc] init]; 21 | info.operatorId = dict[@"operatorId"]; 22 | info.pinTime = [dict[@"pinTime"] integerValue]; 23 | return info; 24 | } 25 | 26 | @end 27 | 28 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/MessageReactionChangeHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMMessageReactionChange+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/5/18. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMMessageReactionChange (Helper) 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/MessageReactionChangeHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMMessageReactionChange+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/5/18. 6 | // 7 | 8 | #import "MessageReactionChangeHelper.h" 9 | #import "MessageReactionHelper.h" 10 | #import "MessageReactionOperationHelper.h" 11 | 12 | @implementation EMMessageReactionChange (Helper) 13 | 14 | - (nonnull NSDictionary *)toJson { 15 | NSMutableDictionary *ret = [NSMutableDictionary dictionary]; 16 | ret[@"conversationId"] = self.conversationId; 17 | ret[@"messageId"] = self.messageId; 18 | NSMutableArray *reactions = [NSMutableArray array]; 19 | for (EMMessageReaction *reaction in self.reactions) { 20 | [reactions addObject:[reaction toJson]]; 21 | } 22 | ret[@"reactions"] = reactions; 23 | 24 | NSMutableArray *operations = [NSMutableArray array]; 25 | for (EMMessageReactionOperation *operation in self.operations) { 26 | [operations addObject:[operation toJson]]; 27 | }; 28 | ret[@"operations"] = operations; 29 | return ret; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/MessageReactionHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMMessageReaction+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/5/18. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMMessageReaction (Helper) 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/MessageReactionHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMMessageReaction+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/5/18. 6 | // 7 | 8 | #import "MessageReactionHelper.h" 9 | 10 | @implementation EMMessageReaction (Helper) 11 | 12 | - (nonnull NSDictionary *)toJson { 13 | return @{ 14 | @"reaction": self.reaction, 15 | @"count": @(self.count), 16 | @"isAddedBySelf": @(self.isAddedBySelf), 17 | @"userList": self.userList, 18 | }; 19 | } 20 | 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/MessageReactionOperationHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMMessageReactionOperation+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2023/5/17. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface EMMessageReactionOperation (Helper) 13 | -(NSDictionary *)toJson; 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/MessageReactionOperationHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMMessageReactionOperation+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2023/5/17. 6 | // 7 | 8 | #import "MessageReactionOperationHelper.h" 9 | 10 | @implementation EMMessageReactionOperation (Helper) 11 | - (NSDictionary *)toJson { 12 | return @{@"userId": self.userId, 13 | @"reaction": self.reaction, 14 | @"operate": @(self.operate) 15 | }; 16 | } 17 | @end 18 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/MessageWrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMChatMessageWrapper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/5/5. 6 | // 7 | 8 | #import "Wrapper.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface MessageWrapper : Wrapper 13 | 14 | 15 | 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/MessageWrapper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMChatMessageWrapper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/5/5. 6 | // 7 | 8 | #import 9 | #import "ChatHeaders.h" 10 | #import "MessageWrapper.h" 11 | #import "MethodKeys.h" 12 | 13 | #import "MessageReactionHelper.h" 14 | #import "ThreadHelper.h" 15 | #import "MessagePinInfoHelper.h" 16 | 17 | 18 | @implementation MessageWrapper 19 | - (instancetype)initWithChannelName:(NSString *)aChannelName 20 | registrar:(NSObject*)registrar { 21 | if(self = [super initWithChannelName:aChannelName 22 | registrar:registrar]) { 23 | } 24 | return self; 25 | } 26 | 27 | 28 | #pragma mark - FlutterPlugin 29 | 30 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { 31 | 32 | if([ChatGetReactionList isEqualToString:call.method]){ 33 | [self getReactionList:call.arguments channelName:call.method result:result]; 34 | } else if([ChatGroupAckCount isEqualToString:call.method]) { 35 | [self getGroupAckCount:call.arguments channelName:call.method result:result]; 36 | } else if([ChatThread isEqualToString:call.method]) { 37 | [self getChatThread:call.arguments channelName:call.method result:result]; 38 | } 39 | // 450 40 | else if ([getPinInfo isEqualToString:call.method]) { 41 | [self getMessagePinInfo:call.arguments channelName:call.method result:result]; 42 | } 43 | else { 44 | [super handleMethodCall:call result:result]; 45 | } 46 | } 47 | 48 | 49 | - (void)getReaction:(NSDictionary *)param 50 | channelName:(NSString *)aChannelName 51 | result:(FlutterResult)result { 52 | NSString *msgId = param[@"msgId"]; 53 | NSString *reaction = param[@"reaction"]; 54 | EMChatMessage *msg = [self getMessageWithId:msgId]; 55 | EMMessageReaction *msgReaction = [msg getReaction:reaction]; 56 | [self wrapperCallBack:result 57 | channelName:aChannelName 58 | error:nil 59 | object:[msgReaction toJson]]; 60 | } 61 | 62 | - (void)getReactionList:(NSDictionary *)param 63 | channelName:(NSString *)aChannelName 64 | result:(FlutterResult)result { 65 | NSString *msgId = param[@"msgId"]; 66 | EMChatMessage *msg = [self getMessageWithId:msgId]; 67 | NSMutableArray *list = [NSMutableArray array]; 68 | for (EMMessageReaction *reaction in msg.reactionList) { 69 | [list addObject:[reaction toJson]]; 70 | } 71 | 72 | [self wrapperCallBack:result 73 | channelName:aChannelName 74 | error:nil 75 | object:list.count > 0 ? list : nil]; 76 | } 77 | 78 | - (void)getGroupAckCount:(NSDictionary *)param 79 | channelName:(NSString *)aChannelName 80 | result:(FlutterResult)result { 81 | NSString *msgId = param[@"msgId"]; 82 | EMChatMessage *msg = [self getMessageWithId:msgId]; 83 | [self wrapperCallBack:result 84 | channelName:aChannelName 85 | error:nil 86 | object:@(msg.groupAckCount)]; 87 | 88 | } 89 | 90 | - (void)getChatThread:(NSDictionary *)param 91 | channelName:(NSString *)aChannelName 92 | result:(FlutterResult)result { 93 | NSString *msgId = param[@"msgId"]; 94 | EMChatMessage *msg = [self getMessageWithId:msgId]; 95 | [self wrapperCallBack:result 96 | channelName:aChannelName 97 | error:nil 98 | object:[msg.chatThread toJson]] ; 99 | } 100 | 101 | - (void)getMessagePinInfo:(NSDictionary *)param 102 | channelName:(NSString *)aChannelName 103 | result:(FlutterResult)result { 104 | NSString *msgId = param[@"msgId"]; 105 | EMChatMessage *msg = [self getMessageWithId:msgId]; 106 | [self wrapperCallBack:result 107 | channelName:aChannelName 108 | error:nil 109 | object:[msg.pinnedInfo toJson]] ; 110 | } 111 | 112 | 113 | - (EMChatMessage *)getMessageWithId:(NSString *)aMessageId { 114 | return [EMClient.sharedClient.chatManager getMessageWithMessageId:aMessageId]; 115 | } 116 | 117 | @end 118 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ModeToJson.h: -------------------------------------------------------------------------------- 1 | // 2 | // EaseModeToJson.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/27. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @protocol ModeToJson 13 | - (NSDictionary *)toJson; 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/NSArray+Helper.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/4/28. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface NSArray (Helper) 13 | - (NSArray *)toJsonArray; 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/NSArray+Helper.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/4/28. 6 | // 7 | 8 | #import "NSArray+Helper.h" 9 | #import "ModeToJson.h" 10 | 11 | @implementation NSArray (Helper) 12 | - (NSArray *)toJsonArray { 13 | NSMutableArray *ary = nil; 14 | for (id item in self) { 15 | if (ary == nil) { 16 | ary = [NSMutableArray array]; 17 | } 18 | [ary addObject:[item toJson]]; 19 | } 20 | return ary; 21 | } 22 | @end 23 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/OptionsHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMOptions+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/10/12. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMOptions (Helper) 14 | - (NSDictionary *)toJson; 15 | + (EMOptions *)fromJson:(NSDictionary *)aJson; 16 | + (NSDictionary *)extSettings:(NSDictionary *)aJson; 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/PageResultHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMPageResult+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/27. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMPageResult (Helper) 14 | - (NSDictionary *)toJson; 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/PageResultHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMPageResult+Flutter.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/9/27. 6 | // 7 | 8 | #import "PageResultHelper.h" 9 | 10 | @implementation EMPageResult (Helper) 11 | - (NSDictionary *)toJson { 12 | NSMutableDictionary *data = [NSMutableDictionary dictionary]; 13 | NSMutableArray *dataList = [NSMutableArray array]; 14 | for (id obj in self.list) { 15 | [dataList addObject:[obj toJson]]; 16 | } 17 | 18 | data[@"list"] = dataList; 19 | data[@"count"] = @(self.count); 20 | 21 | return data; 22 | } 23 | @end 24 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/PresenceHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMPresence+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/4/27. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMPresence (Helper) 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/PresenceHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMPresence+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/4/27. 6 | // 7 | 8 | #import "PresenceHelper.h" 9 | 10 | @implementation EMPresence (Helper) 11 | 12 | - (nonnull NSDictionary *)toJson { 13 | NSMutableDictionary *details = [NSMutableDictionary dictionary]; 14 | for (EMPresenceStatusDetail *detail in self.statusDetails) { 15 | details[detail.device] = @(detail.status); 16 | } 17 | return @{ 18 | @"publisher": self.publisher, 19 | @"statusDetails": details, 20 | @"statusDescription": self.statusDescription, 21 | @"lastTime": @(self.lastTime), 22 | @"expiryTime": @(self.expirytime) 23 | }; 24 | } 25 | 26 | @end 27 | 28 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/PresenceManagerWrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMPresenceManagerWrapper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/4/27. 6 | // 7 | 8 | #import "Wrapper.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface PresenceManagerWrapper : Wrapper 13 | 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ProgressManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMProgressManager.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/5/23. 6 | // 7 | 8 | #import "Wrapper.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface ProgressManager : Wrapper 13 | - (void)sendDownloadSuccessToFlutter:(NSString *)fileId path:(NSString *)savePath; 14 | - (void)sendDownloadProgressToFlutter:(NSString *)fileId progress:(int)progress; 15 | - (void)sendDownloadErrorToFlutter:(NSString *)fileId error:(EMError *)error; 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ProgressManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMProgressManager.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/5/23. 6 | // 7 | #import 8 | #import "ChatHeaders.h" 9 | #import "ProgressManager.h" 10 | #import "ErrorHelper.h" 11 | 12 | @interface ProgressManager () 13 | 14 | @end 15 | 16 | 17 | @implementation ProgressManager 18 | 19 | - (instancetype)initWithChannelName:(NSString *)aChannelName 20 | registrar:(NSObject*)registrar { 21 | if(self = [super initWithChannelName:aChannelName 22 | registrar:registrar]) { 23 | 24 | } 25 | return self; 26 | } 27 | 28 | - (void)sendDownloadSuccessToFlutter:(NSString *)fileId path:(NSString *)savePath { 29 | [self.channel invokeMethod:@"onSuccess" arguments:@{@"fileId":fileId, @"savePath": savePath}]; 30 | } 31 | 32 | - (void)sendDownloadProgressToFlutter:(NSString *)fileId progress:(int)progress { 33 | [self.channel invokeMethod:@"onProgress" arguments:@{@"fileId":fileId, @"progress": @(progress)}]; 34 | } 35 | 36 | - (void)sendDownloadErrorToFlutter:(NSString *)fileId error:(EMError *)error { 37 | [self.channel invokeMethod:@"onError" arguments:@{@"fileId":fileId, @"error": [error toJson]}]; 38 | } 39 | 40 | 41 | - (void)unRegisterEaseListener { 42 | } 43 | 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/PushManagerWrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMPushManagerWrapper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 东海 on 2020/5/7. 6 | // 7 | 8 | #import "Wrapper.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface PushManagerWrapper : Wrapper 13 | 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/PushOptionsHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMPushOptions+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/10/15. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMPushOptions (Helper) 14 | - (NSDictionary *)toJson; 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/PushOptionsHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMPushOptions+Flutter.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2020/10/15. 6 | // 7 | 8 | #import "PushOptionsHelper.h" 9 | 10 | @implementation EMPushOptions (Helper) 11 | - (NSDictionary *)toJson{ 12 | NSMutableDictionary *data = [NSMutableDictionary dictionary]; 13 | data[@"pushStyle"] = @(self.displayStyle != EMPushDisplayStyleSimpleBanner); 14 | data[@"displayName"] = self.displayName; 15 | return data; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/RecallInfoHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMRecallMessageInfo+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2024/5/7. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface EMRecallMessageInfo (Helper) 13 | - (NSDictionary *)toJson; 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/RecallInfoHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMRecallMessageInfo+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2024/5/7. 6 | // 7 | 8 | #import "RecallInfoHelper.h" 9 | #import "MessageHelper.h" 10 | 11 | @implementation EMRecallMessageInfo (Helper) 12 | - (NSDictionary *)toJson { 13 | NSMutableDictionary *ret = [NSMutableDictionary dictionary]; 14 | ret[@"recallMsgId"] = self.recallMessageId; 15 | ret[@"recallBy"] = self.recallBy; 16 | ret[@"ext"] = self.ext; 17 | ret[@"msg"] = [self.recallMessage toJson]; 18 | // 4.10 19 | ret[@"conversationId"] = self.conversationId; 20 | return ret; 21 | } 22 | @end 23 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/SilentModeParamHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMSilentModeParam+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/7/8. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMSilentModeParam (Helper) 14 | + (EMSilentModeParam *)fromJson:(NSDictionary *)dict; 15 | + (int)remindTypeToInt:(EMPushRemindType)type; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/SilentModeParamHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMSilentModeParam+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/7/8. 6 | // 7 | 8 | #import "SilentModeParamHelper.h" 9 | #import "SilentModeTimeHelper.h" 10 | 11 | @implementation EMSilentModeParam (Helper) 12 | + (EMSilentModeParam *)fromJson:(NSDictionary *)dict { 13 | EMSilentModeParamType paramType = [self paramTypeFromInt:[dict[@"paramType"] intValue]]; 14 | EMSilentModeParam *param = [[EMSilentModeParam alloc] initWithParamType:paramType]; 15 | NSDictionary *dictStartTime = dict[@"startTime"]; 16 | NSDictionary *dictEndTime = dict[@"endTime"]; 17 | int duration = [dict[@"duration"] intValue]; 18 | 19 | EMPushRemindType remindType = [self remindTypeFromInt:[dict[@"remindType"] intValue]]; 20 | 21 | param.remindType = remindType; 22 | param.silentModeStartTime = [EMSilentModeTime fromJson:dictStartTime]; 23 | param.silentModeEndTime = [EMSilentModeTime fromJson:dictEndTime]; 24 | param.silentModeDuration = duration; 25 | return param; 26 | } 27 | 28 | 29 | + (EMSilentModeParamType)paramTypeFromInt:(int)iParamType { 30 | EMSilentModeParamType ret = EMSilentModeParamTypeRemindType; 31 | if (iParamType == 0) { 32 | ret = EMSilentModeParamTypeRemindType; 33 | }else if (iParamType == 1) { 34 | ret = EMSilentModeParamTypeDuration; 35 | }else if (iParamType == 2) { 36 | ret = EMSilentModeParamTypeInterval; 37 | } 38 | return ret; 39 | } 40 | 41 | + (EMPushRemindType)remindTypeFromInt:(int)iRemindTime { 42 | EMPushRemindType ret = EMPushRemindTypeAll; 43 | if (iRemindTime == 0) { 44 | ret = EMPushRemindTypeAll; 45 | }else if (iRemindTime == 1) { 46 | ret = EMPushRemindTypeMentionOnly; 47 | }else if (iRemindTime == 2) { 48 | ret = EMPushRemindTypeNone; 49 | } 50 | return ret; 51 | } 52 | 53 | + (int)remindTypeToInt:(EMPushRemindType)type { 54 | int ret = 0; 55 | switch(type) { 56 | case EMPushRemindTypeAll: 57 | ret = 0; 58 | break; 59 | case EMPushRemindTypeMentionOnly: 60 | ret = 1; 61 | break; 62 | case EMPushRemindTypeNone: 63 | ret = 2; 64 | break; 65 | } 66 | return ret; 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/SilentModeResultHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMSilentModeResult+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/7/11. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface EMSilentModeResult (Helper) 13 | - (NSDictionary *)toJson; 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/SilentModeResultHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMSilentModeResult+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/7/11. 6 | // 7 | 8 | #import "SilentModeResultHelper.h" 9 | #import "SilentModeTimeHelper.h" 10 | #import "SilentModeParamHelper.h" 11 | #import "ConversationHelper.h" 12 | #import "EnumTools.h" 13 | 14 | @implementation EMSilentModeResult (Helper) 15 | - (NSDictionary *)toJson { 16 | NSMutableDictionary *ret = [[NSMutableDictionary alloc] init]; 17 | ret[@"expireTs"] = @(self.expireTimestamp); 18 | ret[@"startTime"] = [self.silentModeStartTime toJson]; 19 | ret[@"endTime"] = [self.silentModeEndTime toJson]; 20 | ret[@"remindType"] = @([EMSilentModeParam remindTypeToInt:self.remindType]); 21 | ret[@"conversationId"] = self.conversationID; 22 | ret[@"conversationType"] = [NSNumber numberWithInteger:[EnumTools conversationTypeToInt:self.conversationType]]; 23 | return ret; 24 | } 25 | @end 26 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/SilentModeTimeHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMSilentModeTime+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/7/11. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMSilentModeTime (Helper) 14 | + (EMSilentModeTime *)fromJson:(NSDictionary *)dict; 15 | - (NSDictionary *)toJson; 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/SilentModeTimeHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMSilentModeTime+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/7/11. 6 | // 7 | 8 | #import "SilentModeTimeHelper.h" 9 | 10 | @implementation EMSilentModeTime (Helper) 11 | + (EMSilentModeTime *)fromJson:(NSDictionary *)dict { 12 | int hour = [dict[@"hour"] intValue]; 13 | int minute = [dict[@"minute"] intValue]; 14 | return [[EMSilentModeTime alloc] initWithHours:hour minutes:minute]; 15 | } 16 | - (NSDictionary *)toJson { 17 | return @{@"hour":@(self.hours), @"minute": @(self.minutes)}; 18 | } 19 | 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ThreadEventHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMChatThreadEvent+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/6/6. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMChatThreadEvent (Helper) 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ThreadEventHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMChatThreadEvent+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/6/6. 6 | // 7 | 8 | #import "ThreadEventHelper.h" 9 | #import "ThreadHelper.h" 10 | #import "EnumTools.h" 11 | 12 | @implementation EMChatThreadEvent (Helper) 13 | - (nonnull NSDictionary *)toJson { 14 | NSMutableDictionary *ret = [NSMutableDictionary dictionary]; 15 | ret[@"from"] = self.from; 16 | ret[@"type"] = @([self getIntOperation]); 17 | ret[@"thread"] = [self.chatThread toJson]; 18 | return ret; 19 | } 20 | 21 | 22 | - (NSInteger)getIntOperation { 23 | return [EnumTools threadOperationToInt:self.type]; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ThreadHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMChatThread+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/5/29. 6 | // 7 | 8 | 9 | #import "ChatHeaders.h" 10 | #import "ModeToJson.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface EMChatThread (Helper) 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ThreadHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMChatThread+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/5/29. 6 | // 7 | 8 | #import "ThreadHelper.h" 9 | #import "MessageHelper.h" 10 | 11 | @implementation EMChatThread (Helper) 12 | - (nonnull NSDictionary *)toJson { 13 | NSMutableDictionary *ret = [NSMutableDictionary dictionary]; 14 | ret[@"threadId"] = self.threadId; 15 | ret[@"threadName"] = self.threadName; 16 | ret[@"owner"] = self.owner; 17 | ret[@"msgId"] = self.messageId; 18 | ret[@"parentId"] = self.parentId; 19 | ret[@"memberCount"] = @(self.membersCount); 20 | ret[@"messageCount"] = @(self.messageCount); 21 | ret[@"createAt"] = @(self.createAt); 22 | if (self.lastMessage && self.lastMessage.messageId.length > 0) { 23 | ret[@"lastMessage"] = [self.lastMessage toJson]; 24 | } 25 | return ret; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/ThreadManagerWrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMChatThreadManagerWrapper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/5/7. 6 | // 7 | 8 | #import "Wrapper.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface ThreadManagerWrapper : Wrapper 13 | 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/TranslateLanguageHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMTranslateLanguage+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/5/3. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface EMTranslateLanguage (Helper) 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/TranslateLanguageHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMTranslateLanguage+Helper.m 3 | // im_flutter_sdk 4 | // 5 | // Created by 杜洁鹏 on 2022/5/3. 6 | // 7 | 8 | #import "TranslateLanguageHelper.h" 9 | 10 | @implementation EMTranslateLanguage (Helper) 11 | 12 | - (nonnull NSDictionary *)toJson { 13 | NSMutableDictionary *ret = [NSMutableDictionary dictionary]; 14 | ret[@"code"] = self.languageCode; 15 | ret[@"name"] = self.languageName; 16 | ret[@"nativeName"] = self.languageNativeName; 17 | return ret; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/UserInfoHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMUserInfo+Helper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by liujinliang on 2021/4/28. 6 | // 7 | 8 | #import "ChatHeaders.h" 9 | #import "ModeToJson.h" 10 | 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface EMUserInfo (Helper) 15 | -(NSDictionary *)toJson; 16 | + (EMUserInfo *)fromJson:(NSDictionary *)aJson; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/UserInfoHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMUserInfo+Flutter.m 3 | // im_flutter_sdk 4 | // 5 | // Created by liujinliang on 2021/4/28. 6 | // 7 | 8 | #import "UserInfoHelper.h" 9 | 10 | @implementation EMUserInfo (Helper) 11 | 12 | - (NSDictionary *)toJson { 13 | NSMutableDictionary *ret = [NSMutableDictionary dictionary]; 14 | ret[@"userId"] = self.userId; 15 | ret[@"nickName"] = self.nickname; 16 | ret[@"avatarUrl"] = self.avatarUrl; 17 | ret[@"mail"] = self.mail; 18 | ret[@"phone"] = self.phone; 19 | ret[@"gender"] = @(self.gender); 20 | ret[@"sign"] = self.sign; 21 | ret[@"birth"] = self.birth; 22 | ret[@"ext"] = self.ext; 23 | 24 | return ret; 25 | 26 | } 27 | 28 | + (EMUserInfo *)fromJson:(NSDictionary *)aJson { 29 | EMUserInfo *userInfo = EMUserInfo.new; 30 | userInfo.nickname = aJson[@"nickName"]; 31 | userInfo.avatarUrl = aJson[@"avatarUrl"]; 32 | userInfo.mail = aJson[@"mail"]; 33 | userInfo.phone = aJson[@"phone"]; 34 | userInfo.gender = [aJson[@"gender"] integerValue] ?: 0; 35 | userInfo.sign = aJson[@"sign"]; 36 | userInfo.birth = aJson[@"birth"]; 37 | if (![aJson[@"ext"] isKindOfClass:[NSNull class]]) { 38 | userInfo.ext = aJson[@"ext"]; 39 | } 40 | return [userInfo copy]; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/UserInfoManagerWrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMUserInfoManagerWrapper.h 3 | // im_flutter_sdk 4 | // 5 | // Created by liujinliang on 2021/4/26. 6 | // 7 | 8 | #import "Wrapper.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface UserInfoManagerWrapper : Wrapper 13 | 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/Wrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMWrapper.h 3 | // 4 | // 5 | // Created by 杜洁鹏 on 2019/10/8. 6 | // 7 | 8 | #import 9 | #import "ChatHeaders.h" 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | #define EMChannelName(name) [NSString stringWithFormat:@"com.chat.im/%@", name] 13 | 14 | 15 | @interface Wrapper : NSObject 16 | 17 | @property(nonatomic, strong) FlutterMethodChannel *channel; 18 | @property(nonatomic, strong) NSObject *flutterPluginRegister; 19 | 20 | - (instancetype)initWithChannelName:(NSString *)aChannelName 21 | registrar:(NSObject *)registrar; 22 | 23 | 24 | - (void)wrapperCallBack:(FlutterResult)result 25 | channelName:(NSString *)aChannelName 26 | error:(EMError *__nullable)error 27 | object:(NSObject *__nullable)aObj; 28 | 29 | 30 | - (void)unRegisterEaseListener; 31 | 32 | 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/Classes/Wrapper.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMWrapper.m 3 | // 4 | // 5 | // Created by 杜洁鹏 on 2019/10/8. 6 | // 7 | 8 | #import "Wrapper.h" 9 | #import "ErrorHelper.h" 10 | #define easemob_dispatch_main_async_safe(block)\ 11 | if ([NSThread isMainThread]) {\ 12 | block();\ 13 | } else {\ 14 | dispatch_async(dispatch_get_main_queue(), block);\ 15 | } 16 | 17 | 18 | @implementation Wrapper 19 | 20 | - (instancetype)initWithChannelName:(NSString *)aChannelName 21 | registrar:(NSObject*)registrar { 22 | if(self = [super init]) { 23 | self.flutterPluginRegister = registrar; 24 | FlutterJSONMethodCodec *codec = [FlutterJSONMethodCodec sharedInstance]; 25 | FlutterMethodChannel* channel = [FlutterMethodChannel methodChannelWithName:aChannelName 26 | binaryMessenger:[registrar messenger] 27 | codec:codec]; 28 | self.channel = channel; 29 | [registrar addMethodCallDelegate:self channel:channel]; 30 | } 31 | return self; 32 | } 33 | 34 | 35 | 36 | - (void)wrapperCallBack:(FlutterResult)result 37 | channelName:(NSString *)aChannelName 38 | error:(EMError *)error 39 | object:(NSObject *)aObj 40 | { 41 | if (result) { 42 | NSMutableDictionary *dic = [NSMutableDictionary dictionary]; 43 | dic[@"error"] = [error toJson]; 44 | if (aObj) { 45 | dic[aChannelName] = aObj; 46 | } 47 | 48 | easemob_dispatch_main_async_safe(^(){ 49 | result(dic); 50 | }); 51 | } 52 | } 53 | 54 | - (void)unRegisterEaseListener { 55 | 56 | } 57 | 58 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { 59 | result(FlutterMethodNotImplemented); 60 | } 61 | 62 | 63 | + (void)registerWithRegistrar:(nonnull NSObject *)registrar { 64 | 65 | } 66 | 67 | - (void)detachFromEngineForRegistrar:(NSObject*)registrar { 68 | [self unRegisterEaseListener]; 69 | } 70 | 71 | -(void)dealloc{ 72 | NSLog(@"wrapper dealloc"); 73 | } 74 | 75 | 76 | 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/ios/im_flutter_sdk_ios.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 3 | # 4 | Pod::Spec.new do |s| 5 | s.name = 'im_flutter_sdk_ios' 6 | s.version = '0.0.1' 7 | s.summary = 'A new flutter plugin project.' 8 | s.description = <<-DESC 9 | A new flutter plugin project. 10 | DESC 11 | s.homepage = 'http://example.com' 12 | s.license = { :file => '../LICENSE' } 13 | s.author = { 'Your Company' => 'email@example.com' } 14 | s.source = { :path => '.' } 15 | 16 | s.source_files = 'Classes/**/*' 17 | s.public_header_files = 'Classes/**/*.h' 18 | 19 | s.dependency 'Flutter' 20 | s.dependency 'HyphenateChat','4.13.0' 21 | # s.dependency 'ShengwangChat_iOS','1.3.2' 22 | s.ios.vendored_frameworks = 'framework/HyphenateChat.xcframework', 'framework/aosl.xcframework' 23 | s.ios.deployment_target = '12.0' 24 | 25 | end 26 | 27 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/lib/im_flutter_sdk_ios.dart: -------------------------------------------------------------------------------- 1 | export 'src/client_ios.dart'; 2 | -------------------------------------------------------------------------------- /im_flutter_sdk_ios/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: im_flutter_sdk_ios 2 | description: Integrate the Chat SDK to enjoy the global IM services with high reliability, ultra-low latency, and high concurrency. 3 | version: 4.13.0+1 4 | homepage: https://www.easemob.com 5 | 6 | environment: 7 | sdk: '>=3.3.0 <4.0.0' 8 | flutter: '>=3.3.0' 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | im_flutter_sdk_interface: ^4.13.0+1 15 | 16 | dev_dependencies: 17 | flutter_lints: ^3.0.0 18 | 19 | flutter: 20 | plugin: 21 | implements: im_flutter_sdk 22 | platforms: 23 | ios: 24 | dartPluginClass: ClientIOS 25 | pluginClass: ImFlutterSdkPlugin 26 | --------------------------------------------------------------------------------