├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── android ├── .gitignore ├── build.gradle ├── gradle.properties ├── settings.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── org │ └── leanflutter │ └── plugins │ └── flutter_qiyu │ ├── FlutterQiyuPlugin.java │ ├── GlideGifImagerLoader.java │ ├── GlideImageLoader.java │ └── QiYuUtils.java ├── example ├── .gitignore ├── README.md ├── analysis_options.yaml ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ ├── io │ │ │ │ │ └── flutter │ │ │ │ │ │ └── app │ │ │ │ │ │ └── FlutterMultiDexApplication.java │ │ │ │ └── org │ │ │ │ │ └── leanflutter │ │ │ │ │ └── plugins │ │ │ │ │ └── flutter_qiyu_example │ │ │ │ │ └── MainActivity.java │ │ │ └── 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 │ │ │ │ └── xml │ │ │ │ └── network_security_config.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── 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.h │ │ ├── AppDelegate.m │ │ ├── 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 │ │ └── main.m ├── lib │ └── main.dart ├── pubspec.lock ├── pubspec.yaml └── test │ └── widget_test.dart ├── ios ├── .gitignore ├── Assets │ └── .gitkeep ├── Classes │ ├── FlutterQiyuPlugin.h │ ├── FlutterQiyuPlugin.m │ ├── UIBarButtonItem+blocks.h │ └── UIBarButtonItem+blocks.m └── flutter_qiyu.podspec ├── lib ├── flutter_qiyu.dart ├── qiyu.dart ├── qy_commodity_info.dart ├── qy_service_window_params.dart ├── qy_source.dart └── qy_user_info_params.dart ├── pubspec.lock └── 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 | # 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 | .packages 30 | build/ 31 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.1.2 2 | 3 | - 更换新版七鱼sdk #16 4 | 5 | ## 0.1.1 6 | 7 | - 修复 Android 端 `channel.invokeMethod` 未初始化完成前被调用的问题 8 | 9 | ## 0.1.0 10 | 11 | - [#7](https://github.com/leanflutter/flutter_qiyu/issues/7) 修复 iOS 端编译错误问题 12 | 13 | ## 0.0.3 14 | 15 | - [#6](https://github.com/leanflutter/flutter_qiyu/issues/6) 修复 Android 端编译错误的问题 16 | 17 | ## 0.0.2 18 | 19 | - 空安全支持 20 | - [#4](https://github.com/leanflutter/flutter_qiyu/issues/4) 修复程序包com.netease.nimlib.sdk不存在的问题 21 | 22 | ## 0.0.1 23 | 24 | - first release 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2014 LiJianying 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_qiyu 2 | 3 | 适用于 Flutter 的七鱼客服插件 4 | 5 | 6 | 7 | 8 | 9 | - [快速开始](#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B) 10 | - [安装](#%E5%AE%89%E8%A3%85) 11 | - [用法](#%E7%94%A8%E6%B3%95) 12 | - [初始化 SDK](#%E5%88%9D%E5%A7%8B%E5%8C%96-sdk) 13 | - [上报用户信息](#%E4%B8%8A%E6%8A%A5%E7%94%A8%E6%88%B7%E4%BF%A1%E6%81%AF) 14 | - [打开服务窗口](#%E6%89%93%E5%BC%80%E6%9C%8D%E5%8A%A1%E7%AA%97%E5%8F%A3) 15 | - [获取未读消息数](#%E8%8E%B7%E5%8F%96%E6%9C%AA%E8%AF%BB%E6%B6%88%E6%81%AF%E6%95%B0) 16 | - [自定义客服聊天窗口 UI](#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AE%A2%E6%9C%8D%E8%81%8A%E5%A4%A9%E7%AA%97%E5%8F%A3-ui) 17 | - [相关链接](#%E7%9B%B8%E5%85%B3%E9%93%BE%E6%8E%A5) 18 | - [许可证](#%E8%AE%B8%E5%8F%AF%E8%AF%81) 19 | 20 | 21 | 22 | ## 快速开始 23 | 24 | ### 安装 25 | 26 | 将此添加到包的 pubspec.yaml 文件中: 27 | 28 | ```yaml 29 | dependencies: 30 | flutter_qiyu: ^0.1.1 31 | ``` 32 | 33 | 您可以从命令行安装软件包: 34 | 35 | ```bash 36 | $ flutter packages get 37 | ``` 38 | 39 | ### 用法 40 | 41 | #### 初始化 SDK 42 | 43 | ```dart 44 | QiYu.registerApp( 45 | appKey: '', 46 | appName: 'qiyu example', 47 | ); 48 | ``` 49 | 50 | > 由于七鱼版本升级,Android 平台需要在 `Application#onCreate` 中调用初始化 SDK 方法,请修改以下文件(完整示例参见 example 目录)。 51 | 52 | AndroidManifest.xml 53 | 54 | ```diff 55 | 57 | 58 | ... 59 | 60 | 66 | 67 | ... 68 | 69 | 70 | 71 | ``` 72 | 73 | MainApplication.java 74 | 75 | ```java 76 | package org.leanflutter.plugins.flutter_qiyu_example; 77 | 78 | import org.leanflutter.plugins.flutter_qiyu.FlutterQiyuPlugin; 79 | 80 | import io.flutter.app.FlutterApplication; 81 | 82 | public class MainApplication extends FlutterApplication { 83 | @Override 84 | public void onCreate() { 85 | super.onCreate(); 86 | FlutterQiyuPlugin.initSDK(this, ""); 87 | } 88 | } 89 | ``` 90 | 91 | #### 上报用户信息 92 | 93 | ```dart 94 | QYUserInfoParams userInfoParams = QYUserInfoParams.fromJson({ 95 | 'userId': 'uid10101010', 96 | 'data': 97 | '[{\"key\":\"real_name\", \"value\":\"土豪\"},{\"key\":\"mobile_phone\", \"hidden\":true},{\"key\":\"email\", \"value\":\"13800000000@163.com\"},{\"index\":0, \"key\":\"account\", \"label\":\"账号\", \"value\":\"zhangsan\", \"href\":\"http://example.domain/user/zhangsan\"},{\"index\":1, \"key\":\"sex\", \"label\":\"性别\", \"value\":\"先生\"},{\"index\":5, \"key\":\"reg_date\", \"label\":\"注册日期\", \"value\":\"2015-11-16\"},{\"index\":6, \"key\":\"last_login\", \"label\":\"上次登录时间\", \"value\":\"2015-12-22 15:38:54\"}]' 98 | }); 99 | QiYu.setUserInfo(userInfoParams); 100 | ``` 101 | 102 | #### 打开服务窗口 103 | 104 | ```dart 105 | 106 | QYServiceWindowParams serviceWindowParams = 107 | QYServiceWindowParams.fromJson({ 108 | 'source': { 109 | 'sourceTitle': '网易七鱼Flutter', 110 | 'sourceUrl': 'http://www.qiyukf.com', 111 | 'sourceCustomInfo': '我是来自自定义的信息' 112 | }, 113 | 'commodityInfo': { 114 | 'commodityInfoTitle': 'Flutter商品', 115 | 'commodityInfoDesc': '这是来自网易七鱼Flutter的商品描述', 116 | 'pictureUrl': 117 | 'http://qiyukf.com/res/img/companyLogo/blmn.png', 118 | 'commodityInfoUrl': 'http://www.qiyukf.com', 119 | 'note': '¥1000', 120 | 'show': true 121 | }, 122 | 'sessionTitle': '网易七鱼123', 123 | 'groupId': 0, 124 | 'staffId': 0, 125 | 'robotId': 0, 126 | 'robotFirst': false, 127 | 'faqTemplateId': 0, 128 | 'vipLevel': 0, 129 | 'showQuitQueue': true, 130 | 'showCloseSessionEntry': true 131 | }); 132 | QiYu.openServiceWindow(serviceWindowParams); 133 | ``` 134 | 135 | #### 获取未读消息数 136 | 137 | ```dart 138 | // 直接获取未读消息数 139 | QiYu.getUnreadCount().then((unreadCount) { 140 | setState(() { 141 | _unreadCount = unreadCount; 142 | }); 143 | }); 144 | // 监听未读消息数变化 145 | QiYu.onUnreadCountChange((unreadCount) { 146 | setState(() { 147 | _qiyuUnreadCount = unreadCount; 148 | }); 149 | }); 150 | ``` 151 | 152 | #### 自定义客服聊天窗口 UI 153 | 154 | ```dart 155 | var params = { 156 | // 157 | }; 158 | QiYu.setCustomUIConfig(params) 159 | ``` 160 | 161 | 详情参数说明同官方 react-native-qiyu 插件: 162 | https://github.com/qiyukf/react-native-qiyu#-setcustomuiconfig 163 | 164 | ## 相关链接 165 | 166 | - https://qiyukf.com 167 | - https://github.com/qiyukf/react-native-qiyu 168 | - https://github.com/qiyukf/QIYU_iOS_SDK 169 | 170 | ## 许可证 171 | 172 | ``` 173 | MIT License 174 | 175 | Copyright (c) 2021 LiJianying 176 | 177 | Permission is hereby granted, free of charge, to any person obtaining a copy 178 | of this software and associated documentation files (the "Software"), to deal 179 | in the Software without restriction, including without limitation the rights 180 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 181 | copies of the Software, and to permit persons to whom the Software is 182 | furnished to do so, subject to the following conditions: 183 | 184 | The above copyright notice and this permission notice shall be included in all 185 | copies or substantial portions of the Software. 186 | 187 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 188 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 189 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 190 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 191 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 192 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 193 | SOFTWARE. 194 | ``` 195 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .cxx 10 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'org.leanflutter.plugins.flutter_qiyu' 2 | version '1.0' 3 | 4 | buildscript { 5 | repositories { 6 | google() 7 | mavenCentral() 8 | } 9 | 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:7.1.2' 12 | } 13 | } 14 | 15 | rootProject.allprojects { 16 | repositories { 17 | google() 18 | mavenCentral() 19 | } 20 | } 21 | 22 | apply plugin: 'com.android.library' 23 | 24 | android { 25 | compileSdkVersion 31 26 | 27 | compileOptions { 28 | sourceCompatibility JavaVersion.VERSION_1_8 29 | targetCompatibility JavaVersion.VERSION_1_8 30 | } 31 | 32 | defaultConfig { 33 | minSdkVersion 16 34 | } 35 | 36 | lintOptions { 37 | disable 'InvalidPackage' 38 | } 39 | } 40 | 41 | dependencies { 42 | implementation "androidx.constraintlayout:constraintlayout:2.1.1" 43 | implementation 'com.qiyukf.unicorn:unicorn:+' 44 | implementation 'com.github.bumptech.glide:glide:4.10.0' 45 | // annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0' 46 | } 47 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'flutter_qiyu' 2 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /android/src/main/java/org/leanflutter/plugins/flutter_qiyu/FlutterQiyuPlugin.java: -------------------------------------------------------------------------------- 1 | package org.leanflutter.plugins.flutter_qiyu; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | import android.util.Log; 7 | 8 | import androidx.annotation.NonNull; 9 | 10 | import com.qiyukf.nimlib.sdk.RequestCallback; 11 | import com.qiyukf.nimlib.sdk.StatusBarNotificationConfig; 12 | import com.qiyukf.unicorn.api.ConsultSource; 13 | import com.qiyukf.unicorn.api.OnBotEventListener; 14 | import com.qiyukf.unicorn.api.ProductDetail; 15 | import com.qiyukf.unicorn.api.UICustomization; 16 | import com.qiyukf.unicorn.api.Unicorn; 17 | import com.qiyukf.unicorn.api.UnreadCountChangeListener; 18 | import com.qiyukf.unicorn.api.YSFOptions; 19 | import com.qiyukf.unicorn.api.YSFUserInfo; 20 | import com.qiyukf.unicorn.api.lifecycle.SessionLifeCycleOptions; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 26 | import io.flutter.plugin.common.BinaryMessenger; 27 | import io.flutter.plugin.common.MethodCall; 28 | import io.flutter.plugin.common.MethodChannel; 29 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 30 | import io.flutter.plugin.common.MethodChannel.Result; 31 | import io.flutter.plugin.common.PluginRegistry.Registrar; 32 | 33 | /** 34 | * FlutterQiyuPlugin 35 | */ 36 | public class FlutterQiyuPlugin implements FlutterPlugin, MethodCallHandler { 37 | private static final String CHANNEL_NAME = "flutter_qiyu"; 38 | 39 | public static void config(Context context, String appKey) { 40 | YSFOptions ysfOptions = new YSFOptions(); 41 | ysfOptions.statusBarNotificationConfig = new StatusBarNotificationConfig(); 42 | ysfOptions.onBotEventListener = new OnBotEventListener() { 43 | @Override 44 | public boolean onUrlClick(Context context, String url) { 45 | Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); 46 | context.startActivity(intent); 47 | return true; 48 | } 49 | }; 50 | // 如果项目中使用了 Glide 可以通过设置 gifImageLoader 去加载 gif 图片 51 | ysfOptions.gifImageLoader = new GlideGifImagerLoader(context); 52 | 53 | Unicorn.config(context.getApplicationContext(), appKey, ysfOptions, new GlideImageLoader(context)); 54 | } 55 | 56 | /// The MethodChannel that will the communication between Flutter and native Android 57 | /// 58 | /// This local reference serves to register the plugin with the Flutter Engine and unregister it 59 | /// when the Flutter Engine is detached from the Activity 60 | private MethodChannel channel; 61 | 62 | private Context context; 63 | private YSFOptions ysfOptions; 64 | private UnreadCountChangeListener unreadCountChangeListener = new UnreadCountChangeListener() { 65 | @Override 66 | public void onUnreadCountChange(int unreadCount) { 67 | if (channel == null) return; 68 | 69 | Map map = new HashMap<>(); 70 | map.put("unreadCount", unreadCount); 71 | 72 | channel.invokeMethod("onUnreadCountChange", map); 73 | } 74 | }; 75 | 76 | @Override 77 | public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { 78 | this.setupChannel(flutterPluginBinding.getBinaryMessenger(), flutterPluginBinding.getApplicationContext()); 79 | } 80 | 81 | @Override 82 | public void onDetachedFromEngine(@NonNull FlutterPlugin.FlutterPluginBinding binding) { 83 | this.teardownChannel(); 84 | } 85 | 86 | @Override 87 | public void onMethodCall(MethodCall call, Result result) { 88 | if (call.method.equals("getPlatformVersion")) { 89 | result.success("Android " + android.os.Build.VERSION.RELEASE); 90 | } else if (call.method.equals("registerApp")) { 91 | String appKey = call.argument("appKey"); 92 | String appName = call.argument("appName"); 93 | 94 | this.registerApp(appKey, appName); 95 | result.success(true); 96 | } else if (call.method.equals("openServiceWindow")) { 97 | this.openServiceWindow(call); 98 | result.success(true); 99 | } else if (call.method.equals("setCustomUIConfig")) { 100 | this.setCustomUIConfig(call); 101 | result.success(true); 102 | } else if (call.method.equals("getUnreadCount")) { 103 | this.getUnreadCount(call, result); 104 | } else if (call.method.equals("setUserInfo")) { 105 | this.setUserInfo(call, result); 106 | } else if (call.method.equals("logout")) { 107 | this.logout(); 108 | } else if (call.method.equals("cleanCache")) { 109 | this.cleanCache(); 110 | } else { 111 | result.notImplemented(); 112 | } 113 | } 114 | 115 | private void registerApp(String appKey, String appName) { 116 | Unicorn.initSdk(); 117 | config(context, appKey); 118 | Unicorn.addUnreadCountChangeListener(unreadCountChangeListener, true); 119 | } 120 | 121 | private void openServiceWindow(MethodCall call) { 122 | Map sourceMap = call.argument("source"); 123 | Map commodityInfoMap = call.argument("commodityInfo"); 124 | 125 | String sourceTitle = (String) sourceMap.get("sourceTitle"); 126 | String sourceUrl = (String) sourceMap.get("sourceUrl"); 127 | String sourceCustomInfo = (String) sourceMap.get("sourceCustomInfo"); 128 | 129 | ProductDetail productDetail = null; 130 | if (commodityInfoMap != null) { 131 | String commodityInfoTitle = (String) commodityInfoMap.get("commodityInfoTitle"); 132 | String commodityInfoDesc = (String) commodityInfoMap.get("commodityInfoDesc"); 133 | String pictureUrl = (String) commodityInfoMap.get("pictureUrl"); 134 | String commodityInfoUrl = (String) commodityInfoMap.get("commodityInfoUrl"); 135 | String note = (String) commodityInfoMap.get("note"); 136 | boolean show = false; 137 | if (commodityInfoMap.containsKey("show")) 138 | show = (boolean) commodityInfoMap.get("show"); 139 | boolean sendByUser = false; 140 | if (commodityInfoMap.containsKey("sendByUser")) 141 | sendByUser = (boolean) commodityInfoMap.get("sendByUser"); 142 | 143 | productDetail = new ProductDetail.Builder() 144 | .setTitle(commodityInfoTitle) 145 | .setDesc(commodityInfoDesc) 146 | .setPicture(pictureUrl) 147 | .setUrl(commodityInfoUrl) 148 | .setNote(note) 149 | .setShow(show ? 1 : 0) 150 | .setSendByUser(sendByUser) 151 | .build(); 152 | } 153 | 154 | String sessionTitle = call.argument("sessionTitle"); 155 | long groupId = (int) call.argument("groupId"); 156 | long staffId = (int) call.argument("staffId"); 157 | long robotId = (int) call.argument("robotId"); 158 | boolean robotFirst = false; 159 | if (call.hasArgument("robotFirst")) 160 | robotFirst = (boolean) call.argument("robotFirst"); 161 | long faqTemplateId = (int) call.argument("faqTemplateId"); 162 | int vipLevel = (int) call.argument("vipLevel"); 163 | boolean showQuitQueue = false; 164 | if (call.hasArgument("showQuitQueue")) 165 | call.argument("showQuitQueue"); 166 | boolean showCloseSessionEntry = false; 167 | if (call.hasArgument("showCloseSessionEntry")) 168 | call.argument("showCloseSessionEntry"); 169 | 170 | // 启动聊天界面 171 | ConsultSource source = new ConsultSource(sourceUrl, sourceTitle, sourceCustomInfo); 172 | source.productDetail = productDetail; 173 | source.groupId = groupId; 174 | source.staffId = staffId; 175 | source.robotId = robotId; 176 | source.robotFirst = robotFirst; 177 | source.faqGroupId = faqTemplateId; 178 | source.vipLevel = vipLevel; 179 | source.sessionLifeCycleOptions = new SessionLifeCycleOptions(); 180 | source.sessionLifeCycleOptions.setCanQuitQueue(showQuitQueue); 181 | source.sessionLifeCycleOptions.setCanCloseSession(showCloseSessionEntry); 182 | Unicorn.openServiceActivity(context, sessionTitle, source); 183 | } 184 | 185 | private void setCustomUIConfig(MethodCall call) { 186 | // 会话窗口上方提示条中的文本字体颜色 187 | String sessionTipTextColor = call.argument("sessionTipTextColor"); 188 | // 会话窗口上方提示条中的文本字体大小 189 | int sessionTipTextFontSize = call.argument("sessionTipTextFontSize"); 190 | // 访客文本消息字体颜色 191 | String customMessageTextColor = call.argument("customMessageTextColor"); 192 | // 客服文本消息字体颜色 193 | String serviceMessageTextColor = call.argument("serviceMessageTextColor"); 194 | // 消息文本消息字体大小 195 | int messageTextFontSize = call.argument("messageTextFontSize"); 196 | // 提示文本消息字体颜色 197 | String tipMessageTextColor = call.argument("tipMessageTextColor"); 198 | // 提示文本消息字体大小 199 | int tipMessageTextFontSize = call.argument("tipMessageTextFontSize"); 200 | // 输入框文本消息字体颜色 201 | String inputTextColor = call.argument("inputTextColor"); 202 | // 输入框文本消息字体大小 203 | int inputTextFontSize = call.argument("inputTextFontSize"); 204 | // 客服聊天窗口背景图片 205 | String sessionBackgroundImage = call.argument("sessionBackgroundImage"); 206 | // 会话窗口上方提示条中的背景颜色 207 | String sessionTipBackgroundColor = call.argument("sessionTipBackgroundColor"); 208 | // 访客头像 209 | String customerHeadImage = call.argument("customerHeadImage"); 210 | // 客服头像 211 | String serviceHeadImage = call.argument("serviceHeadImage"); 212 | // 消息竖直方向间距 213 | float sessionMessageSpacing = (float) call.argument("sessionMessageSpacing"); 214 | // 是否显示头像 215 | boolean showHeadImage = true; 216 | if (call.hasArgument("showHeadImage")) 217 | showHeadImage = call.argument("showHeadImage"); 218 | // 显示发送语音入口,设置为false,可以修改为隐藏 219 | boolean showAudioEntry = true; 220 | if (call.hasArgument("showAudioEntry")) 221 | showAudioEntry = call.argument("showAudioEntry"); 222 | // 显示发送表情入口,设置为false,可以修改为隐藏 223 | boolean showEmoticonEntry = true; 224 | if (call.hasArgument("showEmoticonEntry")) call.argument("showEmoticonEntry"); 225 | // 进入聊天界面,是文本输入模式的话,会弹出键盘,设置为false,可以修改为不弹出 226 | boolean autoShowKeyboard = true; 227 | if (call.hasArgument("autoShowKeyboard ")) call.argument("autoShowKeyboard "); 228 | 229 | UICustomization uiCustomization = ysfOptions.uiCustomization; 230 | if (uiCustomization == null) { 231 | uiCustomization = ysfOptions.uiCustomization = new UICustomization(); 232 | } 233 | uiCustomization.topTipBarTextColor = QiYuUtils.parseColor(sessionTipTextColor); 234 | uiCustomization.topTipBarTextSize = sessionTipTextFontSize; 235 | uiCustomization.textMsgColorRight = QiYuUtils.parseColor(customMessageTextColor); 236 | uiCustomization.textMsgColorLeft = QiYuUtils.parseColor(serviceMessageTextColor); 237 | uiCustomization.textMsgSize = messageTextFontSize; 238 | uiCustomization.tipsTextColor = QiYuUtils.parseColor(tipMessageTextColor); 239 | uiCustomization.tipsTextSize = tipMessageTextFontSize; 240 | uiCustomization.inputTextColor = QiYuUtils.parseColor(inputTextColor); 241 | uiCustomization.inputTextSize = inputTextFontSize; 242 | uiCustomization.msgBackgroundUri = QiYuUtils.getImageUri(this.context, sessionBackgroundImage); 243 | uiCustomization.topTipBarBackgroundColor = QiYuUtils.parseColor(sessionTipBackgroundColor); 244 | uiCustomization.rightAvatar = QiYuUtils.getImageUri(this.context, customerHeadImage); 245 | uiCustomization.leftAvatar = QiYuUtils.getImageUri(this.context, serviceHeadImage); 246 | uiCustomization.msgListViewDividerHeight = (int) sessionMessageSpacing; 247 | uiCustomization.hideLeftAvatar = !showHeadImage; 248 | uiCustomization.hideRightAvatar = !showHeadImage; 249 | uiCustomization.hideAudio = !showAudioEntry; 250 | uiCustomization.hideEmoji = !showEmoticonEntry; 251 | uiCustomization.hideKeyboardOnEnterConsult = !autoShowKeyboard; 252 | } 253 | 254 | private void getUnreadCount(MethodCall call, Result result) { 255 | int count = Unicorn.getUnreadCount(); 256 | result.success(count); 257 | } 258 | 259 | private void setUserInfo(MethodCall call, final Result result) { 260 | String userId = call.argument("userId"); 261 | String data = call.argument("data"); 262 | YSFUserInfo userInfo = new YSFUserInfo(); 263 | userInfo.userId = userId; 264 | userInfo.data = data; 265 | Unicorn.setUserInfo(userInfo, new RequestCallback() { 266 | @Override 267 | public void onSuccess(Void aVoid) { 268 | Log.d("FLUTTER_QIYU", "SUCCESS"); 269 | result.success(true); 270 | } 271 | 272 | @Override 273 | public void onFailed(int i) { 274 | Log.d("FLUTTER_QIYU", "I"); 275 | result.error("failed" + i, "", null); 276 | } 277 | 278 | @Override 279 | public void onException(Throwable throwable) { 280 | result.error("error", throwable.toString(), throwable); 281 | } 282 | }); 283 | } 284 | 285 | private void logout() { 286 | Unicorn.setUserInfo(null); 287 | } 288 | 289 | private void cleanCache() { 290 | Unicorn.clearCache(); 291 | } 292 | 293 | private void setupChannel(BinaryMessenger messenger, Context context) { 294 | this.context = context; 295 | this.channel = new MethodChannel(messenger, CHANNEL_NAME); 296 | this.channel.setMethodCallHandler(this); 297 | } 298 | 299 | private void teardownChannel() { 300 | this.channel.setMethodCallHandler(null); 301 | this.channel = null; 302 | } 303 | } 304 | -------------------------------------------------------------------------------- /android/src/main/java/org/leanflutter/plugins/flutter_qiyu/GlideGifImagerLoader.java: -------------------------------------------------------------------------------- 1 | package org.leanflutter.plugins.flutter_qiyu; 2 | 3 | import android.content.Context; 4 | import android.widget.ImageView; 5 | 6 | import com.bumptech.glide.Glide; 7 | import com.qiyukf.unicorn.api.UnicornGifImageLoader; 8 | 9 | import java.io.Serializable; 10 | 11 | public class GlideGifImagerLoader implements UnicornGifImageLoader, Serializable { 12 | 13 | Context context; 14 | 15 | public GlideGifImagerLoader(Context context) { 16 | this.context = context.getApplicationContext(); 17 | } 18 | 19 | 20 | @Override 21 | public void loadGifImage(String url, ImageView imageView, String imgName) { 22 | if (url == null || imgName == null) { 23 | return; 24 | } 25 | Glide.with(context).load(url).into(imageView); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /android/src/main/java/org/leanflutter/plugins/flutter_qiyu/GlideImageLoader.java: -------------------------------------------------------------------------------- 1 | package org.leanflutter.plugins.flutter_qiyu; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.drawable.Drawable; 6 | 7 | import com.bumptech.glide.Glide; 8 | import com.bumptech.glide.request.target.SimpleTarget; 9 | import com.bumptech.glide.request.transition.Transition; 10 | import com.qiyukf.unicorn.api.ImageLoaderListener; 11 | import com.qiyukf.unicorn.api.UnicornImageLoader; 12 | 13 | public class GlideImageLoader implements UnicornImageLoader { 14 | private Context context; 15 | 16 | public GlideImageLoader(Context context) { 17 | this.context = context.getApplicationContext(); 18 | } 19 | 20 | // @Nullable 21 | @Override 22 | public Bitmap loadImageSync(String uri, int width, int height) { 23 | return null; 24 | } 25 | 26 | @Override 27 | public void loadImage(String uri, int width, int height, final ImageLoaderListener listener) { 28 | if (width <= 0 || height <= 0) { 29 | width = height = Integer.MIN_VALUE; 30 | } 31 | 32 | Glide.with(context).asBitmap().load(uri).into(new SimpleTarget(width, height) { 33 | @Override 34 | public void onResourceReady(Bitmap resource, Transition glideAnimation) { 35 | if (listener != null) { 36 | listener.onLoadComplete(resource); 37 | } 38 | } 39 | 40 | @Override 41 | public void onLoadFailed(Drawable errorDrawable) { 42 | if (listener != null) { 43 | listener.onLoadFailed(null); 44 | } 45 | } 46 | }); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /android/src/main/java/org/leanflutter/plugins/flutter_qiyu/QiYuUtils.java: -------------------------------------------------------------------------------- 1 | package org.leanflutter.plugins.flutter_qiyu; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | import android.graphics.Color; 6 | import android.text.TextUtils; 7 | 8 | public class QiYuUtils { 9 | public static int parseColor(String colorString) { 10 | int color = 0; 11 | try { 12 | color = Color.parseColor(colorString); 13 | } catch (Exception e) { 14 | // e.printStackTrace(); 15 | } 16 | return color; 17 | } 18 | 19 | public static String getImageUri(Context context, String resName) { 20 | if (TextUtils.isEmpty(resName)) { 21 | return null; 22 | } 23 | if (resName.startsWith("./")) { 24 | resName = resName.replace("./", ""); 25 | } 26 | if (resName.contains(".")) { 27 | resName = resName.substring(0, resName.indexOf(".")); 28 | } 29 | resName = resName.replace("/", "_"); 30 | Resources res = context.getResources(); 31 | String pkgName = context.getPackageName(); 32 | int resId = res.getIdentifier(resName, "drawable", pkgName); 33 | if (resId > 0) { 34 | return "res:///" + resId; 35 | } 36 | return null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /example/.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 | # Web related 36 | lib/generated_plugin_registrant.dart 37 | 38 | # Symbolication related 39 | app.*.symbols 40 | 41 | # Obfuscation related 42 | app.*.map.json 43 | 44 | # Android Studio will place build artifacts here 45 | /android/app/debug 46 | /android/app/profile 47 | /android/app/release 48 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # flutter_qiyu_example 2 | 3 | Demonstrates how to use the flutter_qiyu plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://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 | -------------------------------------------------------------------------------- /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 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion flutter.compileSdkVersion 30 | ndkVersion flutter.ndkVersion 31 | 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_8 34 | targetCompatibility JavaVersion.VERSION_1_8 35 | } 36 | 37 | defaultConfig { 38 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 39 | applicationId "org.leanflutter.plugins.flutter_qiyu_example" 40 | // You can update the following values to match your application needs. 41 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. 42 | minSdkVersion flutter.minSdkVersion 43 | targetSdkVersion flutter.targetSdkVersion 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | } 47 | 48 | buildTypes { 49 | release { 50 | // TODO: Add your own signing config for the release build. 51 | // Signing with the debug keys for now, so `flutter run --release` works. 52 | signingConfig signingConfigs.debug 53 | } 54 | } 55 | } 56 | 57 | flutter { 58 | source '../..' 59 | } 60 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 16 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 31 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java: -------------------------------------------------------------------------------- 1 | // Generated file. 2 | // 3 | // If you wish to remove Flutter's multidex support, delete this entire file. 4 | // 5 | // Modifications to this file should be done in a copy under a different name 6 | // as this file may be regenerated. 7 | 8 | package io.flutter.app; 9 | 10 | import android.app.Application; 11 | import android.content.Context; 12 | import androidx.annotation.CallSuper; 13 | import androidx.multidex.MultiDex; 14 | 15 | /** 16 | * Extension of {@link android.app.Application}, adding multidex support. 17 | */ 18 | public class FlutterMultiDexApplication extends Application { 19 | @Override 20 | @CallSuper 21 | protected void attachBaseContext(Context base) { 22 | super.attachBaseContext(base); 23 | MultiDex.install(this); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/org/leanflutter/plugins/flutter_qiyu_example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package org.leanflutter.plugins.flutter_qiyu_example; 2 | 3 | import io.flutter.embedding.android.FlutterActivity; 4 | 5 | public class MainActivity extends FlutterActivity { 6 | } 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.6.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.1.2' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | tasks.register("clean", Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 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-7.4-all.zip 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/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 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 32 | end 33 | 34 | post_install do |installer| 35 | installer.pods_project.targets.each do |target| 36 | flutter_additional_ios_build_settings(target) 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - flutter_qiyu (0.0.1): 4 | - Flutter 5 | - QY_iOS_SDK (~> 9.1.0) 6 | - NIMSDK_LITE (8.9.110) 7 | - QY_iOS_SDK (9.1.1): 8 | - QY_iOS_SDK/Default (= 9.1.1) 9 | - QY_iOS_SDK/Default (9.1.1): 10 | - NIMSDK_LITE (= 8.9.110) 11 | 12 | DEPENDENCIES: 13 | - Flutter (from `Flutter`) 14 | - flutter_qiyu (from `.symlinks/plugins/flutter_qiyu/ios`) 15 | 16 | SPEC REPOS: 17 | trunk: 18 | - NIMSDK_LITE 19 | - QY_iOS_SDK 20 | 21 | EXTERNAL SOURCES: 22 | Flutter: 23 | :path: Flutter 24 | flutter_qiyu: 25 | :path: ".symlinks/plugins/flutter_qiyu/ios" 26 | 27 | SPEC CHECKSUMS: 28 | Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 29 | flutter_qiyu: 9030ebb43718e1991806889cdae5e2dcb881e06d 30 | NIMSDK_LITE: 299ff39677d705b91413d14ad352b32a1b0e72fe 31 | QY_iOS_SDK: 4372950b7622d93ef801e5f392e8691bee87c87f 32 | 33 | PODFILE CHECKSUM: 1a782344d33c12ced0182eeab11e8668d253eb48 34 | 35 | COCOAPODS: 1.15.2 36 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 13 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 17 | 9E45B5B0DC542EF9015B3634 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5927389AE98D2D09DBD5D525 /* libPods-Runner.a */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXCopyFilesBuildPhase section */ 21 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 22 | isa = PBXCopyFilesBuildPhase; 23 | buildActionMask = 2147483647; 24 | dstPath = ""; 25 | dstSubfolderSpec = 10; 26 | files = ( 27 | ); 28 | name = "Embed Frameworks"; 29 | runOnlyForDeploymentPostprocessing = 0; 30 | }; 31 | /* End PBXCopyFilesBuildPhase section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 35 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 36 | 33EB25CDD7ED476AA39719F7 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 37 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 38 | 5927389AE98D2D09DBD5D525 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 40 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 41 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 42 | 8528F6F08F6D2B19C6A51195 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 43 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 44 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 45 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 47 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 48 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 49 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 50 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | F8025D60EA0F485544B563EE /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | 9E45B5B0DC542EF9015B3634 /* libPods-Runner.a in Frameworks */, 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXFrameworksBuildPhase section */ 64 | 65 | /* Begin PBXGroup section */ 66 | 9740EEB11CF90186004384FC /* Flutter */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 70 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 71 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 72 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 73 | ); 74 | name = Flutter; 75 | sourceTree = ""; 76 | }; 77 | 97C146E51CF9000F007C117D = { 78 | isa = PBXGroup; 79 | children = ( 80 | 9740EEB11CF90186004384FC /* Flutter */, 81 | 97C146F01CF9000F007C117D /* Runner */, 82 | 97C146EF1CF9000F007C117D /* Products */, 83 | B3939E8C412EB4E7012B6709 /* Pods */, 84 | F820B925E44072E8F9B488F8 /* Frameworks */, 85 | ); 86 | sourceTree = ""; 87 | }; 88 | 97C146EF1CF9000F007C117D /* Products */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 97C146EE1CF9000F007C117D /* Runner.app */, 92 | ); 93 | name = Products; 94 | sourceTree = ""; 95 | }; 96 | 97C146F01CF9000F007C117D /* Runner */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 100 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 101 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 102 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 103 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 104 | 97C147021CF9000F007C117D /* Info.plist */, 105 | 97C146F11CF9000F007C117D /* Supporting Files */, 106 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 107 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 108 | ); 109 | path = Runner; 110 | sourceTree = ""; 111 | }; 112 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 97C146F21CF9000F007C117D /* main.m */, 116 | ); 117 | name = "Supporting Files"; 118 | sourceTree = ""; 119 | }; 120 | B3939E8C412EB4E7012B6709 /* Pods */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | F8025D60EA0F485544B563EE /* Pods-Runner.debug.xcconfig */, 124 | 33EB25CDD7ED476AA39719F7 /* Pods-Runner.release.xcconfig */, 125 | 8528F6F08F6D2B19C6A51195 /* Pods-Runner.profile.xcconfig */, 126 | ); 127 | path = Pods; 128 | sourceTree = ""; 129 | }; 130 | F820B925E44072E8F9B488F8 /* Frameworks */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 5927389AE98D2D09DBD5D525 /* libPods-Runner.a */, 134 | ); 135 | name = Frameworks; 136 | sourceTree = ""; 137 | }; 138 | /* End PBXGroup section */ 139 | 140 | /* Begin PBXNativeTarget section */ 141 | 97C146ED1CF9000F007C117D /* Runner */ = { 142 | isa = PBXNativeTarget; 143 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 144 | buildPhases = ( 145 | 0CF070501EBC611A063ED420 /* [CP] Check Pods Manifest.lock */, 146 | 9740EEB61CF901F6004384FC /* Run Script */, 147 | 97C146EA1CF9000F007C117D /* Sources */, 148 | 97C146EB1CF9000F007C117D /* Frameworks */, 149 | 97C146EC1CF9000F007C117D /* Resources */, 150 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 151 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 152 | 235F4D89BB6C310E79EEB029 /* [CP] Embed Pods Frameworks */, 153 | 576459301B8856F89E6EAFD9 /* [CP] Copy Pods Resources */, 154 | ); 155 | buildRules = ( 156 | ); 157 | dependencies = ( 158 | ); 159 | name = Runner; 160 | productName = Runner; 161 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 162 | productType = "com.apple.product-type.application"; 163 | }; 164 | /* End PBXNativeTarget section */ 165 | 166 | /* Begin PBXProject section */ 167 | 97C146E61CF9000F007C117D /* Project object */ = { 168 | isa = PBXProject; 169 | attributes = { 170 | LastUpgradeCheck = 1510; 171 | ORGANIZATIONNAME = ""; 172 | TargetAttributes = { 173 | 97C146ED1CF9000F007C117D = { 174 | CreatedOnToolsVersion = 7.3.1; 175 | }; 176 | }; 177 | }; 178 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 179 | compatibilityVersion = "Xcode 9.3"; 180 | developmentRegion = en; 181 | hasScannedForEncodings = 0; 182 | knownRegions = ( 183 | en, 184 | Base, 185 | ); 186 | mainGroup = 97C146E51CF9000F007C117D; 187 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 188 | projectDirPath = ""; 189 | projectRoot = ""; 190 | targets = ( 191 | 97C146ED1CF9000F007C117D /* Runner */, 192 | ); 193 | }; 194 | /* End PBXProject section */ 195 | 196 | /* Begin PBXResourcesBuildPhase section */ 197 | 97C146EC1CF9000F007C117D /* Resources */ = { 198 | isa = PBXResourcesBuildPhase; 199 | buildActionMask = 2147483647; 200 | files = ( 201 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 202 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 203 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 204 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 205 | ); 206 | runOnlyForDeploymentPostprocessing = 0; 207 | }; 208 | /* End PBXResourcesBuildPhase section */ 209 | 210 | /* Begin PBXShellScriptBuildPhase section */ 211 | 0CF070501EBC611A063ED420 /* [CP] Check Pods Manifest.lock */ = { 212 | isa = PBXShellScriptBuildPhase; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | ); 216 | inputFileListPaths = ( 217 | ); 218 | inputPaths = ( 219 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 220 | "${PODS_ROOT}/Manifest.lock", 221 | ); 222 | name = "[CP] Check Pods Manifest.lock"; 223 | outputFileListPaths = ( 224 | ); 225 | outputPaths = ( 226 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 227 | ); 228 | runOnlyForDeploymentPostprocessing = 0; 229 | shellPath = /bin/sh; 230 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 231 | showEnvVarsInLog = 0; 232 | }; 233 | 235F4D89BB6C310E79EEB029 /* [CP] Embed Pods Frameworks */ = { 234 | isa = PBXShellScriptBuildPhase; 235 | buildActionMask = 2147483647; 236 | files = ( 237 | ); 238 | inputFileListPaths = ( 239 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", 240 | ); 241 | name = "[CP] Embed Pods Frameworks"; 242 | outputFileListPaths = ( 243 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 244 | ); 245 | runOnlyForDeploymentPostprocessing = 0; 246 | shellPath = /bin/sh; 247 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 248 | showEnvVarsInLog = 0; 249 | }; 250 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 251 | isa = PBXShellScriptBuildPhase; 252 | alwaysOutOfDate = 1; 253 | buildActionMask = 2147483647; 254 | files = ( 255 | ); 256 | inputPaths = ( 257 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 258 | ); 259 | name = "Thin Binary"; 260 | outputPaths = ( 261 | ); 262 | runOnlyForDeploymentPostprocessing = 0; 263 | shellPath = /bin/sh; 264 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 265 | }; 266 | 576459301B8856F89E6EAFD9 /* [CP] Copy Pods Resources */ = { 267 | isa = PBXShellScriptBuildPhase; 268 | buildActionMask = 2147483647; 269 | files = ( 270 | ); 271 | inputFileListPaths = ( 272 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", 273 | ); 274 | name = "[CP] Copy Pods Resources"; 275 | outputFileListPaths = ( 276 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", 277 | ); 278 | runOnlyForDeploymentPostprocessing = 0; 279 | shellPath = /bin/sh; 280 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; 281 | showEnvVarsInLog = 0; 282 | }; 283 | 9740EEB61CF901F6004384FC /* Run Script */ = { 284 | isa = PBXShellScriptBuildPhase; 285 | alwaysOutOfDate = 1; 286 | buildActionMask = 2147483647; 287 | files = ( 288 | ); 289 | inputPaths = ( 290 | ); 291 | name = "Run Script"; 292 | outputPaths = ( 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | shellPath = /bin/sh; 296 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 297 | }; 298 | /* End PBXShellScriptBuildPhase section */ 299 | 300 | /* Begin PBXSourcesBuildPhase section */ 301 | 97C146EA1CF9000F007C117D /* Sources */ = { 302 | isa = PBXSourcesBuildPhase; 303 | buildActionMask = 2147483647; 304 | files = ( 305 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 306 | 97C146F31CF9000F007C117D /* main.m in Sources */, 307 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 308 | ); 309 | runOnlyForDeploymentPostprocessing = 0; 310 | }; 311 | /* End PBXSourcesBuildPhase section */ 312 | 313 | /* Begin PBXVariantGroup section */ 314 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 315 | isa = PBXVariantGroup; 316 | children = ( 317 | 97C146FB1CF9000F007C117D /* Base */, 318 | ); 319 | name = Main.storyboard; 320 | sourceTree = ""; 321 | }; 322 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 323 | isa = PBXVariantGroup; 324 | children = ( 325 | 97C147001CF9000F007C117D /* Base */, 326 | ); 327 | name = LaunchScreen.storyboard; 328 | sourceTree = ""; 329 | }; 330 | /* End PBXVariantGroup section */ 331 | 332 | /* Begin XCBuildConfiguration section */ 333 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 334 | isa = XCBuildConfiguration; 335 | buildSettings = { 336 | ALWAYS_SEARCH_USER_PATHS = NO; 337 | CLANG_ANALYZER_NONNULL = YES; 338 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 339 | CLANG_CXX_LIBRARY = "libc++"; 340 | CLANG_ENABLE_MODULES = YES; 341 | CLANG_ENABLE_OBJC_ARC = YES; 342 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 343 | CLANG_WARN_BOOL_CONVERSION = YES; 344 | CLANG_WARN_COMMA = YES; 345 | CLANG_WARN_CONSTANT_CONVERSION = YES; 346 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 347 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 348 | CLANG_WARN_EMPTY_BODY = YES; 349 | CLANG_WARN_ENUM_CONVERSION = YES; 350 | CLANG_WARN_INFINITE_RECURSION = YES; 351 | CLANG_WARN_INT_CONVERSION = YES; 352 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 353 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 354 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 355 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 356 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 357 | CLANG_WARN_STRICT_PROTOTYPES = YES; 358 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 359 | CLANG_WARN_UNREACHABLE_CODE = YES; 360 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 361 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 362 | COPY_PHASE_STRIP = NO; 363 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 364 | ENABLE_NS_ASSERTIONS = NO; 365 | ENABLE_STRICT_OBJC_MSGSEND = YES; 366 | GCC_C_LANGUAGE_STANDARD = gnu99; 367 | GCC_NO_COMMON_BLOCKS = YES; 368 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 369 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 370 | GCC_WARN_UNDECLARED_SELECTOR = YES; 371 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 372 | GCC_WARN_UNUSED_FUNCTION = YES; 373 | GCC_WARN_UNUSED_VARIABLE = YES; 374 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 375 | MTL_ENABLE_DEBUG_INFO = NO; 376 | SDKROOT = iphoneos; 377 | SUPPORTED_PLATFORMS = iphoneos; 378 | TARGETED_DEVICE_FAMILY = "1,2"; 379 | VALIDATE_PRODUCT = YES; 380 | }; 381 | name = Profile; 382 | }; 383 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 384 | isa = XCBuildConfiguration; 385 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 386 | buildSettings = { 387 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 388 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 389 | DEVELOPMENT_TEAM = 7TG7UHX4F2; 390 | ENABLE_BITCODE = NO; 391 | INFOPLIST_FILE = Runner/Info.plist; 392 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 393 | LD_RUNPATH_SEARCH_PATHS = ( 394 | "$(inherited)", 395 | "@executable_path/Frameworks", 396 | ); 397 | PRODUCT_BUNDLE_IDENTIFIER = org.leanflutter.plugins.flutterQiyuExample; 398 | PRODUCT_NAME = "$(TARGET_NAME)"; 399 | VERSIONING_SYSTEM = "apple-generic"; 400 | }; 401 | name = Profile; 402 | }; 403 | 97C147031CF9000F007C117D /* Debug */ = { 404 | isa = XCBuildConfiguration; 405 | buildSettings = { 406 | ALWAYS_SEARCH_USER_PATHS = NO; 407 | CLANG_ANALYZER_NONNULL = YES; 408 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 409 | CLANG_CXX_LIBRARY = "libc++"; 410 | CLANG_ENABLE_MODULES = YES; 411 | CLANG_ENABLE_OBJC_ARC = YES; 412 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 413 | CLANG_WARN_BOOL_CONVERSION = YES; 414 | CLANG_WARN_COMMA = YES; 415 | CLANG_WARN_CONSTANT_CONVERSION = YES; 416 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 417 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 418 | CLANG_WARN_EMPTY_BODY = YES; 419 | CLANG_WARN_ENUM_CONVERSION = YES; 420 | CLANG_WARN_INFINITE_RECURSION = YES; 421 | CLANG_WARN_INT_CONVERSION = YES; 422 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 423 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 424 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 425 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 426 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 427 | CLANG_WARN_STRICT_PROTOTYPES = YES; 428 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 429 | CLANG_WARN_UNREACHABLE_CODE = YES; 430 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 431 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 432 | COPY_PHASE_STRIP = NO; 433 | DEBUG_INFORMATION_FORMAT = dwarf; 434 | ENABLE_STRICT_OBJC_MSGSEND = YES; 435 | ENABLE_TESTABILITY = YES; 436 | GCC_C_LANGUAGE_STANDARD = gnu99; 437 | GCC_DYNAMIC_NO_PIC = NO; 438 | GCC_NO_COMMON_BLOCKS = YES; 439 | GCC_OPTIMIZATION_LEVEL = 0; 440 | GCC_PREPROCESSOR_DEFINITIONS = ( 441 | "DEBUG=1", 442 | "$(inherited)", 443 | ); 444 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 445 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 446 | GCC_WARN_UNDECLARED_SELECTOR = YES; 447 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 448 | GCC_WARN_UNUSED_FUNCTION = YES; 449 | GCC_WARN_UNUSED_VARIABLE = YES; 450 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 451 | MTL_ENABLE_DEBUG_INFO = YES; 452 | ONLY_ACTIVE_ARCH = YES; 453 | SDKROOT = iphoneos; 454 | TARGETED_DEVICE_FAMILY = "1,2"; 455 | }; 456 | name = Debug; 457 | }; 458 | 97C147041CF9000F007C117D /* Release */ = { 459 | isa = XCBuildConfiguration; 460 | buildSettings = { 461 | ALWAYS_SEARCH_USER_PATHS = NO; 462 | CLANG_ANALYZER_NONNULL = YES; 463 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 464 | CLANG_CXX_LIBRARY = "libc++"; 465 | CLANG_ENABLE_MODULES = YES; 466 | CLANG_ENABLE_OBJC_ARC = YES; 467 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 468 | CLANG_WARN_BOOL_CONVERSION = YES; 469 | CLANG_WARN_COMMA = YES; 470 | CLANG_WARN_CONSTANT_CONVERSION = YES; 471 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 472 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 473 | CLANG_WARN_EMPTY_BODY = YES; 474 | CLANG_WARN_ENUM_CONVERSION = YES; 475 | CLANG_WARN_INFINITE_RECURSION = YES; 476 | CLANG_WARN_INT_CONVERSION = YES; 477 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 478 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 479 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 480 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 481 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 482 | CLANG_WARN_STRICT_PROTOTYPES = YES; 483 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 484 | CLANG_WARN_UNREACHABLE_CODE = YES; 485 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 486 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 487 | COPY_PHASE_STRIP = NO; 488 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 489 | ENABLE_NS_ASSERTIONS = NO; 490 | ENABLE_STRICT_OBJC_MSGSEND = YES; 491 | GCC_C_LANGUAGE_STANDARD = gnu99; 492 | GCC_NO_COMMON_BLOCKS = YES; 493 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 494 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 495 | GCC_WARN_UNDECLARED_SELECTOR = YES; 496 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 497 | GCC_WARN_UNUSED_FUNCTION = YES; 498 | GCC_WARN_UNUSED_VARIABLE = YES; 499 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 500 | MTL_ENABLE_DEBUG_INFO = NO; 501 | SDKROOT = iphoneos; 502 | SUPPORTED_PLATFORMS = iphoneos; 503 | TARGETED_DEVICE_FAMILY = "1,2"; 504 | VALIDATE_PRODUCT = YES; 505 | }; 506 | name = Release; 507 | }; 508 | 97C147061CF9000F007C117D /* Debug */ = { 509 | isa = XCBuildConfiguration; 510 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 511 | buildSettings = { 512 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 513 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 514 | DEVELOPMENT_TEAM = 7TG7UHX4F2; 515 | ENABLE_BITCODE = NO; 516 | INFOPLIST_FILE = Runner/Info.plist; 517 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 518 | LD_RUNPATH_SEARCH_PATHS = ( 519 | "$(inherited)", 520 | "@executable_path/Frameworks", 521 | ); 522 | PRODUCT_BUNDLE_IDENTIFIER = org.leanflutter.plugins.flutterQiyuExample; 523 | PRODUCT_NAME = "$(TARGET_NAME)"; 524 | VERSIONING_SYSTEM = "apple-generic"; 525 | }; 526 | name = Debug; 527 | }; 528 | 97C147071CF9000F007C117D /* Release */ = { 529 | isa = XCBuildConfiguration; 530 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 531 | buildSettings = { 532 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 533 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 534 | DEVELOPMENT_TEAM = 7TG7UHX4F2; 535 | ENABLE_BITCODE = NO; 536 | INFOPLIST_FILE = Runner/Info.plist; 537 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 538 | LD_RUNPATH_SEARCH_PATHS = ( 539 | "$(inherited)", 540 | "@executable_path/Frameworks", 541 | ); 542 | PRODUCT_BUNDLE_IDENTIFIER = org.leanflutter.plugins.flutterQiyuExample; 543 | PRODUCT_NAME = "$(TARGET_NAME)"; 544 | VERSIONING_SYSTEM = "apple-generic"; 545 | }; 546 | name = Release; 547 | }; 548 | /* End XCBuildConfiguration section */ 549 | 550 | /* Begin XCConfigurationList section */ 551 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 552 | isa = XCConfigurationList; 553 | buildConfigurations = ( 554 | 97C147031CF9000F007C117D /* Debug */, 555 | 97C147041CF9000F007C117D /* Release */, 556 | 249021D3217E4FDB00AE95B9 /* Profile */, 557 | ); 558 | defaultConfigurationIsVisible = 0; 559 | defaultConfigurationName = Release; 560 | }; 561 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 562 | isa = XCConfigurationList; 563 | buildConfigurations = ( 564 | 97C147061CF9000F007C117D /* Debug */, 565 | 97C147071CF9000F007C117D /* Release */, 566 | 249021D4217E4FDB00AE95B9 /* Profile */, 567 | ); 568 | defaultConfigurationIsVisible = 0; 569 | defaultConfigurationName = Release; 570 | }; 571 | /* End XCConfigurationList section */ 572 | }; 573 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 574 | } 575 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /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 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #import "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/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 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Flutter Qiyu 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | flutter_qiyu_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 | UIViewControllerBasedStatusBarAppearance 45 | 46 | CADisableMinimumFrameDurationOnPhone 47 | 48 | NSPhotoLibraryUsageDescription 49 | 需要读取相册权限 50 | NSCameraUsageDescription 51 | 需要相机权限 52 | NSMicrophoneUsageDescription 53 | 需要麦克风权限 54 | NSPhotoLibraryAddUsageDescription 55 | 需要写入相册权限 56 | NSAppTransportSecurity 57 | 58 | NSAllowsArbitraryLoads 59 | 60 | NSAllowsArbitraryLoadsInWebContent 61 | 62 | 63 | UIApplicationSupportsIndirectInputEvents 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /example/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:flutter_qiyu/flutter_qiyu.dart'; 4 | 5 | void main() { 6 | WidgetsFlutterBinding.ensureInitialized(); 7 | 8 | QiYu.registerApp( 9 | appKey: '', 10 | appName: 'qiyu example', 11 | ); 12 | 13 | runApp(const MyApp()); 14 | } 15 | 16 | class MyApp extends StatefulWidget { 17 | const MyApp({Key? key}) : super(key: key); 18 | 19 | @override 20 | State createState() => _MyAppState(); 21 | } 22 | 23 | class _MyAppState extends State { 24 | @override 25 | Widget build(BuildContext context) { 26 | return MaterialApp( 27 | home: Scaffold( 28 | appBar: AppBar( 29 | title: const Text('Plugin example app'), 30 | ), 31 | body: Center( 32 | child: Column( 33 | children: [ 34 | MaterialButton( 35 | child: Text('联系客服'), 36 | onPressed: () { 37 | QYUserInfoParams userInfoParams = QYUserInfoParams.fromJson({ 38 | 'userId': 'uid10101010', 39 | 'data': 40 | '[{\"key\":\"real_name\", \"value\":\"土豪\"},{\"key\":\"mobile_phone\", \"hidden\":true},{\"key\":\"email\", \"value\":\"13800000000@163.com\"},{\"index\":0, \"key\":\"account\", \"label\":\"账号\", \"value\":\"zhangsan\", \"href\":\"http://example.domain/user/zhangsan\"},{\"index\":1, \"key\":\"sex\", \"label\":\"性别\", \"value\":\"先生\"},{\"index\":5, \"key\":\"reg_date\", \"label\":\"注册日期\", \"value\":\"2015-11-16\"},{\"index\":6, \"key\":\"last_login\", \"label\":\"上次登录时间\", \"value\":\"2015-12-22 15:38:54\"}]' 41 | }); 42 | QiYu.setUserInfo(userInfoParams); 43 | 44 | QYServiceWindowParams serviceWindowParams = 45 | QYServiceWindowParams.fromJson({ 46 | 'source': { 47 | 'sourceTitle': '网易七鱼Flutter', 48 | 'sourceUrl': 'http://www.qiyukf.com', 49 | 'sourceCustomInfo': '我是来自自定义的信息' 50 | }, 51 | 'commodityInfo': { 52 | 'commodityInfoTitle': 'Flutter商品', 53 | 'commodityInfoDesc': '这是来自网易七鱼Flutter的商品描述', 54 | 'pictureUrl': 55 | 'http://qiyukf.com/res/img/companyLogo/blmn.png', 56 | 'commodityInfoUrl': 'http://www.qiyukf.com', 57 | 'note': '¥1000', 58 | 'show': true 59 | }, 60 | 'sessionTitle': '网易七鱼123', 61 | 'groupId': 0, 62 | 'staffId': 0, 63 | 'robotId': 0, 64 | 'robotFirst': false, 65 | 'faqTemplateId': 0, 66 | 'vipLevel': 0, 67 | 'showQuitQueue': true, 68 | 'showCloseSessionEntry': true 69 | }); 70 | QiYu.openServiceWindow(serviceWindowParams); 71 | }, 72 | ) 73 | ], 74 | ), 75 | ), 76 | ), 77 | ); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "1.3.0" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "1.1.1" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "1.18.0" 44 | cupertino_icons: 45 | dependency: "direct main" 46 | description: 47 | name: cupertino_icons 48 | sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "1.0.6" 52 | fake_async: 53 | dependency: transitive 54 | description: 55 | name: fake_async 56 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "1.3.1" 60 | flutter: 61 | dependency: "direct main" 62 | description: flutter 63 | source: sdk 64 | version: "0.0.0" 65 | flutter_lints: 66 | dependency: "direct dev" 67 | description: 68 | name: flutter_lints 69 | sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 70 | url: "https://pub.dev" 71 | source: hosted 72 | version: "2.0.3" 73 | flutter_qiyu: 74 | dependency: "direct main" 75 | description: 76 | path: ".." 77 | relative: true 78 | source: path 79 | version: "0.1.2" 80 | flutter_test: 81 | dependency: "direct dev" 82 | description: flutter 83 | source: sdk 84 | version: "0.0.0" 85 | leak_tracker: 86 | dependency: transitive 87 | description: 88 | name: leak_tracker 89 | sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" 90 | url: "https://pub.dev" 91 | source: hosted 92 | version: "10.0.0" 93 | leak_tracker_flutter_testing: 94 | dependency: transitive 95 | description: 96 | name: leak_tracker_flutter_testing 97 | sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 98 | url: "https://pub.dev" 99 | source: hosted 100 | version: "2.0.1" 101 | leak_tracker_testing: 102 | dependency: transitive 103 | description: 104 | name: leak_tracker_testing 105 | sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 106 | url: "https://pub.dev" 107 | source: hosted 108 | version: "2.0.1" 109 | lints: 110 | dependency: transitive 111 | description: 112 | name: lints 113 | sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" 114 | url: "https://pub.dev" 115 | source: hosted 116 | version: "2.1.1" 117 | matcher: 118 | dependency: transitive 119 | description: 120 | name: matcher 121 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb 122 | url: "https://pub.dev" 123 | source: hosted 124 | version: "0.12.16+1" 125 | material_color_utilities: 126 | dependency: transitive 127 | description: 128 | name: material_color_utilities 129 | sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" 130 | url: "https://pub.dev" 131 | source: hosted 132 | version: "0.8.0" 133 | meta: 134 | dependency: transitive 135 | description: 136 | name: meta 137 | sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 138 | url: "https://pub.dev" 139 | source: hosted 140 | version: "1.11.0" 141 | path: 142 | dependency: transitive 143 | description: 144 | name: path 145 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 146 | url: "https://pub.dev" 147 | source: hosted 148 | version: "1.9.0" 149 | sky_engine: 150 | dependency: transitive 151 | description: flutter 152 | source: sdk 153 | version: "0.0.99" 154 | source_span: 155 | dependency: transitive 156 | description: 157 | name: source_span 158 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 159 | url: "https://pub.dev" 160 | source: hosted 161 | version: "1.10.0" 162 | stack_trace: 163 | dependency: transitive 164 | description: 165 | name: stack_trace 166 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 167 | url: "https://pub.dev" 168 | source: hosted 169 | version: "1.11.1" 170 | stream_channel: 171 | dependency: transitive 172 | description: 173 | name: stream_channel 174 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 175 | url: "https://pub.dev" 176 | source: hosted 177 | version: "2.1.2" 178 | string_scanner: 179 | dependency: transitive 180 | description: 181 | name: string_scanner 182 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 183 | url: "https://pub.dev" 184 | source: hosted 185 | version: "1.2.0" 186 | term_glyph: 187 | dependency: transitive 188 | description: 189 | name: term_glyph 190 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 191 | url: "https://pub.dev" 192 | source: hosted 193 | version: "1.2.1" 194 | test_api: 195 | dependency: transitive 196 | description: 197 | name: test_api 198 | sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" 199 | url: "https://pub.dev" 200 | source: hosted 201 | version: "0.6.1" 202 | vector_math: 203 | dependency: transitive 204 | description: 205 | name: vector_math 206 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 207 | url: "https://pub.dev" 208 | source: hosted 209 | version: "2.1.4" 210 | vm_service: 211 | dependency: transitive 212 | description: 213 | name: vm_service 214 | sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 215 | url: "https://pub.dev" 216 | source: hosted 217 | version: "13.0.0" 218 | sdks: 219 | dart: ">=3.2.0-0 <4.0.0" 220 | flutter: ">=2.5.0" 221 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_qiyu_example 2 | description: Demonstrates how to use the flutter_qiyu plugin. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `flutter pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | environment: 9 | sdk: ">=2.17.0 <3.0.0" 10 | 11 | # Dependencies specify other packages that your package needs in order to work. 12 | # To automatically upgrade your package dependencies to the latest versions 13 | # consider running `flutter pub upgrade --major-versions`. Alternatively, 14 | # dependencies can be manually updated by changing the version numbers below to 15 | # the latest version available on pub.dev. To see which dependencies have newer 16 | # versions available, run `flutter pub outdated`. 17 | dependencies: 18 | flutter: 19 | sdk: flutter 20 | 21 | flutter_qiyu: 22 | # When depending on this package from a real application you should use: 23 | # flutter_qiyu: ^x.y.z 24 | # See https://dart.dev/tools/pub/dependencies#version-constraints 25 | # The example app is bundled with the plugin so we use a path dependency on 26 | # the parent directory to use the current plugin's version. 27 | path: ../ 28 | 29 | # The following adds the Cupertino Icons font to your application. 30 | # Use with the CupertinoIcons class for iOS style icons. 31 | cupertino_icons: ^1.0.2 32 | 33 | dev_dependencies: 34 | flutter_test: 35 | sdk: flutter 36 | 37 | # The "flutter_lints" package below contains a set of recommended lints to 38 | # encourage good coding practices. The lint set provided by the package is 39 | # activated in the `analysis_options.yaml` file located at the root of your 40 | # package. See that file for information about deactivating specific lint 41 | # rules and activating additional ones. 42 | flutter_lints: ^2.0.0 43 | 44 | # For information on the generic Dart part of this file, see the 45 | # following page: https://dart.dev/tools/pub/pubspec 46 | 47 | # The following section is specific to Flutter packages. 48 | flutter: 49 | 50 | # The following line ensures that the Material Icons font is 51 | # included with your application, so that you can use the icons in 52 | # the material Icons class. 53 | uses-material-design: true 54 | 55 | # To add assets to your application, add an assets section, like this: 56 | # assets: 57 | # - images/a_dot_burr.jpeg 58 | # - images/a_dot_ham.jpeg 59 | 60 | # An image asset can refer to one or more resolution-specific "variants", see 61 | # https://flutter.dev/assets-and-images/#resolution-aware 62 | 63 | # For details regarding adding assets from package dependencies, see 64 | # https://flutter.dev/assets-and-images/#from-packages 65 | 66 | # To add custom fonts to your application, add a fonts section here, 67 | # in this "flutter" section. Each entry in this list should have a 68 | # "family" key with the font family name, and a "fonts" key with a 69 | # list giving the asset and other descriptors for the font. For 70 | # example: 71 | # fonts: 72 | # - family: Schyler 73 | # fonts: 74 | # - asset: fonts/Schyler-Regular.ttf 75 | # - asset: fonts/Schyler-Italic.ttf 76 | # style: italic 77 | # - family: Trajan Pro 78 | # fonts: 79 | # - asset: fonts/TrajanPro.ttf 80 | # - asset: fonts/TrajanPro_Bold.ttf 81 | # weight: 700 82 | # 83 | # For details regarding fonts from package dependencies, 84 | # see https://flutter.dev/custom-fonts/#from-packages 85 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility in the flutter_test package. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:flutter_qiyu_example/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Verify Platform version', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(const MyApp()); 17 | 18 | // Verify that platform version is retrieved. 19 | expect( 20 | find.byWidgetPredicate( 21 | (Widget widget) => widget is Text && 22 | widget.data!.startsWith('Running on:'), 23 | ), 24 | findsOneWidget, 25 | ); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijy91-archives-repos/flutter_qiyu/cf3323951c22f8a1c0c90971f5fcac3416620fcf/ios/Assets/.gitkeep -------------------------------------------------------------------------------- /ios/Classes/FlutterQiyuPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface FlutterQiyuPlugin : NSObject 4 | @property (nonatomic, retain) FlutterMethodChannel *channel; 5 | @property (nonatomic, retain) UIViewController *viewController; 6 | 7 | + (void)registerWithRegistrar:(NSObject*)registrar; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /ios/Classes/FlutterQiyuPlugin.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import "FlutterQiyuPlugin.h" 5 | #import "UIBarButtonItem+blocks.h" 6 | 7 | @interface FlutterQiyuPlugin () 8 | @end 9 | 10 | @implementation FlutterQiyuPlugin 11 | + (void)registerWithRegistrar:(NSObject*)registrar { 12 | // 高版本ios需要配置以下两行才能发送图片 13 | [NIMSDK sharedSDK].serverSetting.nosUploadAddress = @"https://nosup-hz1.127.net"; 14 | [NIMSDK sharedSDK].serverSetting.nosUploadHost = @"nosup-hz1.127.net"; 15 | FlutterMethodChannel* channel = [FlutterMethodChannel 16 | methodChannelWithName:@"flutter_qiyu" 17 | binaryMessenger:[registrar messenger]]; 18 | UIViewController *viewController = [UIApplication sharedApplication].delegate.window.rootViewController; 19 | FlutterQiyuPlugin* instance = [[FlutterQiyuPlugin alloc] initWithViewController:viewController]; 20 | [registrar addMethodCallDelegate:instance channel:channel]; 21 | [registrar addApplicationDelegate:instance]; 22 | 23 | instance.channel = channel; 24 | 25 | [[[QYSDK sharedSDK] conversationManager] setDelegate:instance]; 26 | [[QYSDK sharedSDK] registerPushMessageNotification:^(QYPushMessage *message) { 27 | // TODO: 28 | }]; 29 | } 30 | 31 | - (instancetype)initWithViewController:(UIViewController *)viewController { 32 | self = [super init]; 33 | if (self) { 34 | self.viewController = viewController; 35 | } 36 | return self; 37 | } 38 | 39 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { 40 | NSDictionary *options = call.arguments; 41 | if ([@"getPlatformVersion" isEqualToString:call.method]) { 42 | result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); 43 | } else if ([@"registerApp" isEqualToString:call.method]) { 44 | NSString *appKey = call.arguments[@"appKey"]; 45 | NSString *appName = call.arguments[@"appName"]; 46 | [self registerApp:appKey appName:appName]; 47 | result([NSNumber numberWithBool:YES]); 48 | } else if ([@"openServiceWindow" isEqualToString:call.method]) { 49 | [self openServiceWindow:options]; 50 | result([NSNumber numberWithBool:YES]); 51 | } else if ([@"setCustomUIConfig" isEqualToString:call.method]) { 52 | [self setCustomUIConfig:options]; 53 | result([NSNumber numberWithBool:YES]); 54 | } else if ([@"getUnreadCount" isEqualToString:call.method]) { 55 | NSInteger* unreadCount = [self getUnreadCount]; 56 | result([NSNumber numberWithInteger:unreadCount]); 57 | } else if ([@"setUserInfo" isEqualToString:call.method]) { 58 | [self setUserInfo:options]; 59 | result([NSNumber numberWithBool:YES]); 60 | } else if ([@"logout" isEqualToString:call.method]) { 61 | [self logout]; 62 | result([NSNumber numberWithBool:YES]); 63 | } else if ([@"cleanCache" isEqualToString:call.method]) { 64 | [self cleanCache]; 65 | result([NSNumber numberWithBool:YES]); 66 | } else { 67 | result(FlutterMethodNotImplemented); 68 | } 69 | } 70 | 71 | - (void)registerApp:(NSString*) appKey 72 | appName:(NSString*) appName 73 | { 74 | [[QYSDK sharedSDK] registerAppId:appKey appName:appName]; 75 | } 76 | 77 | - (void)openServiceWindow:(NSDictionary *)options 78 | { 79 | NSDictionary *paramDict = options; 80 | QYSessionViewController *sessionVC = [[QYSDK sharedSDK] sessionViewController]; 81 | 82 | QYSource *source = nil; 83 | if ([paramDict objectForKey:@"source"]) { 84 | NSDictionary *sourceDict = [paramDict objectForKey:@"source"]; 85 | if ([sourceDict objectForKey:@"sourceTitle"] || [sourceDict objectForKey:@"sourceUrl"] 86 | || [sourceDict objectForKey:@"sourceCustomInfo"]) { 87 | source = [[QYSource alloc] init]; 88 | if ([sourceDict objectForKey:@"sourceTitle"]) { 89 | source.title = [sourceDict objectForKey:@"sourceTitle"]; 90 | } 91 | if ([sourceDict objectForKey:@"sourceUrl"]) { 92 | source.urlString = [sourceDict objectForKey:@"sourceUrl"]; 93 | } 94 | if ([sourceDict objectForKey:@"sourceCustomInfo"]) { 95 | source.customInfo = [sourceDict objectForKey:@"sourceCustomInfo"]; 96 | } 97 | } 98 | } 99 | QYCommodityInfo *commodityInfo = nil; 100 | if ([paramDict objectForKey:@"commodityInfo"]) { 101 | NSDictionary *commodityInfoDict = [paramDict objectForKey:@"commodityInfo"]; 102 | if ([commodityInfoDict objectForKey:@"commodityInfoTitle"] || [commodityInfoDict objectForKey:@"commodityInfoDesc"] 103 | || [commodityInfoDict objectForKey:@"pictureUrl"] || [commodityInfoDict objectForKey:@"commodityInfoUrl"] 104 | || [commodityInfoDict objectForKey:@"note"] || [commodityInfoDict objectForKey:@"show"] 105 | || [commodityInfoDict objectForKey:@"sendByUser"]) { 106 | commodityInfo = [[QYCommodityInfo alloc] init]; 107 | if ([commodityInfoDict objectForKey:@"commodityInfoTitle"]) { 108 | commodityInfo.title = [commodityInfoDict objectForKey:@"commodityInfoTitle"]; 109 | } 110 | if ([commodityInfoDict objectForKey:@"commodityInfoDesc"]) { 111 | commodityInfo.desc = [commodityInfoDict objectForKey:@"commodityInfoDesc"]; 112 | } 113 | if ([commodityInfoDict objectForKey:@"pictureUrl"]) { 114 | commodityInfo.pictureUrlString = [commodityInfoDict objectForKey:@"pictureUrl"]; 115 | } 116 | if ([commodityInfoDict objectForKey:@"commodityInfoUrl"]) { 117 | commodityInfo.urlString = [commodityInfoDict objectForKey:@"commodityInfoUrl"]; 118 | } 119 | if ([commodityInfoDict objectForKey:@"note"]) { 120 | commodityInfo.note = [commodityInfoDict objectForKey:@"note"]; 121 | } 122 | if ([commodityInfoDict objectForKey:@"show"]) { 123 | commodityInfo.show = [[commodityInfoDict objectForKey:@"show"] boolValue]; 124 | } 125 | if ([commodityInfoDict objectForKey:@"sendByUser"]) { 126 | commodityInfo.sendByUser = [[commodityInfoDict objectForKey:@"sendByUser"] boolValue]; 127 | } 128 | } 129 | } 130 | if (source) { 131 | sessionVC.source = source; 132 | } 133 | if (commodityInfo) { 134 | sessionVC.commodityInfo = commodityInfo; 135 | } 136 | if ([paramDict objectForKey:@"sessionTitle"]) { 137 | sessionVC.sessionTitle = [paramDict objectForKey:@"sessionTitle"]; 138 | } 139 | if ([paramDict objectForKey:@"groupId"]) { 140 | sessionVC.groupId = [[paramDict objectForKey:@"groupId"] intValue]; 141 | } 142 | if ([paramDict objectForKey:@"staffId"]) { 143 | sessionVC.staffId = [[paramDict objectForKey:@"staffId"] intValue]; 144 | } 145 | if ([paramDict objectForKey:@"robotId"]) { 146 | sessionVC.robotId = [[paramDict objectForKey:@"robotId"] intValue]; 147 | } 148 | if ([paramDict objectForKey:@"vipLevel"]) { 149 | sessionVC.vipLevel = [[paramDict objectForKey:@"vipLevel"] intValue]; 150 | } 151 | if ([paramDict objectForKey:@"robotFirst"]) { 152 | sessionVC.openRobotInShuntMode = [paramDict objectForKey:@"robotFirst"]; 153 | } 154 | if ([paramDict objectForKey:@"faqTemplateId"]) { 155 | sessionVC.commonQuestionTemplateId = [[paramDict objectForKey:@"faqTemplateId"] intValue]; 156 | } 157 | 158 | [sessionVC.navigationItem setLeftBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain actionHandler:^{ 159 | [self.viewController dismissViewControllerAnimated:true completion:nil]; 160 | }]]; 161 | 162 | UINavigationController *rootNavigationController = [[UINavigationController alloc] initWithRootViewController:sessionVC]; 163 | [rootNavigationController setNavigationBarHidden:YES]; 164 | rootNavigationController.modalPresentationStyle = UIModalPresentationFullScreen; 165 | 166 | [self.viewController presentViewController:rootNavigationController animated:YES completion:nil]; 167 | } 168 | 169 | - (void)setCustomUIConfig:(NSDictionary *)options 170 | { 171 | NSDictionary *paramDict = options; 172 | if ([paramDict objectForKey:@"sessionTipTextColor"]) { 173 | [[QYSDK sharedSDK] customUIConfig].sessionTipTextColor = [self colorFromHexString:[paramDict objectForKey:@"sessionTipTextColor"]]; 174 | } 175 | if ([paramDict objectForKey:@"sessionTipTextFontSize"]) { 176 | [[QYSDK sharedSDK] customUIConfig].sessionTipTextFontSize = [[paramDict objectForKey:@"sessionTipTextFontSize"] floatValue]; 177 | } 178 | if ([paramDict objectForKey:@"customMessageTextColor"]) { 179 | [[QYSDK sharedSDK] customUIConfig].customMessageTextColor = [self colorFromHexString:[paramDict objectForKey:@"customMessageTextColor"]]; 180 | } 181 | if ([paramDict objectForKey:@"messageTextFontSize"]) { 182 | [[QYSDK sharedSDK] customUIConfig].customMessageTextFontSize = [[paramDict objectForKey:@"messageTextFontSize"] floatValue]; 183 | } 184 | if ([paramDict objectForKey:@"serviceMessageTextColor"]) { 185 | [[QYSDK sharedSDK] customUIConfig].serviceMessageTextColor = [self colorFromHexString:[paramDict objectForKey:@"serviceMessageTextColor"]]; 186 | } 187 | if ([paramDict objectForKey:@"messageTextFontSize"]) { 188 | [[QYSDK sharedSDK] customUIConfig].serviceMessageTextFontSize = [[paramDict objectForKey:@"messageTextFontSize"] floatValue]; 189 | } 190 | if ([paramDict objectForKey:@"tipMessageTextColor"]) { 191 | [[QYSDK sharedSDK] customUIConfig].tipMessageTextColor = [self colorFromHexString:[paramDict objectForKey:@"tipMessageTextColor"]]; 192 | } 193 | if ([paramDict objectForKey:@"tipMessageTextFontSize"]) { 194 | [[QYSDK sharedSDK] customUIConfig].tipMessageTextFontSize = [[paramDict objectForKey:@"tipMessageTextFontSize"] floatValue]; 195 | } 196 | if ([paramDict objectForKey:@"inputTextColor"]) { 197 | [[QYSDK sharedSDK] customUIConfig].inputTextColor = [self colorFromHexString:[paramDict objectForKey:@"inputTextColor"]]; 198 | } 199 | if ([paramDict objectForKey:@"inputTextFontSize"]) { 200 | [[QYSDK sharedSDK] customUIConfig].inputTextFontSize = [[paramDict objectForKey:@"inputTextFontSize"] floatValue]; 201 | } 202 | NSString *imageName = nil; 203 | if ([paramDict objectForKey:@"sessionBackgroundImage"]) { 204 | imageName = [paramDict objectForKey:@"sessionBackgroundImage"]; 205 | dispatch_async(dispatch_get_main_queue(), ^{ 206 | [[QYSDK sharedSDK] customUIConfig].sessionBackground = [[UIImageView alloc] initWithImage:[self getResourceImage:imageName]]; 207 | }); 208 | } 209 | if ([paramDict objectForKey:@"sessionTipBackgroundColor"]) { 210 | [[QYSDK sharedSDK] customUIConfig].sessionTipBackgroundColor = [self colorFromHexString:[paramDict objectForKey:@"sessionTipBackgroundColor"]]; 211 | } 212 | if ([paramDict objectForKey:@"customerHeadImage"]) { 213 | imageName = [paramDict objectForKey:@"customerHeadImage"]; 214 | [[QYSDK sharedSDK] customUIConfig].customerHeadImage = [self getResourceImage:imageName]; 215 | } 216 | if ([paramDict objectForKey:@"serviceHeadImage"]) { 217 | imageName = [paramDict objectForKey:@"serviceHeadImage"]; 218 | [[QYSDK sharedSDK] customUIConfig].serviceHeadImage = [self getResourceImage:imageName]; 219 | } 220 | if ([paramDict objectForKey:@"customerMessageBubbleNormalImage"]) { 221 | imageName = [paramDict objectForKey:@"customerMessageBubbleNormalImage"]; 222 | [[QYSDK sharedSDK] customUIConfig].customerMessageBubbleNormalImage = [self getResourceImage:imageName]; 223 | } 224 | if ([paramDict objectForKey:@"serviceMessageBubbleNormalImage"]) { 225 | imageName = [paramDict objectForKey:@"serviceMessageBubbleNormalImage"]; 226 | [[QYSDK sharedSDK] customUIConfig].serviceMessageBubbleNormalImage = [self getResourceImage:imageName]; 227 | } 228 | if ([paramDict objectForKey:@"customerMessageBubblePressedImage"]) { 229 | imageName = [paramDict objectForKey:@"customerMessageBubblePressedImage"]; 230 | [[QYSDK sharedSDK] customUIConfig].customerMessageBubblePressedImage = [self getResourceImage:imageName]; 231 | } 232 | if ([paramDict objectForKey:@"serviceMessageBubblePressedImage"]) { 233 | imageName = [paramDict objectForKey:@"serviceMessageBubblePressedImage"]; 234 | [[QYSDK sharedSDK] customUIConfig].serviceMessageBubblePressedImage = [self getResourceImage:imageName]; 235 | } 236 | if ([paramDict objectForKey:@"sessionMessageSpacing"]) { 237 | [[QYSDK sharedSDK] customUIConfig].sessionMessageSpacing = [[paramDict objectForKey:@"sessionMessageSpacing"] floatValue]; 238 | } 239 | if ([paramDict objectForKey:@"showHeadImage"]) { 240 | [[QYSDK sharedSDK] customUIConfig].showHeadImage = [paramDict objectForKey:@"showHeadImage"]; 241 | } 242 | // if ([paramDict objectForKey:@"naviBarColor"]) { 243 | // self.naviBarColor = [self colorFromString:[paramDict objectForKey:@"naviBarColor"]]; 244 | // } 245 | // if ([paramDict objectForKey:@"naviBarStyleDark"]) { 246 | // [[QYSDK sharedSDK] customUIConfig].rightBarButtonItemColorBlackOrWhite = [[paramDict objectForKey:@"naviBarStyleDark"] boolValue]; 247 | // } 248 | if ([paramDict objectForKey:@"showAudioEntry"]) { 249 | [[QYSDK sharedSDK] customUIConfig].showAudioEntry = [[paramDict objectForKey:@"showAudioEntry"] boolValue]; 250 | } 251 | if ([paramDict objectForKey:@"showEmoticonEntry"]) { 252 | [[QYSDK sharedSDK] customUIConfig].showEmoticonEntry = [[paramDict objectForKey:@"showEmoticonEntry"] boolValue]; 253 | } 254 | if ([paramDict objectForKey:@"autoShowKeyboard"]) { 255 | [[QYSDK sharedSDK] customUIConfig].autoShowKeyboard = [[paramDict objectForKey:@"autoShowKeyboard"] boolValue]; 256 | } 257 | if ([paramDict objectForKey:@"bottomMargin"]) { 258 | [[QYSDK sharedSDK] customUIConfig].bottomMargin = [[paramDict objectForKey:@"bottomMargin"] floatValue]; 259 | } 260 | // if ([paramDict objectForKey:@"showCloseSessionEntry"]) { 261 | // [[QYSDK sharedSDK] customUIConfig].showCloseSessionEntry = [RCTConvert BOOL:[paramDict objectForKey:@"showCloseSessionEntry"]]; 262 | // } 263 | } 264 | 265 | - (NSInteger *)getUnreadCount 266 | { 267 | NSInteger count = [[[QYSDK sharedSDK] conversationManager] allUnreadCount]; 268 | return count; 269 | } 270 | 271 | - (void)setUserInfo:(NSDictionary *)options 272 | { 273 | NSDictionary *paramDict = options; 274 | 275 | QYUserInfo *userInfo = nil; 276 | if ([paramDict objectForKey:@"userId"] || [paramDict objectForKey:@"data"]) { 277 | userInfo = [[QYUserInfo alloc] init]; 278 | if ([paramDict objectForKey:@"userId"]) { 279 | userInfo.userId = [paramDict objectForKey:@"userId"]; 280 | } 281 | if ([paramDict objectForKey:@"data"]) { 282 | userInfo.data = [paramDict objectForKey:@"data"]; 283 | } 284 | } 285 | if (userInfo) { 286 | [[QYSDK sharedSDK] setUserInfo:userInfo]; 287 | } 288 | } 289 | 290 | - (void)logout 291 | { 292 | [[QYSDK sharedSDK] logout:nil]; 293 | } 294 | 295 | - (void)cleanCache 296 | { 297 | [[QYSDK sharedSDK] cleanResourceCacheWithBlock:nil]; 298 | } 299 | 300 | - (UIColor *)colorFromHexString:(NSString*)hexString 301 | { 302 | NSString *cleanString = [hexString stringByReplacingOccurrencesOfString:@"#" withString:@""]; 303 | if([cleanString length] == 3) { 304 | cleanString = [NSString stringWithFormat:@"%@%@%@%@%@%@", 305 | [cleanString substringWithRange:NSMakeRange(0, 1)],[cleanString substringWithRange:NSMakeRange(0, 1)], 306 | [cleanString substringWithRange:NSMakeRange(1, 1)],[cleanString substringWithRange:NSMakeRange(1, 1)], 307 | [cleanString substringWithRange:NSMakeRange(2, 1)],[cleanString substringWithRange:NSMakeRange(2, 1)]]; 308 | } 309 | if([cleanString length] == 6) { 310 | cleanString = [cleanString stringByAppendingString:@"ff"]; 311 | } 312 | 313 | unsigned int baseValue; 314 | [[NSScanner scannerWithString:cleanString] scanHexInt:&baseValue]; 315 | 316 | float red = ((baseValue >> 24) & 0xFF)/255.0f; 317 | float green = ((baseValue >> 16) & 0xFF)/255.0f; 318 | float blue = ((baseValue >> 8) & 0xFF)/255.0f; 319 | float alpha = ((baseValue >> 0) & 0xFF)/255.0f; 320 | 321 | return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; 322 | } 323 | 324 | - (UIImage*)getResourceImage:(NSString*)imageFilePath 325 | { 326 | NSString *localImagePath = [imageFilePath substringFromIndex:1]; 327 | NSString *bundlePath = [NSBundle mainBundle].bundlePath; 328 | bundlePath = [[bundlePath stringByAppendingPathComponent:@"assets"] stringByAppendingPathComponent:localImagePath]; 329 | 330 | UIImage *image = [[UIImage imageWithContentsOfFile:bundlePath] resizableImageWithCapInsets:UIEdgeInsetsMake(15,15,30,30) resizingMode:UIImageResizingModeStretch]; 331 | if (image) { 332 | return image; 333 | } 334 | 335 | return nil; 336 | } 337 | 338 | - (void)onUnreadCountChanged:(NSInteger)count 339 | { 340 | [_channel invokeMethod:@"onUnreadCountChange" arguments: @{@"unreadCount": [NSNumber numberWithInteger:count]}]; 341 | } 342 | 343 | - (void)application:(UIApplication *)app 344 | didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 345 | { 346 | [[QYSDK sharedSDK] updateApnsToken:deviceToken]; 347 | } 348 | 349 | @end 350 | -------------------------------------------------------------------------------- /ios/Classes/UIBarButtonItem+blocks.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIBarButtonItem+blocks.h 3 | // 4 | // Created by Julian Weinert on 04.08.14. 5 | // Copyright (c) 2014 Julian Weinert Softwareentwicklung. All rights reserved. 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 2 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | 20 | #import 21 | 22 | typedef void (^UIBarButtonItemActionHandler)(); 23 | 24 | @interface UIBarButtonItem (blocks) 25 | 26 | - (id)initWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style actionHandler:(UIBarButtonItemActionHandler)actionHandler; 27 | - (id)initWithImage:(UIImage *)image landscapeImagePhone:(UIImage *)landscapeImagePhone style:(UIBarButtonItemStyle)style actionHandler:(UIBarButtonItemActionHandler)actionHandler NS_AVAILABLE_IOS(5_0); 28 | - (id)initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style actionHandler:(UIBarButtonItemActionHandler)actionHandler; 29 | - (id)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem actionHandler:(UIBarButtonItemActionHandler)actionHandler; 30 | 31 | - (void)setActionHandler:(UIBarButtonItemActionHandler)actionHandler; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /ios/Classes/UIBarButtonItem+blocks.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIBarButtonItem+blocks.m 3 | // 4 | // Created by Julian Weinert on 04.08.14. 5 | // Copyright (c) 2014 Julian Weinert Softwareentwicklung. All rights reserved. 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 2 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | 20 | #import "UIBarButtonItem+blocks.h" 21 | #import 22 | 23 | @implementation UIBarButtonItem (blocks) 24 | 25 | - (id)initWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style actionHandler:(UIBarButtonItemActionHandler)actionHandler { 26 | if (self = [self initWithImage:image style:style target:self action:@selector(performActionHandler)]) { 27 | [self setActionHandler:actionHandler]; 28 | } 29 | return self; 30 | } 31 | 32 | - (id)initWithImage:(UIImage *)image landscapeImagePhone:(UIImage *)landscapeImagePhone style:(UIBarButtonItemStyle)style actionHandler:(UIBarButtonItemActionHandler)actionHandler { 33 | if (self = [self initWithImage:image landscapeImagePhone:landscapeImagePhone style:style target:self action:@selector(performActionHandler)]) { 34 | [self setActionHandler:actionHandler]; 35 | } 36 | return self; 37 | } 38 | 39 | - (id)initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style actionHandler:(UIBarButtonItemActionHandler)actionHandler { 40 | if (self = [self initWithTitle:title style:style target:self action:@selector(performActionHandler)]) { 41 | [self setActionHandler:actionHandler]; 42 | } 43 | return self; 44 | } 45 | 46 | - (id)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem actionHandler:(UIBarButtonItemActionHandler)actionHandler { 47 | if (self = [self initWithBarButtonSystemItem:systemItem target:self action:@selector(performActionHandler)]) { 48 | [self setActionHandler:actionHandler]; 49 | } 50 | return self; 51 | } 52 | 53 | - (void)setActionHandler:(UIBarButtonItemActionHandler)actionHandler { 54 | objc_setAssociatedObject(self, "actionHandler", actionHandler, OBJC_ASSOCIATION_COPY_NONATOMIC); 55 | } 56 | 57 | - (void)performActionHandler { 58 | UIBarButtonItemActionHandler actionHandler = objc_getAssociatedObject(self, "actionHandler"); 59 | actionHandler(); 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /ios/flutter_qiyu.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint flutter_qiyu.podspec` to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'flutter_qiyu' 7 | s.version = '0.0.1' 8 | s.summary = 'A new Flutter plugin project.' 9 | s.description = <<-DESC 10 | A new Flutter plugin project. 11 | DESC 12 | s.homepage = 'http://example.com' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Your Company' => 'email@example.com' } 15 | s.source = { :path => '.' } 16 | s.source_files = 'Classes/**/*' 17 | s.public_header_files = 'Classes/**/*.h' 18 | s.dependency 'Flutter' 19 | s.dependency 'QY_iOS_SDK', '~> 9.1.0' 20 | s.platform = :ios, '11.0' 21 | 22 | # Flutter.framework does not contain a i386 slice. 23 | # s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } 24 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } 25 | s.static_framework = true 26 | end 27 | -------------------------------------------------------------------------------- /lib/flutter_qiyu.dart: -------------------------------------------------------------------------------- 1 | export './qiyu.dart'; 2 | export './qy_commodity_info.dart'; 3 | export './qy_service_window_params.dart'; 4 | export './qy_source.dart'; 5 | export './qy_user_info_params.dart'; 6 | -------------------------------------------------------------------------------- /lib/qiyu.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/services.dart'; 4 | 5 | import './qy_service_window_params.dart'; 6 | import './qy_user_info_params.dart'; 7 | 8 | typedef UnreadCountChangeListener(int unreadCount); 9 | 10 | class QiYuMethodCallHandler { 11 | QiYuMethodCallHandler(); 12 | 13 | List _unreadCountChangeListeners = []; 14 | 15 | void register(dynamic listener) { 16 | if (listener is UnreadCountChangeListener) { 17 | _unreadCountChangeListeners.add(listener); 18 | } 19 | } 20 | 21 | void unregister(dynamic listener) { 22 | if (listener is UnreadCountChangeListener) { 23 | _unreadCountChangeListeners.removeWhere((v) => v == listener); 24 | } 25 | } 26 | 27 | Future handler(MethodCall call) { 28 | switch (call.method) { 29 | case 'onUnreadCountChange': 30 | for (var unreadCountChangeListener in _unreadCountChangeListeners) { 31 | int unreadCount = call.arguments['unreadCount']; 32 | unreadCountChangeListener(unreadCount); 33 | } 34 | break; 35 | default: 36 | throw new UnsupportedError("Unrecognized Method"); 37 | } 38 | return null!; 39 | } 40 | } 41 | 42 | class QiYu { 43 | static const MethodChannel _channel = const MethodChannel('flutter_qiyu'); 44 | 45 | static QiYuMethodCallHandler _methodCallHandler = QiYuMethodCallHandler(); 46 | 47 | static void registerListener(dynamic listener) { 48 | _methodCallHandler.register(listener); 49 | } 50 | 51 | static void unregisterListener(dynamic listener) { 52 | _methodCallHandler.unregister(listener); 53 | } 54 | 55 | static void onUnreadCountChange(UnreadCountChangeListener listener) { 56 | _methodCallHandler.register(listener); 57 | } 58 | 59 | static Future registerApp({String? appKey, String? appName}) async { 60 | _channel.setMethodCallHandler(_methodCallHandler.handler); 61 | 62 | return await _channel.invokeMethod('registerApp', { 63 | 'appKey': appKey, 64 | 'appName': appName, 65 | }); 66 | } 67 | 68 | static Future openServiceWindow(QYServiceWindowParams params) async { 69 | return await _channel.invokeMethod('openServiceWindow', params.toJson()); 70 | } 71 | 72 | static Future setCustomUIConfig(Map params) async { 73 | return await _channel.invokeMethod('setCustomUIConfig', params); 74 | } 75 | 76 | static Future getUnreadCount() async { 77 | return await _channel.invokeMethod('getUnreadCount', {}); 78 | } 79 | 80 | static Future setUserInfo(QYUserInfoParams params) async { 81 | return await _channel.invokeMethod('setUserInfo', params.toJson()); 82 | } 83 | 84 | static Future logout() async { 85 | return await _channel.invokeMethod('logout', {}); 86 | } 87 | 88 | static Future cleanCache() async { 89 | return await _channel.invokeMethod('cleanCache', {}); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /lib/qy_commodity_info.dart: -------------------------------------------------------------------------------- 1 | class QYCommodityInfo { 2 | String? commodityInfoTitle; 3 | String? commodityInfoDesc; 4 | String? pictureUrl; 5 | String? commodityInfoUrl; 6 | String? note; 7 | bool? show; 8 | bool? sendByUser; 9 | 10 | QYCommodityInfo({ 11 | this.commodityInfoTitle, 12 | this.commodityInfoDesc, 13 | this.pictureUrl, 14 | this.commodityInfoUrl, 15 | this.note, 16 | this.show, 17 | this.sendByUser, 18 | }); 19 | 20 | factory QYCommodityInfo.fromJson(Map json) { 21 | return QYCommodityInfo( 22 | commodityInfoTitle: json['commodityInfoTitle'], 23 | commodityInfoDesc: json['commodityInfoDesc'], 24 | pictureUrl: json['pictureUrl'], 25 | commodityInfoUrl: json['commodityInfoUrl'], 26 | note: json['note'], 27 | show: json['show'], 28 | sendByUser: json['sendByUser'], 29 | ); 30 | } 31 | 32 | Map toJson() { 33 | Map json = new Map(); 34 | 35 | if (commodityInfoTitle != null) 36 | json.putIfAbsent('commodityInfoTitle', () => commodityInfoTitle); 37 | if (commodityInfoDesc != null) 38 | json.putIfAbsent('commodityInfoDesc', () => commodityInfoDesc); 39 | if (pictureUrl != null) 40 | json.putIfAbsent('pictureUrl', () => pictureUrl); 41 | if (commodityInfoUrl != null) 42 | json.putIfAbsent('commodityInfoUrl', () => commodityInfoUrl); 43 | if (note != null) 44 | json.putIfAbsent('note', () => note); 45 | if (show != null) 46 | json.putIfAbsent('show', () => show); 47 | if (sendByUser != null) 48 | json.putIfAbsent('sendByUser', () => sendByUser); 49 | return json; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/qy_service_window_params.dart: -------------------------------------------------------------------------------- 1 | import './qy_commodity_info.dart'; 2 | import './qy_source.dart'; 3 | 4 | class QYServiceWindowParams { 5 | QYSource? source; 6 | QYCommodityInfo? commodityInfo; 7 | 8 | String? sessionTitle; 9 | int groupId; 10 | int staffId; 11 | int? robotId; 12 | bool robotFirst; 13 | int faqTemplateId; 14 | int vipLevel; 15 | bool showQuitQueue; 16 | bool showCloseSessionEntry; 17 | 18 | QYServiceWindowParams({ 19 | this.source, 20 | this.commodityInfo, 21 | this.sessionTitle, 22 | this.groupId = 0, 23 | this.staffId = 0, 24 | this.robotId, 25 | this.robotFirst = false, 26 | this.faqTemplateId = 0, 27 | this.vipLevel = 0, 28 | this.showQuitQueue = true, 29 | this.showCloseSessionEntry = true, 30 | }); 31 | 32 | factory QYServiceWindowParams.fromJson(Map json) { 33 | return QYServiceWindowParams( 34 | source: QYSource.fromJson(json['source']), 35 | commodityInfo: json.containsKey('commodityInfo') 36 | ? QYCommodityInfo.fromJson(json['commodityInfo']) 37 | : null, 38 | sessionTitle: json['sessionTitle'], 39 | groupId: json['groupId'], 40 | staffId: json['staffId'], 41 | robotId: json['robotId'], 42 | robotFirst: json['robotFirst'], 43 | faqTemplateId: json['faqTemplateId'], 44 | vipLevel: json['vipLevel'], 45 | showQuitQueue: json['showQuitQueue'], 46 | showCloseSessionEntry: json['showCloseSessionEntry'], 47 | ); 48 | } 49 | 50 | Map toJson() { 51 | Map json = new Map(); 52 | if (source != null) json.putIfAbsent('source', () => source!.toJson()); 53 | if (commodityInfo != null) 54 | json.putIfAbsent('commodityInfo', () => commodityInfo!.toJson()); 55 | if (sessionTitle != null) 56 | json.putIfAbsent('sessionTitle', () => sessionTitle); 57 | if (groupId != null) json.putIfAbsent('groupId', () => groupId); 58 | if (staffId != null) json.putIfAbsent('staffId', () => staffId); 59 | if (robotId != null) json.putIfAbsent('robotId', () => robotId); 60 | if (robotFirst != null) json.putIfAbsent('robotFirst', () => robotFirst); 61 | if (faqTemplateId != null) 62 | json.putIfAbsent('faqTemplateId', () => faqTemplateId); 63 | if (vipLevel != null) json.putIfAbsent('vipLevel', () => vipLevel); 64 | if (showQuitQueue != null) 65 | json.putIfAbsent('showQuitQueue', () => showQuitQueue); 66 | if (showCloseSessionEntry != null) 67 | json.putIfAbsent('showCloseSessionEntry', () => showCloseSessionEntry); 68 | return json; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /lib/qy_source.dart: -------------------------------------------------------------------------------- 1 | class QYSource { 2 | String? sourceTitle; 3 | String? sourceUrl; 4 | String? sourceCustomInfo; 5 | 6 | QYSource({ 7 | this.sourceTitle, 8 | this.sourceUrl, 9 | this.sourceCustomInfo, 10 | }); 11 | 12 | factory QYSource.fromJson(Map json) { 13 | return QYSource( 14 | sourceTitle: json['sourceTitle'], 15 | sourceUrl: json['sourceUrl'], 16 | sourceCustomInfo: json['sourceCustomInfo'], 17 | ); 18 | } 19 | 20 | Map toJson() { 21 | return { 22 | 'sourceTitle': sourceTitle, 23 | 'sourceUrl': sourceUrl, 24 | 'sourceCustomInfo': sourceCustomInfo, 25 | }; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/qy_user_info_params.dart: -------------------------------------------------------------------------------- 1 | class QYUserInfoParams { 2 | String? userId; 3 | String? data; 4 | 5 | QYUserInfoParams({ 6 | this.userId, 7 | this.data, 8 | }); 9 | 10 | factory QYUserInfoParams.fromJson(Map json) { 11 | return QYUserInfoParams( 12 | userId: json['userId'], 13 | data: json['data'], 14 | ); 15 | } 16 | 17 | Map toJson() { 18 | return { 19 | 'userId': userId, 20 | 'data': data, 21 | }; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "1.3.0" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "1.1.1" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "1.18.0" 44 | fake_async: 45 | dependency: transitive 46 | description: 47 | name: fake_async 48 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "1.3.1" 52 | flutter: 53 | dependency: "direct main" 54 | description: flutter 55 | source: sdk 56 | version: "0.0.0" 57 | flutter_lints: 58 | dependency: "direct dev" 59 | description: 60 | name: flutter_lints 61 | sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 62 | url: "https://pub.dev" 63 | source: hosted 64 | version: "2.0.3" 65 | flutter_test: 66 | dependency: "direct dev" 67 | description: flutter 68 | source: sdk 69 | version: "0.0.0" 70 | leak_tracker: 71 | dependency: transitive 72 | description: 73 | name: leak_tracker 74 | sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" 75 | url: "https://pub.dev" 76 | source: hosted 77 | version: "10.0.0" 78 | leak_tracker_flutter_testing: 79 | dependency: transitive 80 | description: 81 | name: leak_tracker_flutter_testing 82 | sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 83 | url: "https://pub.dev" 84 | source: hosted 85 | version: "2.0.1" 86 | leak_tracker_testing: 87 | dependency: transitive 88 | description: 89 | name: leak_tracker_testing 90 | sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 91 | url: "https://pub.dev" 92 | source: hosted 93 | version: "2.0.1" 94 | lints: 95 | dependency: transitive 96 | description: 97 | name: lints 98 | sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" 99 | url: "https://pub.dev" 100 | source: hosted 101 | version: "2.1.1" 102 | matcher: 103 | dependency: transitive 104 | description: 105 | name: matcher 106 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb 107 | url: "https://pub.dev" 108 | source: hosted 109 | version: "0.12.16+1" 110 | material_color_utilities: 111 | dependency: transitive 112 | description: 113 | name: material_color_utilities 114 | sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" 115 | url: "https://pub.dev" 116 | source: hosted 117 | version: "0.8.0" 118 | meta: 119 | dependency: transitive 120 | description: 121 | name: meta 122 | sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 123 | url: "https://pub.dev" 124 | source: hosted 125 | version: "1.11.0" 126 | path: 127 | dependency: transitive 128 | description: 129 | name: path 130 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 131 | url: "https://pub.dev" 132 | source: hosted 133 | version: "1.9.0" 134 | sky_engine: 135 | dependency: transitive 136 | description: flutter 137 | source: sdk 138 | version: "0.0.99" 139 | source_span: 140 | dependency: transitive 141 | description: 142 | name: source_span 143 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 144 | url: "https://pub.dev" 145 | source: hosted 146 | version: "1.10.0" 147 | stack_trace: 148 | dependency: transitive 149 | description: 150 | name: stack_trace 151 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 152 | url: "https://pub.dev" 153 | source: hosted 154 | version: "1.11.1" 155 | stream_channel: 156 | dependency: transitive 157 | description: 158 | name: stream_channel 159 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 160 | url: "https://pub.dev" 161 | source: hosted 162 | version: "2.1.2" 163 | string_scanner: 164 | dependency: transitive 165 | description: 166 | name: string_scanner 167 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 168 | url: "https://pub.dev" 169 | source: hosted 170 | version: "1.2.0" 171 | term_glyph: 172 | dependency: transitive 173 | description: 174 | name: term_glyph 175 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 176 | url: "https://pub.dev" 177 | source: hosted 178 | version: "1.2.1" 179 | test_api: 180 | dependency: transitive 181 | description: 182 | name: test_api 183 | sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" 184 | url: "https://pub.dev" 185 | source: hosted 186 | version: "0.6.1" 187 | vector_math: 188 | dependency: transitive 189 | description: 190 | name: vector_math 191 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 192 | url: "https://pub.dev" 193 | source: hosted 194 | version: "2.1.4" 195 | vm_service: 196 | dependency: transitive 197 | description: 198 | name: vm_service 199 | sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 200 | url: "https://pub.dev" 201 | source: hosted 202 | version: "13.0.0" 203 | sdks: 204 | dart: ">=3.2.0-0 <4.0.0" 205 | flutter: ">=2.5.0" 206 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_qiyu 2 | description: 适用于 Flutter 的七鱼客服插件 3 | version: 0.1.2 4 | homepage: https://github.com/leanflutter/flutter_qiyu 5 | 6 | environment: 7 | sdk: ">=2.12.0 <4.0.0" 8 | flutter: ">=2.5.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | dev_dependencies: 15 | flutter_test: 16 | sdk: flutter 17 | flutter_lints: ^2.0.0 18 | 19 | flutter: 20 | plugin: 21 | platforms: 22 | android: 23 | package: org.leanflutter.plugins.flutter_qiyu 24 | pluginClass: FlutterQiyuPlugin 25 | ios: 26 | pluginClass: FlutterQiyuPlugin 27 | --------------------------------------------------------------------------------