Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7f5c7d8fb | ||
|
|
e4d0407c63 | ||
|
|
754f161a3f | ||
|
|
fa8584a73f | ||
|
|
5cc2685f03 |
@@ -65,10 +65,12 @@ LOG_LEVEL=3
|
||||
LIVEKIT_API_KEY=openimLKkey
|
||||
# secret 必须 ≥32 字符,否则 LiveKit 启动报 secret is too short
|
||||
LIVEKIT_API_SECRET=lk-secret-9f2c7a41d5e8b063f1a4c795e2d8b3a6
|
||||
# 三个都是宿主机映射端口;7880/7881/7882 被占用时改成 17880/17881/17882 之类即可
|
||||
LIVEKIT_PORT=7880
|
||||
LIVEKIT_RTC_TCP_PORT=7881
|
||||
LIVEKIT_RTC_UDP_PORT=7882
|
||||
# 三个端口必须与 config/livekit.yaml 的 port/tcp_port/udp_port 完全一致,
|
||||
# 且与 docker-compose.yaml 的“宿主侧=容器侧”保持一致(默认 17880/17881/17882)。
|
||||
# 改端口时三个文件要一起改,否则语音通话会出现“能接听但双方网络错误”。
|
||||
LIVEKIT_PORT=17880
|
||||
LIVEKIT_RTC_TCP_PORT=17881
|
||||
LIVEKIT_RTC_UDP_PORT=17882
|
||||
|
||||
# ===== 公司账号服务(工号+密码登录,自研)=====
|
||||
# 宿主端口;管理页 http://<SERVER_IP>:10010/
|
||||
|
||||
@@ -6,3 +6,13 @@
|
||||
/components/
|
||||
.selftest/
|
||||
data/
|
||||
|
||||
# mobile-next:官方基线构建产物与本机路径,不入库
|
||||
/mobile-next/build/
|
||||
/mobile-next/.dart_tool/
|
||||
/mobile-next/android/.gradle/
|
||||
/mobile-next/android/local.properties
|
||||
/mobile-next/android/app/proguard/
|
||||
/mobile-next/**/.flutter-plugins
|
||||
/mobile-next/**/.flutter-plugins-dependencies
|
||||
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
| 10002 | TCP/HTTP | OpenIM REST API |
|
||||
| 10005 | TCP/HTTP | MinIO(图片/语音/文件下载) |
|
||||
| 10010 | TCP/HTTP | 公司账号服务(员工登录接口 + 管理页) |
|
||||
| 7880 | TCP/WS | LiveKit 信令(`.env` 的 `LIVEKIT_PORT` 可改) |
|
||||
| 7882 | UDP | LiveKit 语音媒体(`LIVEKIT_RTC_UDP_PORT` 可改) |
|
||||
| 7881 | TCP | LiveKit 媒体备用通道(`LIVEKIT_RTC_TCP_PORT` 可改) |
|
||||
| 17880 | TCP/WS | LiveKit 信令(`.env` 的 `LIVEKIT_PORT` 可改,但必须与 `config/livekit.yaml` 一致) |
|
||||
| 17882 | UDP | LiveKit 语音媒体(`LIVEKIT_RTC_UDP_PORT` 可改,同上) |
|
||||
| 17881 | TCP | LiveKit 媒体备用通道(`LIVEKIT_RTC_TCP_PORT` 可改,同上) |
|
||||
| 10004 | TCP/HTTP | MinIO 控制台(运维用,可不开放) |
|
||||
| 12379/12380 | TCP | Etcd(仅容器间用,建议不对外) |
|
||||
|
||||
@@ -79,7 +79,7 @@ docker compose up -d # 再启动
|
||||
|
||||
- OpenIM API: `http://<服务器IP>:10002`
|
||||
- OpenIM WebSocket: `ws://<服务器IP>:10001`
|
||||
- LiveKit: `ws://<服务器IP>:7880`(7880 为默认信令端口,可用 `.env` 的 `LIVEKIT_PORT` 改),API Key/Secret 见 `.env` 的 `LIVEKIT_API_KEY` / `LIVEKIT_API_SECRET`
|
||||
- LiveKit: `ws://<服务器IP>:17880`(17880 为默认信令端口;改端口时必须 `.env` 的 `LIVEKIT_PORT`、`config/livekit.yaml` 的 `port`、`docker-compose.yaml` 的容器侧端口三者一起改),API Key/Secret 见 `.env` 的 `LIVEKIT_API_KEY` / `LIVEKIT_API_SECRET`
|
||||
- 测试账号:`test001` / `test002`(由自测脚本注册);语音通话时两名用户以各自 identity 进同一房间即可
|
||||
|
||||
## 常见问题
|
||||
@@ -87,6 +87,6 @@ docker compose up -d # 再启动
|
||||
- **文件/语音能发但打不开**:`MINIO_EXTERNAL_ADDRESS` 没写成客户端能访问的 IP。改 `.env` 后 `docker compose up -d` 重建 openim-server。
|
||||
- **启动报缺 `ETCD_USERNAME` / `KAFKA_USERNAME` 等警告**:未启用对应组件认证,官方说明可忽略。
|
||||
- **openim-server 一直 unhealthy**:`docker exec -it openim-server mage check` 看哪项依赖没通;首次启动需等 30-60 秒。
|
||||
- **livekit 启动报 `bind ... 7880/7881: address already in use`**:服务器上这些端口被别的程序占了(`ss -tlnp | grep 788` 查占用者)。不要动别人的服务,把 `.env` 里 `LIVEKIT_PORT` / `LIVEKIT_RTC_TCP_PORT` / `LIVEKIT_RTC_UDP_PORT` 改成空闲端口(如 17880/17881/17882),再 `docker compose up -d --force-recreate livekit`。之后客户端和自测脚本都用新端口(自测脚本会自动读 `.env`)。
|
||||
- **livekit 启动报 `bind ... 7880/7881: address already in use`**:服务器上这些端口被别的程序占了(`ss -tlnp | grep 788` 查占用者)。不要动别人的服务,把端口统一改成空闲端口(如 17880/17881/17882)——注意**必须三处一起改**:`.env` 的 `LIVEKIT_PORT` / `LIVEKIT_RTC_TCP_PORT` / `LIVEKIT_RTC_UDP_PORT`、`config/livekit.yaml` 的 `port` / `tcp_port` / `udp_port`、`docker-compose.yaml` 里 livekit 的容器侧端口(保持“宿主侧=容器侧”),然后 `docker compose up -d --force-recreate livekit`。只改其中一两处会导致“能邀请、能接听,但接听后双方网络错误”。
|
||||
- **livekit 日志报 `secret is too short`**:`LIVEKIT_API_SECRET` 必须 ≥32 字符,换个长密钥后重建 livekit 容器。
|
||||
- **语音通话连不上**:确认服务器 UDP 7882 放行(内网防火墙/安全组);UDP 不通时会走 TCP 7881 兜底。
|
||||
- **语音通话连不上(接听后双方网络错误)**:先确认 `.env` / `config/livekit.yaml` / `docker-compose.yaml` 三处端口一致;再确认服务器防火墙放通 `LIVEKIT_PORT`(TCP)、`LIVEKIT_RTC_TCP_PORT`(TCP)、`LIVEKIT_RTC_UDP_PORT`(UDP)(默认 17880/17881/17882)。UDP 不通时会走 TCP 兜底。
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
# LiveKit 服务端配置(内网部署)
|
||||
# API Key/Secret 通过环境变量 LIVEKIT_KEYS 注入(见 docker-compose.yaml)
|
||||
# 服务器对内 IP 通过启动参数 --node-ip 注入(deploy.sh 写入 .env 的 SERVER_IP)
|
||||
port: 7880
|
||||
#
|
||||
# 重要:这里的 port / tcp_port / udp_port 必须与 docker-compose.yaml 里
|
||||
# 容器侧端口、以及 .env 的 LIVEKIT_PORT / LIVEKIT_RTC_TCP_PORT /
|
||||
# LIVEKIT_RTC_UDP_PORT 三者完全一致(默认 17880/17881/17882)。
|
||||
# LiveKit 用 --node-ip + use_external_ip:false 向客户端宣告媒体地址时,
|
||||
# 只会宣告这里的端口,不会感知 Docker 宿主侧的重映射;三者不一致会导致
|
||||
# “能邀请、能接听,但接听后双方网络错误”(信令通、媒体不通)。
|
||||
port: 17880
|
||||
rtc:
|
||||
tcp_port: 7881
|
||||
udp_port: 7882
|
||||
tcp_port: 17881
|
||||
udp_port: 17882
|
||||
# 内网部署:不做公网 IP 探测,candidate 直接使用 --node-ip
|
||||
use_external_ip: false
|
||||
room:
|
||||
|
||||
@@ -370,7 +370,9 @@ services:
|
||||
|
||||
# LiveKit:语音/视频通话的 SFU,Apache 2.0,自部署。
|
||||
# 客户端通过 ws://<SERVER_IP>:<LIVEKIT_PORT> 连接,凭 LIVEKIT_API_KEY/SECRET 签发的 token 进房。
|
||||
# 三个宿主端口都可在 .env 调整(7880/7881/7882 被其他服务占用时改映射即可,容器内端口不变)。
|
||||
# 三个端口必须与 config/livekit.yaml 里容器监听的端口完全一致(默认 17880/17881/17882),
|
||||
# 即“宿主侧 = 容器侧”,不要在宿主侧做重映射;LiveKit 向客户端宣告媒体地址时只认
|
||||
# config/livekit.yaml 里的端口,重映射会导致信令通、媒体不通。
|
||||
livekit:
|
||||
image: ${LIVEKIT_IMAGE}
|
||||
container_name: livekit
|
||||
@@ -379,9 +381,9 @@ services:
|
||||
environment:
|
||||
LIVEKIT_KEYS: "${LIVEKIT_API_KEY}: ${LIVEKIT_API_SECRET}"
|
||||
ports:
|
||||
- "${LIVEKIT_PORT:-7880}:7880" # HTTP / WebSocket 信令
|
||||
- "${LIVEKIT_RTC_TCP_PORT:-7881}:7881" # RTC over TCP(UDP 不通时的备用通道)
|
||||
- "${LIVEKIT_RTC_UDP_PORT:-7882}:7882/udp" # RTC 媒体(UDP 复用端口)
|
||||
- "${LIVEKIT_PORT:-17880}:17880" # HTTP / WebSocket 信令
|
||||
- "${LIVEKIT_RTC_TCP_PORT:-17881}:17881" # RTC over TCP(UDP 不通时的备用通道)
|
||||
- "${LIVEKIT_RTC_UDP_PORT:-17882}:17882/udp" # RTC 媒体(UDP 复用端口)
|
||||
volumes:
|
||||
- ./config/livekit.yaml:/etc/livekit.yaml
|
||||
networks:
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
# mobile-next 固定基线导入与构建记录(B-128 第1阶段)
|
||||
|
||||
## 上游来源
|
||||
|
||||
- 项目:OpenIM 官方 Flutter 样板工程 `openim-flutter-demo`
|
||||
- 仓库:`https://github.com/OpenIMSDK/openim-flutter-demo.git`
|
||||
- 固定基线:tag `3.8.3-patch.3`,提交 `b3dfdb1e8aaeaaf6f0793e10cadd20d5c184a31f`("Updated IM SDK",2025-03-07)
|
||||
- 校验:`git ls-remote --tags` 解析该 tag 的 `^{}` 即指向 `b3dfdb1e8aaeaaf6f0793e10cadd20d5c184a31f`
|
||||
|
||||
## 导入方式
|
||||
|
||||
- 并行目录 `mobile-next/`,与现网 `mobile/` 并存,未覆盖、未改动 `mobile/`。
|
||||
- 以 `git clone --no-checkout` 拉取上游后 `git checkout 3.8.3-patch.3`,将整棵工作树复制入 `mobile-next/`(剔除 `.git` 与 `.DS_Store`)。
|
||||
- 导入后与原 tag 树做 `git diff --no-index` 比对,除 `.git`/`.DS_Store` 外**零差异**。
|
||||
- 未迁入公司功能、未换品牌、未调整 SDK 版本,源码保持上游原样。
|
||||
- 平台工程内生成的 `android/local.properties`(sdk.dir / flutter.sdk 指向本机)不入库(见 `.gitignore`)。
|
||||
|
||||
## 许可证位置
|
||||
|
||||
- 上游仓库根目录 `LICENSE`(已随导入进入 `mobile-next/LICENSE`)。
|
||||
- 子包 `openim_common/LICENSE`、`openim_live/LICENSE`、`local_plugin/flutter_openim_live_alert/LICENSE`。
|
||||
- 各 pub.dev 依赖许可证见各自包目录,依赖清单以 `mobile-next/pubspec.yaml` 与 `mobile-next/pubspec.lock` 为准。
|
||||
|
||||
## 锁定工具链版本
|
||||
|
||||
| 组件 | 版本 |
|
||||
| --- | --- |
|
||||
| Flutter | 3.24.5 stable(revision `dec2ee5c1f`,engine `a18df97ca5`) |
|
||||
| Dart | 3.5.4(随 Flutter 3.24.5 分发) |
|
||||
| JDK | OpenJDK 17.0.20+8(Temurin) |
|
||||
| Gradle | 7.6.3(`android/gradle/wrapper/gradle-wrapper.properties` 锁定) |
|
||||
| AGP | 7.3.1(`android/build.gradle` buildscript 声明) |
|
||||
| Kotlin | 1.9.23(`android/build.gradle` `ext.kotlin_version`) |
|
||||
| Android SDK | compileSdk 34,minSdk 24,targetSdk 33,build-tools 36.0.0 |
|
||||
| Dart 依赖锁 | `mobile-next/pubspec.lock`(上游自带,原样保留) |
|
||||
| OpenIM SDK | `flutter_openim_sdk 3.8.3+3`(上游 pubspec 锁定) |
|
||||
|
||||
注意:`pubspec.lock` 为上游原样内容;执行 `flutter pub get` 后仅将 `flutter_openim_sdk` 由 lock 中记录的 `3.8.3+2` 对齐到 `pubspec.yaml` 声明的 `3.8.3+3`(上游 lock 与 pubspec 不一致,为官方产物)。
|
||||
|
||||
## 可复现构建命令
|
||||
|
||||
前置环境变量:
|
||||
|
||||
```
|
||||
set JAVA_HOME=<JDK17 目录>
|
||||
set ANDROID_HOME=<Android SDK 目录>
|
||||
set PATH=%JAVA_HOME%\bin;<Flutter SDK>\bin;%PATH%
|
||||
```
|
||||
|
||||
`mobile-next/android/local.properties` 需含:
|
||||
|
||||
```
|
||||
sdk.dir=<Android SDK 目录,反斜杠转义>
|
||||
flutter.sdk=<Flutter SDK 目录,反斜杠转义>
|
||||
```
|
||||
|
||||
首次执行依赖解析(会写 `.dart_tool`,不产生源码改动):
|
||||
|
||||
```
|
||||
flutter pub get
|
||||
```
|
||||
|
||||
### Debug 构建
|
||||
|
||||
```
|
||||
flutter build apk --debug
|
||||
```
|
||||
|
||||
产物:`build/app/outputs/flutter-apk/app-debug.apk`(约 110 MB)。
|
||||
|
||||
### Release 构建
|
||||
|
||||
```
|
||||
flutter build apk --release
|
||||
```
|
||||
|
||||
产物:`build/app/outputs/flutter-apk/app-release.apk`(约 51.3 MB,签名使用上游自带 keystore `android/app/openim`,alias/password 均为 `openim`)。
|
||||
|
||||
## 构建结果(2026-08-19,本机实测)
|
||||
|
||||
| 构建 | 结果 | 产物 | 大小 | SHA256 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| debug | 成功 | `app-debug.apk` | 109,930,873 B | `55789791CE8226573C0030A026E5C89C44AD6E154884F24F7329357FCA7E0464` |
|
||||
| release | 成功 | `app-release.apk` | 53,742,479 B | `46D5900FC735FE0880994385691E62A00589040C4D9FCD4DFA69E003763E7780`(sha1 `7191307bc54624c7b3cfdf13ed2378a749b19ec2`) |
|
||||
|
||||
APK 元数据(aapt badging):package `io.openim.flutter.demo`,versionName `3.8.3`,versionCode `180`,minSdk 24 / targetSdk 33 / compileSdk 34。
|
||||
|
||||
### 构建期警告(不影响产物)
|
||||
|
||||
- Flutter Gradle 插件以 `apply script` 方式应用,报 "deprecated, will be removed in a future release"(上游工程原生写法,非本任务改动)。
|
||||
- 部分依赖 Kotlin metadata 版本(1.8.x)高于工程 Kotlin(1.9.23 预期 1.6.0/1.8.0)的警告,属于上游依赖组合特性,debug/release 均通过。
|
||||
|
||||
## 失败证据
|
||||
|
||||
本阶段 debug 与 release 均构建成功,无失败步骤。若后续步骤出现构建失败,按完成标准须明确到具体依赖或构建步骤并留存日志,不再继续后续兼容迁移。
|
||||
|
||||
## 回退方法
|
||||
|
||||
本任务为独立提交,仅新增 `mobile-next/` 与本文档,未触碰 `mobile/`、`pc-client/`、`account-service/` 及现网服务。
|
||||
|
||||
回退命令:
|
||||
|
||||
```
|
||||
git revert 0a2fbac
|
||||
```
|
||||
|
||||
或直接删除并行目录(不影响现网):
|
||||
|
||||
```
|
||||
git rm -r mobile-next
|
||||
```
|
||||
|
||||
## 备注
|
||||
|
||||
- 本目录仅证明「官方固定基线可稳定构建」,不含任何公司定制逻辑,尚未接入公司账号/品牌,属后续阶段工作。
|
||||
@@ -0,0 +1,109 @@
|
||||
# mobile-next 通信组件热修接入与核心能力实测记录(B-137)
|
||||
|
||||
> 基线:`0a2fbac`(官方 openim-flutter-demo 3.8.3-patch.3 固定基线导入)+ `44ac7d9`(文档修正)。
|
||||
> 本阶段只做一件事:把 `flutter_openim_sdk` 从 `3.8.3+3` 升级到 `3.8.3+hotfix.12`,锁定依赖、完成 debug/release 双构建、用两个测试账号逐项实测核心通信能力。未开始品牌换壳或公司业务迁移。
|
||||
|
||||
## 一、依赖升级与差异记录
|
||||
|
||||
### 变更文件(仅 4 个,全部为版本号)
|
||||
|
||||
| 文件 | 变更 |
|
||||
| --- | --- |
|
||||
| `mobile-next/pubspec.yaml` | `flutter_openim_sdk: 3.8.3+3` → `3.8.3+hotfix.12` |
|
||||
| `mobile-next/openim_common/pubspec.yaml` | 同上 |
|
||||
| `mobile-next/openim_live/pubspec.yaml` | 同上 |
|
||||
| `mobile-next/pubspec.lock` | `flutter_openim_sdk` sha256 与 version 同步更新 |
|
||||
|
||||
`openim_common` / `openim_live` 为 `mobile-next/` 内的本地子包,同样引用该 SDK,必须一致升级,否则 `flutter pub get` 解析失败。
|
||||
|
||||
### 依赖解析结果
|
||||
|
||||
`flutter pub get` 输出仅 `flutter_openim_sdk 3.8.3+hotfix.12 (was 3.8.3+3)`,**其余全部依赖无变化**。
|
||||
|
||||
### pubspec.lock 差异
|
||||
|
||||
```diff
|
||||
flutter_openim_sdk:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_openim_sdk
|
||||
- sha256: "09149d60b4c096acab52279365285409123f15f9111d5fc84cc2481b29343a04"
|
||||
+ sha256: b57d1fd63f52fa5cbd7c257fccc9d04902c266e96172f5112c00b428af2f2ff5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
- version: "3.8.3+3"
|
||||
+ version: "3.8.3+hotfix.12"
|
||||
```
|
||||
|
||||
### hotfix 与旧版 API 差异(基于 pub.dev 下载的源码 diff)
|
||||
|
||||
`flutter_openim_sdk 3.8.3+hotfix.12` 相对 `3.8.3+3` 的 Dart API 变化均为**新增/放宽**,向后兼容:
|
||||
|
||||
- `FriendshipManager` 新增 `getFriendApplicationListAsRecipient` / `getFriendApplicationListAsApplicant` / `getFriendApplicationUnhandledCount`。
|
||||
- `GroupManager` 新增 `getGroupApplicationUnhandledCount`;`inviteUserToGroup` / `kickGroupMember` 返回类型由 `Future<List<GroupInviteResult>>` 放宽为 `Future`。
|
||||
- `ConversationManager` 删除 2 行(内部实现),无公开 API 变更。
|
||||
|
||||
`dart analyze lib test` 对应用代码 **0 error**(仅有上游自带 info/warning 级 lint,与本次升级无关)。应用内调用 `inviteUserToGroup` / `kickGroupMember` 的地方(`lib/pages/chat/group_setup/group_setup_logic.dart:401,421`)不依赖返回值,编译通过。
|
||||
|
||||
### Android 原生侧差异(影响构建产物,不改变应用代码)
|
||||
|
||||
- hotfix 的 `android/build.gradle`:AGP `7.3.1`→`8.7.3`、compileSdk `34`→`35`、Java `1.8`→`11`;核心库 `io.openim:core-sdk:3.8.3-patch3@aar` → `3.8.3-patch12@aar`。
|
||||
- 应用工程 `mobile-next/android/`(固定基线)仍为 AGP 7.3.1 / compileSdk 34 / Java 1.8,构建时以应用工程为准,hotfix 插件用应用工程工具链编译,双构建均通过。
|
||||
|
||||
## 二、构建与产物
|
||||
|
||||
工具链:Flutter 3.24.5(`C:\flutter324`)、JDK 17.0.20(Temurin)、Android SDK(platforms 34/35/36,build-tools 36.0.0)、Gradle 7.6.3 / AGP 7.3.1(应用工程锁定)。
|
||||
|
||||
| 构建 | 结果 | 产物 | 大小 | SHA256 | 签名 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| debug | 成功 | `app-debug.apk` | 109,454,753 B | `9020C291B9BE12C5B50720264797B06AF1D9C21708A5B8AD2847594C486DB642` | CN=openim keystore(与 release 同源) |
|
||||
| release | 成功 | `app-release.apk` | 53,323,403 B | `A746DC83C3DB2E35A7AFA90B7FC1A02EAF751631F1DA9AAAF1799B28529B7F84` | CN=openim, cert SHA-256 `1f38a82fb3c33be7951fb5d964ef5bd9c6c9bfc084ae1e2a8a40a0d1f44ae1fe` |
|
||||
|
||||
APK 元数据(aapt badging,debug 与 release 一致):package `io.openim.flutter.demo`,versionName `3.8.3`,versionCode `180`,minSdk 24 / targetSdk 33 / compileSdk 34。
|
||||
|
||||
构建期警告与基线相同(Flutter Gradle 插件 apply-script 弃用提示、部分依赖 Kotlin metadata 版本高于工程 Kotlin 的提示),不影响产物。release 包字体 tree-shaking 正常。
|
||||
|
||||
> 说明:x86_64 模拟器测试用的 fat APK(`--target-platform android-x64` 临时放开 abiFilters 构建)仅为本地联调产物,未入库,交付物以 arm64 debug/release 为准。
|
||||
|
||||
## 三、核心能力实测(2026-08-19,两 x86_64 模拟器)
|
||||
|
||||
环境:模拟器 A=emulator-5554 登录 t1001("Test One"),模拟器 B=emulator-5556 登录 t1002("Test Two");连真实 OpenIM `192.168.200.11:10002/:10001`。登录凭据 userID+imToken 与公司账号服务签发链路一致(OpenIM `/auth/get_user_token`),SDK 版本日志 `3.8.0`(hotfix 内核 3.8.3-patch12)。
|
||||
|
||||
| # | 能力 | 方法 | 结果 | 证据 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 1 | SDK 初始化 | App 启动 `initSDK(apiAddr, wsAddr, listener…)` | 通过 | 双端 `IM SDK Status: connecting → connectionSucceeded → syncStart → syncEnded` 日志 |
|
||||
| 2 | 登录(userID+imToken) | 双端自动登录 | 通过 | 双端 `conn start`(ws 带 sendID/token),`onConnectSuccess` |
|
||||
| 3 | 会话同步 | 启动拉取会话 | 通过 | 双端 `get_full_conversation_ids` 返回 `si_t1001_t1002` 等;UI 会话列表可见 |
|
||||
| 4 | 断线重连 | 关 WiFi → 开 WiFi | 通过 | 断网 `onConnectFailed` + `reConn`,恢复后 `onConnectSuccess`,随后发送 `reconnectOK_3` 送达(seq 11) |
|
||||
| 5 | 好友 | 通讯录→My Friends | 通过 | t1001 好友列表含 "Test Two";早前好友申请通知已接受(`friendApplicationAccepted`) |
|
||||
| 6 | 群组 | 建群 + 群消息 | 通过 | 建群 `hotfix-grp-test`(1481671100,成员 t1001+t1002),双端会话列表出现,群消息 `grp148_msg_ok` 送达 t1002(seq 2) |
|
||||
| 7 | 文字消息 | t1001→t1002 / t1002→t1001 | 通过 | `regHotfixText_1_`(seq 6)、`hotfixBtoA_2`(seq 7)双端 UI + 服务端落库(status 2) |
|
||||
| 8 | 图片消息 | 相册选图发送 | 通过 | `contentType 102`,URL `msg_picture_…png`,t1002 收到(seq 8,hasReadTime 回执) |
|
||||
| 9 | 文件消息 | 文件选择器发送 | 通过 | `contentType 105`,`hotfix-file-test.txt` 66B 上传,t1002 UI 显示文件卡片(seq 9) |
|
||||
| 10 | 语音消息 | 按住说话 | 通过 | `contentType 103`,`.m4a` 33,866B 上传,t1002 收到(seq 10,duration 1s) |
|
||||
|
||||
服务端落库通过 `/msg/search_msg` 复核,均为 `status=2`(已发送)。
|
||||
|
||||
## 四、完成标准核对
|
||||
|
||||
- [x] debug、release 真实构建成功,构建与产物信息齐全(含包名/版本/签名/SHA256)。
|
||||
- [x] 核心能力逐项有"通过"结果与证据(初始化/登录/会话同步/重连/好友/群组/文字/图片/文件/语音),均为双账号实测,非版本号代替。
|
||||
- [x] 任一核心门禁失败则停止后续迁移:本阶段**全部通过**,可进入公司功能迁移(阶段4)。
|
||||
- [x] 旧版安装包、`mobile/`、PC 客户端、现网服务均未改动。
|
||||
|
||||
## 五、已知差异 / 备注
|
||||
|
||||
- 登录链路的 HTTP 工号密码校验(account-service `/api/login`)属于公司业务层,本次未接入 mobile-next(禁止公司业务迁移);SDK 登录用与账号服务同源的 userID+imToken 实测通过。部署账号服务管理口令已改(非默认值),本次未触碰服务端任何配置与数据。
|
||||
- 语音通话(LiveKit)不在本阶段范围(阶段4 迁移),未测。
|
||||
- hotfix 插件自身 `android/build.gradle` 目标升级到 AGP 8.7.3/compileSdk 35,但被应用工程工具链(AGP 7.3.1/compileSdk 34)覆盖,行为由应用工程决定;已按基线记录。
|
||||
- 模拟器测试时照片选择器因"受限访问"需在系统设置授予"允许所有照片",为 Android 14+ 权限行为,非 SDK 问题。
|
||||
|
||||
## 六、回退方法
|
||||
|
||||
本提交只改动 4 个依赖声明文件(`mobile-next/` 内),可单独回退:
|
||||
|
||||
```
|
||||
git revert <本提交哈希>
|
||||
```
|
||||
|
||||
或手动把 4 个文件的 `flutter_openim_sdk` 改回 `3.8.3+3` 并 `flutter pub get`。`mobile/`、`pc-client/`、`account-service/`、服务器与现网均不受影响。
|
||||
@@ -0,0 +1,4 @@
|
||||
/.flutter-plugins
|
||||
/.flutter-plugins-dependencies
|
||||
/.packages
|
||||
/.dart_tool/
|
||||
@@ -0,0 +1,88 @@
|
||||
|
||||
# Common Function Configuration Guide
|
||||
|
||||
- [Offline push](#offlinepush)
|
||||
- [Map](#map)
|
||||
|
||||
## Offlinepush
|
||||
|
||||
Currently using the integrated solution.
|
||||
|
||||
### Client configuration
|
||||
|
||||
#### 1. Use Getui (https://getui.com/) in mainland China
|
||||
|
||||
###### Configure iOS and Android in the integration guide of Getui
|
||||
|
||||
**iOS platform configuration:**
|
||||
According to [its documentation](https://docs.getui.com/getui/mobile/ios/overview/), make the corresponding iOS configuration. Then find the following files in the code and modify the corresponding iOS side key:
|
||||
|
||||
- **[push_controller.dart](openim_common/lib/src/controller/push_controller.dart)**
|
||||
|
||||
```dart
|
||||
const appID = 'your-app-id';
|
||||
const appKey = 'your-app-key';
|
||||
const appSecret = 'your-app-secret';
|
||||
```
|
||||
|
||||
**Android platform configuration:**
|
||||
According to [its documentation](https://docs.getui.com/getui/mobile/android/overview/), make corresponding Android configurations, and pay attention to [multi-vendor](https://docs.getui.com/getui/mobile/vendor/vendor_open/) configurations. Then modify the following file contents:
|
||||
|
||||
- **[build.gradle](android/app/build.gradle)**
|
||||
|
||||
```gradle
|
||||
manifestPlaceholders = [
|
||||
GETUI_APPID : "",
|
||||
XIAOMI_APP_ID : "",
|
||||
XIAOMI_APP_KEY : "",
|
||||
MEIZU_APP_ID : "",
|
||||
MEIZU_APP_KEY : "",
|
||||
HUAWEI_APP_ID : "",
|
||||
OPPO_APP_KEY : "",
|
||||
OPPO_APP_SECRET: "",
|
||||
VIVO_APP_ID : "",
|
||||
VIVO_APP_KEY : "",
|
||||
HONOR_APP_ID : "",
|
||||
]
|
||||
```
|
||||
|
||||
#### 2. Use [FCM (Firebase Cloud Messaging)](https://firebase.google.com/docs/cloud-messaging) in overseas regions
|
||||
|
||||
According to the integration guide of [FCM](https://firebase.google.com/docs/cloud-messaging), replace the following files:
|
||||
|
||||
- **[google-services.json](android/app/google-services.json)** (Android platform)
|
||||
- **[GoogleService-Info.plist](ios/Runner/GoogleService-Info.plist)** (iOS platform)
|
||||
- **[firebase_options.dart](openim_common/lib/src/controller/firebase_options.dart)** (Firebase configuration in Dart project)
|
||||
|
||||
### Offline push banner settings
|
||||
|
||||
Currently, the SDK is designed to directly control the display content of the push banner by the client. When sending a message, set the input parameter [offlinePushInfo](https://github.com/openimsdk/openim-flutter-demo/blob/cc72b6d7ca5f70ca07885857beecec512f904f8c/lib/pages/chat/chat_logic.dart#L543):
|
||||
|
||||
```dart
|
||||
final offlinePushInfo = OfflinePushInfo(
|
||||
title: "Fill in the title",
|
||||
desc: "Fill in the description, such as the message content",
|
||||
iOSBadgeCount: true,
|
||||
);
|
||||
// If you do not customize offlinePushInfo, the title defaults to the app name, and the desc defaults to "You received a new message"
|
||||
```
|
||||
|
||||
According to actual needs, you can enable the offline push function after completing the corresponding client and server configurations.
|
||||
|
||||
---
|
||||
|
||||
## Map
|
||||
|
||||
### Configuration Guide
|
||||
|
||||
Need to configure the corresponding AMap Key. Please refer to [AMap Document](https://lbs.amap.com/) for details. The code in the project needs to modify the following Key:
|
||||
|
||||
- **[webKey](https://github.com/openimsdk/openim-flutter-demo/blob/5720a10a31a0a9bc5319775f9f4da83d6996dbfe/openim_common/lib/src/config.dart#L49)**
|
||||
- **[webServerKey](https://github.com/openimsdk/openim-flutter-demo/blob/5720a10a31a0a9bc5319775f9f4da83d6996dbfe/openim_common/lib/src/config.dart#L50)**
|
||||
|
||||
```dart
|
||||
static const webKey = 'webKey';
|
||||
static const webServerKey = 'webServerKey';
|
||||
```
|
||||
|
||||
Once the configuration is complete, you can enable the map function.
|
||||
@@ -0,0 +1,88 @@
|
||||
|
||||
# 常见功能配置指南
|
||||
|
||||
- [离线推送功能](#离线推送功能)
|
||||
- [地图功能](#地图功能)
|
||||
|
||||
## 离线推送功能
|
||||
|
||||
目前使用的是集成方案。
|
||||
|
||||
### 客户端配置
|
||||
|
||||
#### 1. 中国大陆地区使用个推([Getui](https://getui.com/))
|
||||
|
||||
###### 在[Getui](https://getui.com/)的集成指南,配置iOS和Android。
|
||||
|
||||
**iOS 平台配置:**
|
||||
根据[其文档](https://docs.getui.com/getui/mobile/ios/overview/)做好相应的iOS配置。然后在代码中找到以下文件并修改对应的 iOS侧Key:
|
||||
|
||||
- **[push_controller.dart](openim_common/lib/src/controller/push_controller.dart)**
|
||||
|
||||
```dart
|
||||
const appID = 'your-app-id';
|
||||
const appKey = 'your-app-key';
|
||||
const appSecret = 'your-app-secret';
|
||||
```
|
||||
|
||||
**Android 平台配置:**
|
||||
根据[其文档](https://docs.getui.com/getui/mobile/android/overview/)做好相应的Android配置,注意[多厂商](https://docs.getui.com/getui/mobile/vendor/vendor_open/)配置。然后修改以下文件内容:
|
||||
|
||||
- **[build.gradle](android/app/build.gradle)**
|
||||
|
||||
```gradle
|
||||
manifestPlaceholders = [
|
||||
GETUI_APPID : "",
|
||||
XIAOMI_APP_ID : "",
|
||||
XIAOMI_APP_KEY : "",
|
||||
MEIZU_APP_ID : "",
|
||||
MEIZU_APP_KEY : "",
|
||||
HUAWEI_APP_ID : "",
|
||||
OPPO_APP_KEY : "",
|
||||
OPPO_APP_SECRET: "",
|
||||
VIVO_APP_ID : "",
|
||||
VIVO_APP_KEY : "",
|
||||
HONOR_APP_ID : "",
|
||||
]
|
||||
```
|
||||
|
||||
#### 2. 海外地区使用 [FCM(Firebase Cloud Messaging)](https://firebase.google.com/docs/cloud-messaging)
|
||||
|
||||
根据 [FCM](https://firebase.google.com/docs/cloud-messaging) 的集成指南,替换以下文件:
|
||||
|
||||
- **[google-services.json](android/app/google-services.json)**(Android 平台)
|
||||
- **[GoogleService-Info.plist](ios/Runner/GoogleService-Info.plist)**(iOS 平台)
|
||||
- **[firebase_options.dart](openim_common/lib/src/controller/firebase_options.dart)**(Dart 项目中的 Firebase 配置)
|
||||
|
||||
### 离线推送横幅设置
|
||||
|
||||
目前SDK的设计是直接由客户端控制推送横幅的展示内容。发送消息时,设置入参[offlinePushInfo](https://github.com/openimsdk/openim-flutter-demo/blob/cc72b6d7ca5f70ca07885857beecec512f904f8c/lib/pages/chat/chat_logic.dart#L543):
|
||||
|
||||
```dart
|
||||
final offlinePushInfo = OfflinePushInfo(
|
||||
title: "填写标题",
|
||||
desc: "填写描述信息,例如消息内容",
|
||||
iOSBadgeCount: true,
|
||||
);
|
||||
// 如果不自定义offlinePushInfo,则title默认为app名称,desc默认为为“你收到了一条新消息”
|
||||
```
|
||||
|
||||
根据实际需求,完成对应的客户端和服务端配置后即可启用离线推送功能。
|
||||
|
||||
---
|
||||
|
||||
## 地图功能
|
||||
|
||||
### 配置指南
|
||||
|
||||
需要配置对应的 AMap Key。具体请参考 [AMap 文档](https://lbs.amap.com/),工程中的代码需要修改以下 Key:
|
||||
|
||||
- **[webKey](https://github.com/openimsdk/openim-flutter-demo/blob/5720a10a31a0a9bc5319775f9f4da83d6996dbfe/openim_common/lib/src/config.dart#L49)**
|
||||
- **[webServerKey](https://github.com/openimsdk/openim-flutter-demo/blob/5720a10a31a0a9bc5319775f9f4da83d6996dbfe/openim_common/lib/src/config.dart#L50)**
|
||||
|
||||
```dart
|
||||
static const webKey = 'webKey';
|
||||
static const webServerKey = 'webServerKey';
|
||||
```
|
||||
|
||||
完成配置后即可启用地图功能。
|
||||
@@ -0,0 +1,45 @@
|
||||
OpenIM Open Source License
|
||||
This repository is licensed under the GNU Affero General Public License version 3 (AGPL-3.0) and is subject to the following additional terms:
|
||||
1. Commercial Use
|
||||
1.1 Prohibition of Commercial Use
|
||||
This repository and its contents may not be used for any commercial purposes. If you wish to use OpenIM for commercial purposes, you must obtain a commercial license from the producer.
|
||||
1.2 Commercial License Application
|
||||
For commercial licensing, please contact contact@openim.io. Commercial licenses will be tailored to your specific needs and use cases to ensure that you use OpenIM legally and compliantly.
|
||||
1.3 License After Commercial Authorization
|
||||
If you have paid the relevant commercial licensing fees to the producer, you may use OpenIM in accordance with the terms of the commercial license without adhering to the provisions of AGPL-3.0. The commercial license grants you the rights to use, modify, and distribute OpenIM under specific conditions detailed in the commercial licensing agreement.
|
||||
2. LOGO and Copyright Information
|
||||
2.1 Protection of LOGO and Copyright Information
|
||||
During the use of this repository, you may not remove, modify, or hide the LOGO or copyright information within the OpenIM console or applications.
|
||||
2.2 LOGO Definition
|
||||
All unified text or icons bearing the words OpenIM or OpenIMSDK within the user interfaces of this repository are collectively referred to as the LOGO. This includes, but is not limited to, textual and iconographic identifiers in software interfaces, documentation, and promotional materials.
|
||||
3. Contributor Agreement
|
||||
As a contributor, you agree to the following terms:
|
||||
3.1 Right to Adjust the Agreement
|
||||
The producer reserves the right to adjust the strictness or leniency of the open-source agreement as necessary to ensure that the agreement aligns with the development and needs of the project.
|
||||
3.2 Commercial Use of Code
|
||||
The code you contribute may be used for commercial purposes, including but not limited to cloud business operations. By contributing, you agree that the producer has the right to use your contributions for commercial purposes without additional compensation or authorization.
|
||||
4. Other Terms
|
||||
4.1 Compliance with AGPL-3.0
|
||||
Except for the specific conditions mentioned above, all other rights and restrictions are governed by the GNU Affero General Public License version 3 (AGPL-3.0). For detailed information about the AGPL-3.0 license, please refer to the GNU AGPL-3.0 License.
|
||||
4.2 Patent Protection
|
||||
The interactive design of this product is protected by design patents. Any unauthorized copying, modification, or distribution of the interactive design constitutes infringement and will be subject to legal action.
|
||||
5. Disclaimer
|
||||
This software is provided "as is," without any form of express or implied warranty, including but not limited to warranties of merchantability, fitness for a particular purpose, or non-infringement. Users assume all risks associated with the use of this software.
|
||||
6. Contact Information
|
||||
For any licensing-related questions or to obtain a commercial license, please contact contact@openim.io.
|
||||
|
||||
GNU Affero General Public License Version 3 (AGPL-3.0)
|
||||
© 2024 OpenIMSDK
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
@@ -0,0 +1,257 @@
|
||||
<p align="center">
|
||||
<a href="https://openim.io">
|
||||
<img src="./docs/images/logo.jpg" width="60%" height="30%"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
# OpenIM Flutter 💬💻
|
||||
|
||||
<p>
|
||||
<a href="https://docs.openim.io/">OpenIM Docs</a>
|
||||
•
|
||||
<a href="https://github.com/openimsdk/open-im-server">OpenIM Server</a>
|
||||
•
|
||||
<a href="https://github.com/openimsdk/open-im-sdk-flutter">openim-sdk-flutter</a>
|
||||
•
|
||||
<a href="https://github.com/openimsdk/openim-sdk-core">openim-sdk-core</a>
|
||||
</p>
|
||||
|
||||
OpenIM provides an open-source Instant Messaging (IM) SDK for developers, serving as an alternative solution to cloud services like Twilio and Sendbird. With OpenIM, developers can build secure and reliable IM applications similar to WeChat, Zoom, and Slack.
|
||||
|
||||
This repository is based on the open-source version of the OpenIM SDK, offering an Flutter IM application. You can use this application as a reference implementation of the OpenIM SDK.
|
||||
|
||||
<p align="center">
|
||||
<img src="./docs/images/preview1.jpeg" alt="Preview" width="32%"/>
|
||||
<span style="display: inline-block; width: 16px;"></span>
|
||||
<img src="./docs/images/preview2.jpeg" alt="Preview" width="32%"/>
|
||||
</p>
|
||||
|
||||
## License :page_facing_up:
|
||||
|
||||
This repository is licensed under the GNU Affero General Public License Version 3 (AGPL-3.0) and is subject to additional terms. **Commercial use is prohibited**. For more details, see [here](./LICENSE).
|
||||
|
||||
## Development Environment
|
||||
|
||||
Before you start development, ensure that the following software is installed on your system:
|
||||
|
||||
- **Operating System**: macOS 14.6 or later
|
||||
- **Flutter**: Version 3.24.5 ([Installation Guide](https://docs.flutter.dev/get-started/install)), XCode: 15.4, Android Studio: Koala | 2024.1.1 Patch 1
|
||||
- **Git**: For version control
|
||||
|
||||
Additionally, make sure you have [deployed](https://docs.openim.io/zh-Hans/guides/gettingStarted/dockerCompose) the latest version of the OpenIM Server. After deployment, you can compile the project and connect it to your server for testing.
|
||||
|
||||
## Supported Platforms
|
||||
|
||||
This application supports the following platforms:
|
||||
|
||||
| Platform | Version | Status |
|
||||
| ------------- | --------------------- | ------ |
|
||||
| **iOS** | 13.0 and above | ✅ |
|
||||
| **Android** | minSdkVersion 24 | ✅ |
|
||||
|
||||
### Notes
|
||||
|
||||
- **Flutter**: Ensure your version meets the requirements to avoid dependency issues.
|
||||
|
||||
## Quick Start
|
||||
|
||||
Follow the steps below to set up your local development environment:
|
||||
|
||||
1. Clone the repository:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/openimsdk/openim-flutter-demo.git
|
||||
cd openim-flutter-demo
|
||||
```
|
||||
|
||||
2. Install dependencies
|
||||
|
||||
```bash
|
||||
flutter clean
|
||||
flutter pub get
|
||||
```
|
||||
|
||||
3. Modify the configuration
|
||||
|
||||
> If you have not changed the default server ports, update only the [_host](https://github.com/openimsdk/open-im-flutter-demo/blob/a309f25fdbc143e49d5ca852171ce57970871c85/openim_common/lib/src/config.dart#L59) to your server IP.
|
||||
|
||||
```dart
|
||||
static const _host = "your-server-ip or your-domain";
|
||||
```
|
||||
|
||||
4. Run the application using `flutter run` from the terminal or through your IDE.
|
||||
|
||||
5. Start developing and testing! 🎉
|
||||
|
||||
## Audio/Video Calls
|
||||
|
||||
The open-source version supports one-to-one audio and video calls. You need to first deploy and configure the [server](https://github.com/openimsdk/chat/blob/main/HOW_TO_SETUP_LIVEKIT_SERVER.md). For multi-party audio/video calls or video conferencing, please contact us at [contact@openim.io](mailto:contact@openim.io).
|
||||
|
||||
## Build 🚀
|
||||
|
||||
> This project allows building separate iOS and Android applications with some differences in the process.
|
||||
|
||||
- iOS:
|
||||
```bash
|
||||
flutter build ipa
|
||||
```
|
||||
- Android:
|
||||
```bash
|
||||
flutter build apk
|
||||
```
|
||||
|
||||
1. The build artifacts will be located in the `build` directory.
|
||||
|
||||
## Features
|
||||
|
||||
### Description
|
||||
|
||||
| Feature Module | Feature | Status |
|
||||
| -------------------------- | -------------------------------------------------------------------------------- | ------ |
|
||||
| **Account Features** | Phone number registration \ Email registration \ Verification code login | ✅ |
|
||||
| | View \ Edit personal information | ✅ |
|
||||
| | Multi-language settings | ✅ |
|
||||
| | Change password \ Forgot password | ✅ |
|
||||
| **Friend Features** | Find \ Apply \ Search \ Add \ Delete friends | ✅ |
|
||||
| | Accept \ Reject friend requests | ✅ |
|
||||
| | Friend notes | ✅ |
|
||||
| | Allow friend requests or not | ✅ |
|
||||
| | Friend list \ Friend data real-time syncing | ✅ |
|
||||
| **Blocklist** | Restrict messages | ✅ |
|
||||
| | Real-time syncing of blocklist | ✅ |
|
||||
| | Add \ Remove from blocklist | ✅ |
|
||||
| **Group Features** | Create \ Dismiss groups | ✅ |
|
||||
| | Apply to join \ Invite to join \ Leave group \ Remove members | ✅ |
|
||||
| | Group name / Avatar changes / Group data updates (notifications, real-time sync) | ✅ |
|
||||
| | Invite members to group | ✅ |
|
||||
| | Transfer group ownership | ✅ |
|
||||
| | Group owner or admin approve join requests | ✅ |
|
||||
| | Search group members | ✅ |
|
||||
| **Message Features** | Offline messages | ✅ |
|
||||
| | Roaming messages | ✅ |
|
||||
| | Multi-end messages | ✅ |
|
||||
| | Message history | ✅ |
|
||||
| | Message deletion | ✅ |
|
||||
| | Clear messages | ✅ |
|
||||
| | Copy messages | ✅ |
|
||||
| | Typing indicator in single chat | ✅ |
|
||||
| | Do Not Disturb for new messages | ✅ |
|
||||
| | Clear chat history | ✅ |
|
||||
| | New members can view group chat history | ✅ |
|
||||
| | New message reminders | ✅ |
|
||||
| | Text messages | ✅ |
|
||||
| | Image messages | ✅ |
|
||||
| | Video messages | ✅ |
|
||||
| | Emoji messages | ✅ |
|
||||
| | File messages | ✅ |
|
||||
| | Voice messages | ✅ |
|
||||
| | Contact card messages | ✅ |
|
||||
| | Location messages | ✅ |
|
||||
| | Custom messages | ✅ |
|
||||
| **Conversation** | Pin conversation | ✅ |
|
||||
| | Mark conversation as read | ✅ |
|
||||
| | Mute conversation | ✅ |
|
||||
| **REST API** | Authentication management | ✅ |
|
||||
| | User management | ✅ |
|
||||
| | Relationship chain management | ✅ |
|
||||
| | Group management | ✅ |
|
||||
| | Conversation management | ✅ |
|
||||
| | Message management | ✅ |
|
||||
| **Webhook** | Group callbacks | ✅ |
|
||||
| | Message callbacks | ✅ |
|
||||
| | Push callbacks | ✅ |
|
||||
| | Relationship callbacks | ✅ |
|
||||
| | User callbacks | ✅ |
|
||||
| **Capacity & Performance** | 10,000 friends | ✅ |
|
||||
| | 100,000-member supergroup | ✅ |
|
||||
| | Second-level syncing | ✅ |
|
||||
| | Cluster deployment | ✅ |
|
||||
| | Multi-device kick-out strategy | |
|
||||
| **Online Status** | No mutual kick-out across all platforms | ✅ |
|
||||
| | Each platform can only log in with one device | ✅ |
|
||||
| | PC, Mobile, Pad, Web, Mini Program each can log in with one device | ✅ |
|
||||
| | PC not mutually kicked, only one device total for other platforms | ✅ |
|
||||
| **Audio/Video Call** | One-to-one audio and video calls | ✅ |
|
||||
| **File Storage** | Supports private Minio deployment | ✅ |
|
||||
| | Supports public cloud services COS, OSS, Kodo, S3 | ✅ |
|
||||
| **Push** | Real-time online message push | ✅ |
|
||||
| | Offline message push, supports Getui, Firebase | ✅ |
|
||||
|
||||
For more advanced features, audio/video calls, or video conferences, please contact us at [contact@openim.io](mailto:contact@openim.io).
|
||||
|
||||
## Join Our Community :busts_in_silhouette:
|
||||
|
||||
- 🚀 [Join our Slack community](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q)
|
||||
- :eyes: [Join our WeChat group](https://openim-1253691595.cos.ap-nanjing.myqcloud.com/WechatIMG20.jpeg)
|
||||
|
||||
## FAQ
|
||||
|
||||
##### 1. Does it support multiple languages?
|
||||
|
||||
A: Support, follow the system language by default
|
||||
|
||||
##### 2. Which platforms are supported?
|
||||
|
||||
A: The demo currently supports android and ios.
|
||||
|
||||
##### 3. The debug of the android installation package can run, but the release starts with a white screen?
|
||||
|
||||
A: The release package of flutter is obfuscated by default. You can use the command: flutter build release --no -shrink. If this command is invalid, you can do the following
|
||||
|
||||
Add the following configuration to the release configuration configured in android/app/build.gradle
|
||||
|
||||
```
|
||||
release {
|
||||
minifyEnabled false
|
||||
useProguard false
|
||||
shrinkResources false
|
||||
}
|
||||
```
|
||||
|
||||
##### 4. What should I do if the code must be confused?
|
||||
|
||||
A: Add the following rules to the obfuscation rules
|
||||
|
||||
```
|
||||
-keep class io.openim.**{*;}
|
||||
-keep class open_im_sdk.**{*;}
|
||||
-keep class open_im_sdk_callback.**{*;}
|
||||
```
|
||||
|
||||
##### 5. The android installation package cannot be installed on the emulator?
|
||||
|
||||
A: Because the Demo has removed some cpu architectures, if you want to run it on the emulator, please do the following:
|
||||
|
||||
Add in android/build.gradle configuration
|
||||
|
||||
```
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86"
|
||||
}
|
||||
```
|
||||
|
||||
##### 6, ios run/build release package error
|
||||
|
||||
A: Please set the CPU architecture to arm64, and then operate as follows
|
||||
|
||||
- flutter clean
|
||||
- flutter pub get
|
||||
- cd ios
|
||||
- rm -f Podfile.lock
|
||||
- rm -rf Pods
|
||||
- pod install
|
||||
- Run Archive after connecting to the real device
|
||||
|
||||

|
||||
|
||||
##### 7. What is the minimum version number for ios to run?
|
||||
|
||||
A: 13.0
|
||||
|
||||
##### 8. Why is the map not working?
|
||||
|
||||
A: [Doc](CONFIGKEY.md)
|
||||
|
||||
##### 9. Why is offline push not working?
|
||||
|
||||
A: [Doc](CONFIGKEY.md)
|
||||
@@ -0,0 +1,253 @@
|
||||
<p align="center">
|
||||
<a href="https://openim.io">
|
||||
<img src="./docs/images/logo.jpg" width="60%" height="30%"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
# OpenIM Flutter 💬💻
|
||||
|
||||
<p>
|
||||
<a href="https://docs.openim.io/">OpenIM Docs</a>
|
||||
•
|
||||
<a href="https://github.com/openimsdk/open-im-server">OpenIM Server</a>
|
||||
•
|
||||
<a href="https://github.com/openimsdk/open-im-sdk-flutter">openim-sdk-flutter</a>
|
||||
•
|
||||
<a href="https://github.com/openimsdk/openim-sdk-core">openim-sdk-core</a>
|
||||
</p>
|
||||
OpenIM 为开发者提供开源即时通讯 SDK,作为 Twilio、Sendbird 等云服务的替代方案。借助 OpenIM,开发者可以构建安全可靠的即时通讯应用,如 WeChat、Zoom、Slack 等。
|
||||
|
||||
本仓库基于开源版 OpenIM SDK 开发,提供了一款基于 Flutter 的即时通讯应用。您可以使用此应用程序作为 OpenIM SDK 的参考实现。
|
||||
|
||||
<p align="center">
|
||||
<img src="./docs/images/preveiw1.zh-CN.jpeg" alt="预览图" width="32%"/>
|
||||
<span style="display: inline-block; width: 16px;"></span>
|
||||
<img src="./docs/images/preveiw2.zh-CN.jpeg" alt="预览图" width="32%"/>
|
||||
</p>
|
||||
|
||||
## 授权许可 :page_facing_up:
|
||||
|
||||
本仓库采用 GNU Affero 通用公共许可证第 3 版 (AGPL-3.0) 进行许可,并受以下附加条款的约束。**不允许用于商业用途**。详情请参阅 [此处](./LICENSE)。
|
||||
|
||||
## 开发环境
|
||||
|
||||
在开始开发之前,请确保您的系统已安装以下软件:
|
||||
|
||||
- **操作系统**:macOS 14.6 或更高版本
|
||||
- **Flutter**:版本 3.24.5(根据官网步骤进行[安装](https://docs.flutter.cn/get-started/install))XCode: 15.4, Android Studio: Koala | 2024.1.1 Patch 1
|
||||
- **Git**:用于代码版本控制
|
||||
|
||||
同时,您需要确保已经[部署](https://docs.openim.io/zh-Hans/guides/gettingStarted/dockerCompose)了最新版本的 OpenIM Server。接下来,您可以编译项目并连接自己的服务端进行测试。
|
||||
|
||||
## 运行环境
|
||||
|
||||
本应用支持以下操作系统版本:
|
||||
|
||||
| 操作系统 | 版本 | 状态 |
|
||||
| --------------- | ----------------- | ---- |
|
||||
| **iOS** | 13.0 及以上 | ✅ |
|
||||
| **Android** | minSdkVersion 24 | ✅ |
|
||||
|
||||
### 说明
|
||||
|
||||
- **Flutter**:确保您的版本符合要求,以避免依赖问题。
|
||||
|
||||
## 快速开始
|
||||
|
||||
按照以下步骤设置本地开发环境:
|
||||
|
||||
1. 拉取代码
|
||||
|
||||
```bash
|
||||
git clone https://github.com/openimsdk/openim-flutter-demo.git
|
||||
cd openim-flutter-demo
|
||||
```
|
||||
|
||||
2. 安装依赖
|
||||
|
||||
```bash
|
||||
flutter clean
|
||||
flutter pub get
|
||||
```
|
||||
|
||||
3. 修改配置
|
||||
|
||||
> 如果没有修改过服务端默认端口,则只需要修改[_host](https://github.com/openimsdk/open-im-flutter-demo/blob/a309f25fdbc143e49d5ca852171ce57970871c85/openim_common/lib/src/config.dart#L59)为您的服务器 ip 即可。
|
||||
|
||||
```dart
|
||||
static const _host = "your-server-ip or your-domain";
|
||||
```
|
||||
|
||||
4. 通过终端执行 `flutter run` 或者IDE的启动菜单来运行iOS/Android应用程序。
|
||||
|
||||
5. 开始开发测试! 🎉
|
||||
|
||||
## 音视频通话
|
||||
|
||||
开源版支持一对一音视频通话,并且需要先部署并配置[服务端](https://github.com/openimsdk/chat/blob/main/HOW_TO_SETUP_LIVEKIT_SERVER.md)。多人音视频通话、视频会议请联系邮箱 [contact@openim.io](mailto:contact@openim.io)
|
||||
|
||||
## 构建 🚀
|
||||
|
||||
> 该项目允许分别构建 iOS 应用程序和 Android 应用程序,但在构建过程中会有一些差异。
|
||||
|
||||
- iOS:
|
||||
```bash
|
||||
flutter build ipa
|
||||
```
|
||||
- Android:
|
||||
```bash
|
||||
flutter build apk
|
||||
```
|
||||
|
||||
构建结果将位于 `build` 目录下。
|
||||
|
||||
## 功能列表
|
||||
|
||||
### 说明
|
||||
|
||||
| 功能模块 | 功能项 | 状态 |
|
||||
| ------------------ | --------------------------------------------------------- | ---- |
|
||||
| **账号功能** | 手机号注册\邮箱注册\验证码登录 | ✅ |
|
||||
| | 个人信息查看\修改 | ✅ |
|
||||
| | 多语言设置 | ✅ |
|
||||
| | 修改密码\忘记密码 | ✅ |
|
||||
| **好友功能** | 查找\申请\搜索\添加\删除好友 | ✅ |
|
||||
| | 同意\拒绝好友申请 | ✅ |
|
||||
| | 好友备注 | ✅ |
|
||||
| | 是否允许添加好友 | ✅ |
|
||||
| | 好友列表\好友资料实时同步 | ✅ |
|
||||
| **黑名单功能** | 限制消息 | ✅ |
|
||||
| | 黑名单列表实时同步 | ✅ |
|
||||
| | 添加\移出黑名单 | ✅ |
|
||||
| **群组功能** | 创建\解散群组 | ✅ |
|
||||
| | 申请加群\邀请加群\退出群组\移除群成员 | ✅ |
|
||||
| | 群名/群头像更改/群资料变更通知和实时同步 | ✅ |
|
||||
| | 群成员邀请进群 | ✅ |
|
||||
| | 群主转让 | ✅ |
|
||||
| | 群主、管理员同意进群申请 | ✅ |
|
||||
| | 搜索群成员 | ✅ |
|
||||
| **消息功能** | 离线消息 | ✅ |
|
||||
| | 漫游消息 | ✅ |
|
||||
| | 多端消息 | ✅ |
|
||||
| | 历史消息 | ✅ |
|
||||
| | 消息删除 | ✅ |
|
||||
| | 消息清空 | ✅ |
|
||||
| | 消息复制 | ✅ |
|
||||
| | 单聊正在输入 | ✅ |
|
||||
| | 新消息勿扰 | ✅ |
|
||||
| | 清空聊天记录 | ✅ |
|
||||
| | 新成员查看群聊历史消息 | ✅ |
|
||||
| | 新消息提示 | ✅ |
|
||||
| | 文本消息 | ✅ |
|
||||
| | 图片消息 | ✅ |
|
||||
| | 视频消息 | ✅ |
|
||||
| | 表情消息 | ✅ |
|
||||
| | 文件消息 | ✅ |
|
||||
| | 语音消息 | ✅ |
|
||||
| | 名片消息 | ✅ |
|
||||
| | 地理位置消息 | ✅ |
|
||||
| | 自定义消息 | ✅ |
|
||||
| **会话功能** | 置顶会话 | ✅ |
|
||||
| | 会话已读 | ✅ |
|
||||
| | 会话免打扰 | ✅ |
|
||||
| **REST API** | 认证管理 | ✅ |
|
||||
| | 用户管理 | ✅ |
|
||||
| | 关系链管理 | ✅ |
|
||||
| | 群组管理 | ✅ |
|
||||
| | 会话管理 | ✅ |
|
||||
| | 消息管理 | ✅ |
|
||||
| **Webhook** | 群组回调 | ✅ |
|
||||
| | 消息回调 | ✅ |
|
||||
| | 推送回调 | ✅ |
|
||||
| | 关系链回调 | ✅ |
|
||||
| | 用户回调 | ✅ |
|
||||
| **容量和性能** | 1 万好友 | ✅ |
|
||||
| | 10 万人大群 | ✅ |
|
||||
| | 秒级同步 | ✅ |
|
||||
| | 集群部署 | ✅ |
|
||||
| | 互踢策略 | |
|
||||
| **在线状态** | 所有平台不互踢 | ✅ |
|
||||
| | 每个平台各只能登录一个设备 | ✅ |
|
||||
| | PC 端、移动端、Pad 端、Web 端、小程序端各只能登录一个设备 | ✅ |
|
||||
| | PC 端不互踢,其他平台总计一个设备 | ✅ |
|
||||
| **音视频通话** | 一对一音视频通话 | ✅ |
|
||||
| **文件类对象存储** | 支持私有化部署 minio | ✅ |
|
||||
| | 支持 COS、OSS、Kodo、S3 公有云 | ✅ |
|
||||
| **推送** | 消息在线实时推送 | ✅ |
|
||||
| | 消息离线推送,支持个推,Firebase | ✅ |
|
||||
|
||||
更多高级功能、音视频通话、视频会议 请联系邮箱 [contact@openim.io](mailto:contact@openim.io)
|
||||
|
||||
## 加入社区 :busts_in_silhouette:
|
||||
|
||||
- 🚀 [加入我们的 Slack 社区](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q)
|
||||
- :eyes: [加入我们的微信群](https://openim-1253691595.cos.ap-nanjing.myqcloud.com/WechatIMG20.jpeg)
|
||||
|
||||
## 常见问题
|
||||
|
||||
##### 1. 是否支持多语言?
|
||||
答:支持,默认跟随系统语言。
|
||||
|
||||
##### 2. 支持哪些平台?
|
||||
答:目前 Demo 支持 Android 和 iOS。
|
||||
|
||||
##### 3. Android 安装包的 debug 版本可以运行,但 release 启动是白屏?
|
||||
答:Flutter 的 release 包默认会进行混淆,可以使用以下命令:
|
||||
|
||||
```bash
|
||||
flutter build release --no-shrink
|
||||
```
|
||||
|
||||
如果此命令无效,可以在 android/app/build.gradle 文件的 release 配置中添加以下代码:
|
||||
|
||||
```bash
|
||||
release {
|
||||
minifyEnabled false
|
||||
useProguard false
|
||||
shrinkResources false
|
||||
}
|
||||
```
|
||||
|
||||
##### 4. 如果代码必须混淆该怎么办?
|
||||
答:在混淆规则中添加以下配置:
|
||||
|
||||
```bash
|
||||
-keep class io.openim.**{*;}
|
||||
-keep class open_im_sdk.**{*;}
|
||||
-keep class open_im_sdk_callback.**{*;}
|
||||
```
|
||||
|
||||
##### 5. Android 安装包无法安装在模拟器上?
|
||||
答:由于 Demo 移除了一些 CPU 架构,如果需要在模拟器上运行,请在 android/build.gradle 配置中添加以下内容:
|
||||
|
||||
```bash
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86"
|
||||
}
|
||||
```
|
||||
|
||||
##### 6. iOS 运行/打包 release 包时报错?
|
||||
答:请将 CPU 架构设置为 arm64,然后按以下步骤操作:
|
||||
|
||||
```bash
|
||||
执行 flutter clean
|
||||
执行 flutter pub get
|
||||
cd ios/
|
||||
rm -f Podfile.lock
|
||||
rm -rf Pods
|
||||
执行 pod install
|
||||
连接真机后运行 Archive。
|
||||
```
|
||||

|
||||
|
||||
##### 7. iOS 最低运行版本是多少?
|
||||
|
||||
答:13.0
|
||||
|
||||
##### 8. 地图为什么不能使用?
|
||||
|
||||
答: [文档](CONFIGKEY.zh-CN.md)
|
||||
|
||||
##### 9. 离线推送为什么不能使用?
|
||||
|
||||
答: [文档](CONFIGKEY.zh-CN.md)
|
||||
@@ -0,0 +1,29 @@
|
||||
# This file configures the analyzer, which statically analyzes Dart code to
|
||||
# check for errors, warnings, and lints.
|
||||
#
|
||||
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
||||
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
||||
# invoked from the command line by running `flutter analyze`.
|
||||
|
||||
# The following line activates a set of recommended lints for Flutter apps,
|
||||
# packages, and plugins designed to encourage good coding practices.
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
linter:
|
||||
# The lint rules applied to this project can be customized in the
|
||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||
# included above or to enable additional rules. A list of all available lints
|
||||
# and their documentation is published at
|
||||
# https://dart-lang.github.io/linter/lints/index.html.
|
||||
#
|
||||
# Instead of disabling a lint rule for the entire project in the
|
||||
# section below, it can also be suppressed for a single line of code
|
||||
# or a specific dart file by using the `// ignore: name_of_lint` and
|
||||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||
# producing the lint.
|
||||
rules:
|
||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
@@ -0,0 +1,13 @@
|
||||
gradle-wrapper.jar
|
||||
/.gradle
|
||||
/captures/
|
||||
/gradlew
|
||||
/gradlew.bat
|
||||
/local.properties
|
||||
GeneratedPluginRegistrant.java
|
||||
|
||||
# Remember to never publicly share your keystore.
|
||||
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
|
||||
key.properties
|
||||
**/*.keystore
|
||||
**/*.jks
|
||||
@@ -0,0 +1,188 @@
|
||||
def localProperties = new Properties()
|
||||
def localPropertiesFile = rootProject.file('local.properties')
|
||||
if (localPropertiesFile.exists()) {
|
||||
localPropertiesFile.withReader('UTF-8') { reader ->
|
||||
localProperties.load(reader)
|
||||
}
|
||||
}
|
||||
|
||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
||||
if (flutterRoot == null) {
|
||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = '1'
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = '1.0'
|
||||
}
|
||||
|
||||
subprojects { afterEvaluate { android { compileSdkVersion 34 } } }
|
||||
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
apply plugin: 'com.huawei.agconnect'
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
android {
|
||||
compileSdkVersion 34
|
||||
ndkVersion flutter.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "io.openim.flutter.demo"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 33
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
|
||||
multiDexEnabled true
|
||||
|
||||
ndk {
|
||||
abiFilters "arm64-v8a"//, "armeabi-v7a", "armeabi", "x86", "x86_64", "mips", "mips64"
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
disable "Instantiatable"
|
||||
checkReleaseBuilds false
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
manifestPlaceholders = [
|
||||
GETUI_APPID : "",
|
||||
XIAOMI_APP_ID : "",
|
||||
XIAOMI_APP_KEY : "",
|
||||
MEIZU_APP_ID : "",
|
||||
MEIZU_APP_KEY : "",
|
||||
HUAWEI_APP_ID : "",
|
||||
OPPO_APP_KEY : "",
|
||||
OPPO_APP_SECRET: "",
|
||||
VIVO_APP_ID : "",
|
||||
VIVO_APP_KEY : "",
|
||||
HONOR_APP_ID : "",
|
||||
]
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
keyAlias 'openim'
|
||||
keyPassword 'openim'
|
||||
storeFile file('./openim')
|
||||
storePassword 'openim'
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
profile {
|
||||
signingConfig signingConfigs.release
|
||||
|
||||
}
|
||||
release {
|
||||
// minifyEnabled false
|
||||
// useProguard false
|
||||
// shrinkResources false
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig signingConfigs.release
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
android.applicationVariants.all {
|
||||
variant ->
|
||||
variant.outputs.all {
|
||||
outputFileName = "F-DEMO_${versionName}(${versionCode})_${buildType.name}_${buildTime()}.apk"
|
||||
}
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
// other options here
|
||||
|
||||
/* Fix for ffmpeg-kit-react-native START */
|
||||
pickFirst 'lib/arm64-v8a/libgojni.so'
|
||||
pickFirst 'lib/armeabi-v7a/libgojni.so'
|
||||
pickFirst 'lib/x86/libgojni.so'
|
||||
pickFirst 'lib/x86_64/libgojni.so'
|
||||
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
|
||||
pickFirst 'lib/x86/libc++_shared.so'
|
||||
pickFirst 'lib/x86_64/libc++_shared.so'
|
||||
pickFirst 'lib/arm64-v8a/libc++_shared.so'
|
||||
pickFirst 'lib/arm64-v8a/libavcodec.so'
|
||||
pickFirst 'lib/arm64-v8a/libavformat.so'
|
||||
pickFirst 'lib/arm64-v8a/libavutil.so'
|
||||
pickFirst 'lib/arm64-v8a/libswscale.so'
|
||||
pickFirst 'lib/arm64-v8a/libavdevice.so'
|
||||
pickFirst 'lib/arm64-v8a/libavfilter.so'
|
||||
pickFirst 'lib/arm64-v8a/libffmpegkit.so'
|
||||
pickFirst 'lib/arm64-v8a/libffmpegkit_abidetect.so'
|
||||
pickFirst 'lib/arm64-v8a/libswresample.so'
|
||||
pickFirst 'lib/arm64-v8a/libswscale.so'
|
||||
pickFirst 'lib/x86/libavcodec.so'
|
||||
pickFirst 'lib/x86/libavformat.so'
|
||||
pickFirst 'lib/x86/libavutil.so'
|
||||
pickFirst 'lib/x86/libswscale.so'
|
||||
pickFirst 'lib/x86/libavdevice.so'
|
||||
pickFirst 'lib/x86/libavfilter.so'
|
||||
pickFirst 'lib/x86/libffmpegkit.so'
|
||||
pickFirst 'lib/x86/libffmpegkit_abidetect.so'
|
||||
pickFirst 'lib/x86/libswresample.so'
|
||||
pickFirst 'lib/x86/libswscale.so'
|
||||
pickFirst 'lib/x86_64/libavcodec.so'
|
||||
pickFirst 'lib/x86_64/libavformat.so'
|
||||
pickFirst 'lib/x86_64/libavutil.so'
|
||||
pickFirst 'lib/x86_64/libswscale.so'
|
||||
pickFirst 'lib/x86_64/libavdevice.so'
|
||||
pickFirst 'lib/x86_64/libavfilter.so'
|
||||
pickFirst 'lib/x86_64/libffmpegkit.so'
|
||||
pickFirst 'lib/x86_64/libffmpegkit_abidetect.so'
|
||||
pickFirst 'lib/x86_64/libswresample.so'
|
||||
pickFirst 'lib/x86_64/libswscale.so'
|
||||
/* Fix for ffmpeg-kit-react-native END */
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source '../..'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
|
||||
implementation 'com.getui:gtsdk:3.3.9.0'
|
||||
implementation 'com.getui:gtc:3.2.18.0'
|
||||
implementation 'com.huawei.hms:push:6.12.0.300'
|
||||
implementation 'com.huawei.agconnect:agconnect-core:1.5.2.300'
|
||||
implementation 'com.getui.opt:hwp:3.1.0'
|
||||
implementation 'com.getui.opt:xmp:3.2.0'
|
||||
implementation('com.assist-v3:oppo:3.1.0') {
|
||||
exclude group: 'commons-codec'
|
||||
}
|
||||
implementation 'com.assist-v3:vivo:3.1.0'
|
||||
implementation 'com.getui.opt:mzp:3.2.0'
|
||||
implementation 'com.getui.opt:ups:3.0.3'
|
||||
implementation 'com.getui.opt:honor:3.2.0'
|
||||
|
||||
implementation 'androidx.multidex:multidex:2.0.1'
|
||||
|
||||
implementation platform("com.google.firebase:firebase-bom:33.7.0")
|
||||
implementation "com.google.firebase:firebase-messaging" // FCM
|
||||
}
|
||||
|
||||
static def buildTime() {
|
||||
return new Date().format("MMddHHmm", TimeZone.getTimeZone("GMT+08:00"))
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "299075855003",
|
||||
"project_id": "im-fer-c3347",
|
||||
"storage_bucket": "im-fer-c3347.firebasestorage.app"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:299075855003:android:292449dc34ad498109dc3e",
|
||||
"android_client_info": {
|
||||
"package_name": "io.openim.flutter.demo"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyCw-ohvxFisvm3Yrb4kCzPBuL0YfZkzI9Q"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": []
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in D:\COMPETITION\Android Studio\Android Studio SDK/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
#指定代码的压缩级别
|
||||
-optimizationpasses 5
|
||||
|
||||
#包明不混合大小写
|
||||
-dontusemixedcaseclassnames
|
||||
|
||||
#不去忽略非公共的库类
|
||||
-dontskipnonpubliclibraryclasses
|
||||
|
||||
#优化 不优化输入的类文件
|
||||
-dontoptimize
|
||||
|
||||
#预校验
|
||||
-dontpreverify
|
||||
|
||||
#混淆时是否记录日志
|
||||
-verbose
|
||||
|
||||
# 混淆时所采用的算法
|
||||
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||
|
||||
#保护注解
|
||||
-keepattributes *Annotation*
|
||||
|
||||
# 保持哪些类不被混淆
|
||||
-keep public class * extends android.support.v4.app.Fragment
|
||||
-keep public class * extends android.app.Fragment
|
||||
-keep public class * extends android.app.Activity
|
||||
-keep public class * extends android.app.Application
|
||||
-keep public class * extends android.app.Service
|
||||
-keep public class * extends android.content.BroadcastReceiver
|
||||
-keep public class * extends android.content.ContentProvider
|
||||
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||
-keep public class * extends android.preference.Preference
|
||||
-keep public class com.android.vending.licensing.ILicensingService
|
||||
-keep public class * extends android.support.multidex.MultiDexApplication
|
||||
-keep public class * extends android.view.View
|
||||
-keep class android.support.** {*;}
|
||||
|
||||
#忽略警告
|
||||
-ignorewarnings
|
||||
|
||||
##记录生成的日志数据,gradle build时在本项目根目录输出##
|
||||
#apk 包内所有 class 的内部结构
|
||||
-dump proguard/class_files.txt
|
||||
#未混淆的类和成员
|
||||
-printseeds proguard/seeds.txt
|
||||
#列出从 apk 中删除的代码
|
||||
-printusage proguard/unused.txt
|
||||
#混淆前后的映射
|
||||
-printmapping proguard/mapping.txt
|
||||
########记录生成的日志数据,gradle build时 在本项目根目录输出-end######
|
||||
|
||||
#如果引用了v4或者v7包
|
||||
-dontwarn android.support.**
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
public *;
|
||||
}
|
||||
|
||||
####混淆保护自己项目的部分代码以及引用的第三方jar包library-end####
|
||||
|
||||
#保持 native 方法不被混淆
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
#保持自定义控件类不被混淆
|
||||
-keepclasseswithmembers class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet);
|
||||
}
|
||||
|
||||
#保持自定义控件类不被混淆
|
||||
-keepclassmembers class * extends android.app.Activity {
|
||||
public void *(android.view.View);
|
||||
}
|
||||
|
||||
-keep public class * extends android.view.View {
|
||||
public <init>(android.content.Context);
|
||||
public <init>(android.content.Context, android.util.AttributeSet);
|
||||
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||
public void set*(...);
|
||||
}
|
||||
|
||||
-keepclassmembers class * extends android.app.Activity { # 保持自定义控件类不被混淆
|
||||
public void *(android.view.View);
|
||||
}
|
||||
|
||||
#保持 Parcelable 不被混淆
|
||||
-keep class * implements android.os.Parcelable {
|
||||
public static final android.os.Parcelable$Creator *;
|
||||
}
|
||||
|
||||
#保持 Serializable 不被混淆
|
||||
-keepnames class * implements java.io.Serializable
|
||||
|
||||
#保持 Serializable 不被混淆并且enum 类也不被混淆
|
||||
-keepclassmembers class * implements java.io.Serializable {
|
||||
static final long serialVersionUID;
|
||||
private static final java.io.ObjectStreamField[] serialPersistentFields;
|
||||
!static !transient <fields>;
|
||||
!private <fields>;
|
||||
!private <methods>;
|
||||
private void writeObject(java.io.ObjectOutputStream);
|
||||
private void readObject(java.io.ObjectInputStream);
|
||||
java.lang.Object writeReplace();
|
||||
java.lang.Object readResolve();
|
||||
}
|
||||
|
||||
#保持枚举 enum 类不被混淆
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
-keepclassmembers class * {
|
||||
public void *ButtonClicked(android.view.View);
|
||||
}
|
||||
|
||||
#不混淆资源类
|
||||
-keepclassmembers class **.R$* {
|
||||
public static <fields>;
|
||||
}
|
||||
|
||||
#泛型与反射
|
||||
-keepattributes Signature
|
||||
-keepattributes EnclosingMethod
|
||||
-keepattributes *Annotation*
|
||||
-dontoptimize
|
||||
-dontpreverify
|
||||
#############################################################################################
|
||||
######################## 以上通用 ##################################
|
||||
#############################################################################################
|
||||
|
||||
#------------------ 下方是共性的排除项目 ----------------
|
||||
# 方法名中含有“JNI”字符的,认定是Java Native Interface方法,自动排除
|
||||
# 方法名中含有“JRI”字符的,认定是Java Reflection Interface方法,自动排除
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
... *JNI*(...);
|
||||
}
|
||||
|
||||
-keepclasseswithmembernames class * {
|
||||
... *JRI*(...);
|
||||
}
|
||||
|
||||
-keep class **JNI* {*;}
|
||||
|
||||
# Keep native methods
|
||||
-keepclassmembers class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
# UCrop
|
||||
-dontwarn com.yalantis.ucrop**
|
||||
-keep class com.yalantis.ucrop** { *; }
|
||||
-keep interface com.yalantis.ucrop** { *; }
|
||||
|
||||
# zxing
|
||||
-keep class com.google.zxing.** {*;}
|
||||
-dontwarn com.google.zxing.**
|
||||
|
||||
|
||||
-keep public class **.R$*{
|
||||
public static final int *;
|
||||
}
|
||||
# jpush
|
||||
-dontoptimize
|
||||
|
||||
-dontwarn cn.jpush.**
|
||||
|
||||
-keep class cn.jpush.** { *; }
|
||||
|
||||
-keep class * extends cn.jpush.android.service.JPushMessageReceiver { *; }
|
||||
|
||||
-dontwarn cn.jiguang.**
|
||||
|
||||
-keep class cn.jiguang.** { *; }
|
||||
|
||||
#腾讯 Bugly
|
||||
-dontwarn com.tencent.bugly.**
|
||||
|
||||
-keep public class com.tencent.bugly.**{*;}
|
||||
|
||||
# OpenIM
|
||||
-keep class io.openim.**{*;}
|
||||
-keep class open_im_sdk.**{*;}
|
||||
-keep class open_im_sdk_callback.**{*;}
|
||||
|
||||
#getui
|
||||
-dontwarn com.igexin.**
|
||||
-keep class com.igexin.** { *; }
|
||||
@@ -0,0 +1,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="cn.rentsoft.flutter.openim.business">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
||||
@@ -0,0 +1,160 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="cn.rentsoft.flutter.openim.business">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<!-- <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />-->
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
|
||||
<uses-permission-sdk-23 android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
<uses-permission android:name="android.permission.CALL_PHONE" />
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
|
||||
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" />
|
||||
|
||||
<uses-permission
|
||||
android:name="android.permission.BLUETOOTH"
|
||||
android:maxSdkVersion="30" />
|
||||
<uses-permission
|
||||
android:name="android.permission.BLUETOOTH_ADMIN"
|
||||
android:maxSdkVersion="30" />
|
||||
<!--From Android 12-->
|
||||
<uses-permission
|
||||
android:name="android.permission.BLUETOOTH_SCAN"
|
||||
android:usesPermissionFlags="neverForLocation" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
|
||||
<uses-permission android:name="android.permission.GET_TASKS" />
|
||||
<uses-permission android:name="android.permission.REORDER_TASKS" />
|
||||
|
||||
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
|
||||
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED"/>
|
||||
|
||||
<!-- Provide required visibility configuration for API level 30 and above -->
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<data android:scheme="https" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.DIAL" />
|
||||
<data android:scheme="tel" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.speech.RecognitionService" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<application
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="F-DEMO"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:replace="android:label">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:exported="true"
|
||||
android:hardwareAccelerated="true"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme" />
|
||||
<!-- Displays an Android View that continues showing the launch screen
|
||||
Drawable until Flutter paints its first frame, then this splash
|
||||
screen fades out. A splash screen is useful to avoid any visual
|
||||
gap between the end of Android's launch screen and the painting of
|
||||
Flutter's first frame. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.SplashScreenDrawable"
|
||||
android:resource="@drawable/launch_background" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
|
||||
<activity
|
||||
android:name="com.yalantis.ucrop.UCropActivity"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
|
||||
|
||||
<!-- If you want your foreground service to be stopped if
|
||||
your app is stopped, set android:stopWithTask to true.
|
||||
See https://developer.android.com/reference/android/R.attr#stopWithTask -->
|
||||
<service
|
||||
android:name="com.dexterous.flutterlocalnotifications.ForegroundService"
|
||||
android:exported="false"
|
||||
android:stopWithTask="false" />
|
||||
|
||||
<service
|
||||
android:name="io.openim.live.alert.flutter_openim_live_alert.services.CallService"
|
||||
android:exported="false" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileProvider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths"/>
|
||||
</provider>
|
||||
|
||||
<!-- <provider android:name="com.pichillilorenzo.flutter_inappwebview_android.InAppWebViewFileProvider"
|
||||
android:authorities="${applicationId}.flutter_inappwebview_android.fileprovider"
|
||||
android:exported="false" android:grantUriPermissions="true">
|
||||
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" />
|
||||
</provider> -->
|
||||
|
||||
|
||||
<service android:name="de.julianassmann.flutter_background.IsolateHolderService"
|
||||
android:foregroundServiceType="mediaProjection"
|
||||
tools:targetApi="q"
|
||||
android:enabled="true"
|
||||
android:exported="false"/>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,6 @@
|
||||
package cn.rentsoft.flutter.openim.business;
|
||||
|
||||
import io.flutter.embedding.android.FlutterFragmentActivity;
|
||||
|
||||
public class MainActivity extends FlutterFragmentActivity {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="?android:colorBackground" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@android:color/white" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths>
|
||||
<!-- "/" -->
|
||||
<!--<root-path
|
||||
name="rootPath"
|
||||
path="." />-->
|
||||
<!--Context.getFilesDir().-->
|
||||
<files-path
|
||||
name="filesPath"
|
||||
path="." />
|
||||
<!-- getCacheDir().-->
|
||||
<cache-path
|
||||
name="cachePath"
|
||||
path="." />
|
||||
<!-- Environment.getExternalStorageDirectory().-->
|
||||
<!-- <external-path
|
||||
name="externalPath"
|
||||
path="." />-->
|
||||
<!--Context#getExternalFilesDir(String) Context.getExternalFilesDir(null). -->
|
||||
<external-files-path
|
||||
name="externalFilesPath"
|
||||
path="." />
|
||||
<!-- Context.getExternalCacheDir(). -->
|
||||
|
||||
<external-cache-path
|
||||
name="externalCachePath"
|
||||
path="." />
|
||||
|
||||
</paths>
|
||||
@@ -0,0 +1,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="cn.rentsoft.flutter.openim.business">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
||||
@@ -0,0 +1,64 @@
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.9.23'
|
||||
repositories {
|
||||
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
|
||||
maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
|
||||
maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
|
||||
maven { url 'https://maven.aliyun.com/nexus/content/repositories/gradle-plugin' }
|
||||
maven { url "https://mvn.gt.getui.com/nexus/content/repositories/releases/" }
|
||||
maven { url 'https://developer.huawei.com/repo/' } // hms
|
||||
maven { url "https://dl.google.com/dl/android/maven2/" } // fcm
|
||||
maven {
|
||||
url 'https://maven.columbus.heytapmobi.com/repository/releases/'
|
||||
credentials {
|
||||
username 'nexus'
|
||||
password 'c0b08da17e3ec36c3870fed674a0bcb36abc2e23'
|
||||
}
|
||||
}
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath("com.android.tools:r8:8.3.37")
|
||||
classpath 'com.android.tools.build:gradle:7.3.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath 'com.google.gms:google-services:4.4.2' // fcm
|
||||
classpath 'com.huawei.agconnect:agcp:1.6.0.300' // hms
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
|
||||
maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
|
||||
maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
|
||||
maven { url 'https://maven.aliyun.com/nexus/content/repositories/gradle-plugin' }
|
||||
maven { url "https://mvn.gt.getui.com/nexus/content/repositories/releases/" }
|
||||
maven { url 'https://developer.huawei.com/repo/' } // hms
|
||||
maven { url "https://dl.google.com/dl/android/maven2/" } // fcm
|
||||
maven {
|
||||
url 'https://maven.columbus.heytapmobi.com/repository/releases/'
|
||||
credentials {
|
||||
username 'nexus'
|
||||
password 'c0b08da17e3ec36c3870fed674a0bcb36abc2e23'
|
||||
}
|
||||
}
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.buildDir = '../build'
|
||||
subprojects { afterEvaluate { android { compileSdkVersion 34 } } }
|
||||
|
||||
subprojects {
|
||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||
}
|
||||
subprojects {
|
||||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
tasks.register("clean", Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
@@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
|
||||
@@ -0,0 +1,11 @@
|
||||
include ':app'
|
||||
|
||||
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
|
||||
def properties = new Properties()
|
||||
|
||||
assert localPropertiesFile.exists()
|
||||
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
|
||||
|
||||
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
||||
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
errCode: 0,
|
||||
errMsg: "",
|
||||
data: {
|
||||
userFullInfoList: [
|
||||
{
|
||||
userID: "2380124277",
|
||||
password: "",
|
||||
account: "11002",
|
||||
phoneNumber: "",
|
||||
areaCode: "",
|
||||
nickname: "林玟书",
|
||||
englishName: "",
|
||||
faceURL: "",
|
||||
gender: 1,
|
||||
mobileAreaCode: "+86",
|
||||
mobile: "",
|
||||
telephone: "",
|
||||
level: 1,
|
||||
birth: 288316800000,
|
||||
email: "",
|
||||
order: 0,
|
||||
status: 0,
|
||||
allowAddFriend: 1,
|
||||
allowBeep: 1,
|
||||
allowVibration: 1,
|
||||
forbidden: 0,
|
||||
station: "",
|
||||
departmentList: [
|
||||
{
|
||||
departmentID: "936609157",
|
||||
departmentFaceURL: "",
|
||||
departmentName: "前端",
|
||||
departmentParentID: "1852915335",
|
||||
departmentOrder: 0,
|
||||
departmentDepartmentType: 0,
|
||||
departmentRelatedGroupID: "",
|
||||
departmentCreateTime: 1678095053014,
|
||||
memberOrder: 0,
|
||||
memberPosition: "IOS",
|
||||
memberLeader: 0,
|
||||
memberStatus: 0,
|
||||
memberEntryTime: 0,
|
||||
memberTerminationTime: 0,
|
||||
memberCreateTime: 1678095467228
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
totalNumber: 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
description: This file stores settings for Dart & Flutter DevTools.
|
||||
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
|
||||
extensions:
|
||||
|
After Width: | Height: | Size: 496 KiB |
|
After Width: | Height: | Size: 307 KiB |
|
After Width: | Height: | Size: 390 KiB |
|
After Width: | Height: | Size: 313 KiB |
|
After Width: | Height: | Size: 410 KiB |
@@ -0,0 +1 @@
|
||||
{"flutter":{"platforms":{"android":{"default":{"projectId":"im-fer-c3347","appId":"1:299075855003:android:292449dc34ad498109dc3e","fileOutput":"android/app/google-services.json"}},"ios":{"default":{"projectId":"im-fer-c3347","appId":"1:299075855003:ios:23b06300e33d984309dc3e","uploadDebugSymbols":false,"fileOutput":"ios/Runner/GoogleService-Info.plist"}},"dart":{"lib/firebase_options.dart":{"projectId":"im-fer-c3347","configurations":{"android":"1:299075855003:android:292449dc34ad498109dc3e","ios":"1:299075855003:ios:23b06300e33d984309dc3e"}}}}}}
|
||||
@@ -0,0 +1,13 @@
|
||||
flutter_icons:
|
||||
android: true
|
||||
ios: true
|
||||
remove_alpha_ios: true
|
||||
image_path: "launcher_icon/app-icon.png"
|
||||
|
||||
|
||||
|
||||
# flutter pub get
|
||||
# flutter pub run flutter_launcher_icons:main -f <your config file name here>
|
||||
|
||||
# flutter pub get
|
||||
# flutter pub run flutter_launcher_icons:main
|
||||
@@ -0,0 +1,138 @@
|
||||
flutter_native_splash:
|
||||
# This package generates native code to customize Flutter's default white native splash screen
|
||||
# with background color and splash image.
|
||||
# Customize the parameters below, and run the following command in the terminal:
|
||||
# flutter pub run flutter_native_splash:create
|
||||
# To restore Flutter's default white splash screen, run the following command in the terminal:
|
||||
# flutter pub run flutter_native_splash:remove
|
||||
|
||||
# color or background_image is the only required parameter. Use color to set the background
|
||||
# of your splash screen to a solid color. Use background_image to set the background of your
|
||||
# splash screen to a png image. This is useful for gradients. The image will be stretch to the
|
||||
# size of the app. Only one parameter can be used, color and background_image cannot both be set.
|
||||
color: "#42a5f5"
|
||||
#background_image: "assets/background.png"
|
||||
|
||||
# Optional parameters are listed below. To enable a parameter, uncomment the line by removing
|
||||
# the leading # character.
|
||||
|
||||
# The image parameter allows you to specify an image used in the splash screen. It must be a
|
||||
# png file and should be sized for 4x pixel density.
|
||||
#image: assets/splash.png
|
||||
|
||||
# The branding property allows you to specify an image used as branding in the splash screen.
|
||||
# It must be a png file. It is supported for Android, iOS and the Web. For Android 12,
|
||||
# see the Android 12 section below.
|
||||
#branding: assets/dart.png
|
||||
|
||||
# To position the branding image at the bottom of the screen you can use bottom, bottomRight,
|
||||
# and bottomLeft. The default values is bottom if not specified or specified something else.
|
||||
#branding_mode: bottom
|
||||
|
||||
# The color_dark, background_image_dark, image_dark, branding_dark are parameters that set the background
|
||||
# and image when the device is in dark mode. If they are not specified, the app will use the
|
||||
# parameters from above. If the image_dark parameter is specified, color_dark or
|
||||
# background_image_dark must be specified. color_dark and background_image_dark cannot both be
|
||||
# set.
|
||||
#color_dark: "#042a49"
|
||||
#background_image_dark: "assets/dark-background.png"
|
||||
#image_dark: assets/splash-invert.png
|
||||
#branding_dark: assets/dart_dark.png
|
||||
|
||||
# Android 12 handles the splash screen differently than previous versions. Please visit
|
||||
# https://developer.android.com/guide/topics/ui/splash-screen
|
||||
# Following are Android 12 specific parameter.
|
||||
android_12:
|
||||
# The image parameter sets the splash screen icon image. If this parameter is not specified,
|
||||
# the app's launcher icon will be used instead.
|
||||
# Please note that the splash screen will be clipped to a circle on the center of the screen.
|
||||
# App icon with an icon background: This should be 960×960 pixels, and fit within a circle
|
||||
# 640 pixels in diameter.
|
||||
# App icon without an icon background: This should be 1152×1152 pixels, and fit within a circle
|
||||
# 768 pixels in diameter.
|
||||
#image: assets/android12splash.png
|
||||
|
||||
# Splash screen background color.
|
||||
#color: "#42a5f5"
|
||||
|
||||
# App icon background color.
|
||||
#icon_background_color: "#111111"
|
||||
|
||||
# The branding property allows you to specify an image used as branding in the splash screen.
|
||||
#branding: assets/dart.png
|
||||
|
||||
# The image_dark, color_dark, icon_background_color_dark, and branding_dark set values that
|
||||
# apply when the device is in dark mode. If they are not specified, the app will use the
|
||||
# parameters from above.
|
||||
#image_dark: assets/android12splash-invert.png
|
||||
#color_dark: "#042a49"
|
||||
#icon_background_color_dark: "#eeeeee"
|
||||
|
||||
# The android, ios and web parameters can be used to disable generating a splash screen on a given
|
||||
# platform.
|
||||
#android: false
|
||||
#ios: false
|
||||
#web: false
|
||||
|
||||
# Platform specific images can be specified with the following parameters, which will override
|
||||
# the respective parameter. You may specify all, selected, or none of these parameters:
|
||||
#color_android: "#42a5f5"
|
||||
#color_dark_android: "#042a49"
|
||||
#color_ios: "#42a5f5"
|
||||
#color_dark_ios: "#042a49"
|
||||
#color_web: "#42a5f5"
|
||||
#color_dark_web: "#042a49"
|
||||
#image_android: assets/splash-android.png
|
||||
#image_dark_android: assets/splash-invert-android.png
|
||||
#image_ios: assets/splash-ios.png
|
||||
#image_dark_ios: assets/splash-invert-ios.png
|
||||
#image_web: assets/splash-web.png
|
||||
#image_dark_web: assets/splash-invert-web.png
|
||||
#background_image_android: "assets/background-android.png"
|
||||
#background_image_dark_android: "assets/dark-background-android.png"
|
||||
#background_image_ios: "assets/background-ios.png"
|
||||
#background_image_dark_ios: "assets/dark-background-ios.png"
|
||||
#background_image_web: "assets/background-web.png"
|
||||
#background_image_dark_web: "assets/dark-background-web.png"
|
||||
#branding_android: assets/brand-android.png
|
||||
#branding_dark_android: assets/dart_dark-android.png
|
||||
#branding_ios: assets/brand-ios.png
|
||||
#branding_dark_ios: assets/dart_dark-ios.png
|
||||
|
||||
# The position of the splash image can be set with android_gravity, ios_content_mode, and
|
||||
# web_image_mode parameters. All default to center.
|
||||
#
|
||||
# android_gravity can be one of the following Android Gravity (see
|
||||
# https://developer.android.com/reference/android/view/Gravity): bottom, center,
|
||||
# center_horizontal, center_vertical, clip_horizontal, clip_vertical, end, fill, fill_horizontal,
|
||||
# fill_vertical, left, right, start, or top.
|
||||
#android_gravity: center
|
||||
#
|
||||
# ios_content_mode can be one of the following iOS UIView.ContentMode (see
|
||||
# https://developer.apple.com/documentation/uikit/uiview/contentmode): scaleToFill,
|
||||
# scaleAspectFit, scaleAspectFill, center, top, bottom, left, right, topLeft, topRight,
|
||||
# bottomLeft, or bottomRight.
|
||||
#ios_content_mode: center
|
||||
#
|
||||
# web_image_mode can be one of the following modes: center, contain, stretch, and cover.
|
||||
#web_image_mode: center
|
||||
|
||||
# The screen orientation can be set in Android with the android_screen_orientation parameter.
|
||||
# Valid parameters can be found here:
|
||||
# https://developer.android.com/guide/topics/manifest/activity-element#screen
|
||||
#android_screen_orientation: sensorLandscape
|
||||
|
||||
# To hide the notification bar, use the fullscreen parameter. Has no effect in web since web
|
||||
# has no notification bar. Defaults to false.
|
||||
# NOTE: Unlike Android, iOS will not automatically show the notification bar when the app loads.
|
||||
# To show the notification bar, add the following code to your Flutter app:
|
||||
# WidgetsFlutterBinding.ensureInitialized();
|
||||
# SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom, SystemUiOverlay.top]);
|
||||
#fullscreen: true
|
||||
|
||||
# If you have changed the name(s) of your info.plist file(s), you can specify the filename(s)
|
||||
# with the info_plist_files parameter. Remove only the # characters in the three lines below,
|
||||
# do not remove any spaces:
|
||||
#info_plist_files:
|
||||
# - 'ios/Runner/Info-Debug.plist'
|
||||
# - 'ios/Runner/Info-Release.plist'
|
||||
@@ -0,0 +1,34 @@
|
||||
**/dgph
|
||||
*.mode1v3
|
||||
*.mode2v3
|
||||
*.moved-aside
|
||||
*.pbxuser
|
||||
*.perspectivev3
|
||||
**/*sync/
|
||||
.sconsign.dblite
|
||||
.tags*
|
||||
**/.vagrant/
|
||||
**/DerivedData/
|
||||
Icon?
|
||||
**/Pods/
|
||||
**/.symlinks/
|
||||
profile
|
||||
xcuserdata
|
||||
**/.generated/
|
||||
Flutter/App.framework
|
||||
Flutter/Flutter.framework
|
||||
Flutter/Flutter.podspec
|
||||
Flutter/Generated.xcconfig
|
||||
Flutter/ephemeral/
|
||||
Flutter/app.flx
|
||||
Flutter/app.zip
|
||||
Flutter/flutter_assets/
|
||||
Flutter/flutter_export_environment.sh
|
||||
ServiceDefinitions.json
|
||||
Runner/GeneratedPluginRegistrant.*
|
||||
|
||||
# Exceptions to above rules.
|
||||
!default.mode1v3
|
||||
!default.mode2v3
|
||||
!default.pbxuser
|
||||
!default.perspectivev3
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>App</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>io.flutter.flutter.app</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>App</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>12.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,2 @@
|
||||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
@@ -0,0 +1,2 @@
|
||||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.usernotifications.service</string>
|
||||
<key>NSExtensionPrincipalClass</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).NotificationService</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.cn.rentsoft.openim.flutter.rtc</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,33 @@
|
||||
import UserNotifications
|
||||
|
||||
class NotificationService: UNNotificationServiceExtension {
|
||||
var contentHandler: ((UNNotificationContent) -> Void)?
|
||||
var bestAttemptContent: UNMutableNotificationContent?
|
||||
|
||||
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
||||
self.contentHandler = contentHandler
|
||||
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
|
||||
|
||||
if let bestAttemptContent = bestAttemptContent {
|
||||
// Modify the notification content here...
|
||||
if let userInfo = request.content.userInfo as? [String: Any],
|
||||
let clientID = userInfo["clientMsgID"] as? String,
|
||||
!clientID.isEmpty == true
|
||||
{
|
||||
let key = "key"
|
||||
UserDefaults.standard.set(request.identifier, forKey: key)
|
||||
bestAttemptContent.title = "\(bestAttemptContent.title)"
|
||||
bestAttemptContent.sound = UNNotificationSound(named: .init(rawValue: "call.caf"))
|
||||
}
|
||||
contentHandler(bestAttemptContent)
|
||||
}
|
||||
}
|
||||
|
||||
override func serviceExtensionTimeWillExpire() {
|
||||
// Called just before the extension will be terminated by the system.
|
||||
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
|
||||
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
|
||||
contentHandler(bestAttemptContent)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
# Uncomment this line to define a global platform for your project
|
||||
# platform :ios, '12.0'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
project 'Runner', {
|
||||
'Debug' => :debug,
|
||||
'Profile' => :release,
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||
end
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
|
||||
end
|
||||
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_ios_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
use_modular_headers!
|
||||
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_ios_build_settings(target)
|
||||
# Start of the permission_handler configuration
|
||||
target.build_configurations.each do |config|
|
||||
|
||||
# You can enable the permissions needed here. For example to enable camera
|
||||
# permission, just remove the `#` character in front so it looks like this:
|
||||
#
|
||||
# ## dart: PermissionGroup.camera
|
||||
# 'PERMISSION_CAMERA=1'
|
||||
#
|
||||
# Preprocessor definitions can be found in: https://github.com/Baseflow/flutter-permission-handler/blob/master/permission_handler_apple/ios/Classes/PermissionHandlerEnums.h
|
||||
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
|
||||
'$(inherited)',
|
||||
|
||||
## dart: PermissionGroup.calendar
|
||||
# 'PERMISSION_EVENTS=1',
|
||||
|
||||
## dart: PermissionGroup.reminders
|
||||
# 'PERMISSION_REMINDERS=1',
|
||||
|
||||
## dart: PermissionGroup.contacts
|
||||
# 'PERMISSION_CONTACTS=1',
|
||||
|
||||
## dart: PermissionGroup.camera
|
||||
'PERMISSION_CAMERA=1',
|
||||
|
||||
## dart: PermissionGroup.microphone
|
||||
'PERMISSION_MICROPHONE=1',
|
||||
|
||||
## dart: PermissionGroup.speech
|
||||
# 'PERMISSION_SPEECH_RECOGNIZER=1',
|
||||
|
||||
## dart: PermissionGroup.photos
|
||||
'PERMISSION_PHOTOS=1',
|
||||
|
||||
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
|
||||
'PERMISSION_LOCATION=1',
|
||||
|
||||
## dart: PermissionGroup.notification
|
||||
'PERMISSION_NOTIFICATIONS=1',
|
||||
|
||||
## dart: PermissionGroup.mediaLibrary
|
||||
# 'PERMISSION_MEDIA_LIBRARY=1',
|
||||
|
||||
## dart: PermissionGroup.sensors
|
||||
# 'PERMISSION_SENSORS=1',
|
||||
|
||||
## dart: PermissionGroup.bluetooth
|
||||
# 'PERMISSION_BLUETOOTH=1',
|
||||
|
||||
## dart: PermissionGroup.appTrackingTransparency
|
||||
# 'PERMISSION_APP_TRACKING_TRANSPARENCY=1',
|
||||
|
||||
## dart: PermissionGroup.criticalAlerts
|
||||
# 'PERMISSION_CRITICAL_ALERTS=1'
|
||||
]
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,505 @@
|
||||
PODS:
|
||||
- audio_session (0.0.1):
|
||||
- Flutter
|
||||
- camera_avfoundation (0.0.1):
|
||||
- Flutter
|
||||
- connectivity_plus (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- device_info_plus (0.0.1):
|
||||
- Flutter
|
||||
- DKImagePickerController/Core (4.3.9):
|
||||
- DKImagePickerController/ImageDataManager
|
||||
- DKImagePickerController/Resource
|
||||
- DKImagePickerController/ImageDataManager (4.3.9)
|
||||
- DKImagePickerController/PhotoGallery (4.3.9):
|
||||
- DKImagePickerController/Core
|
||||
- DKPhotoGallery
|
||||
- DKImagePickerController/Resource (4.3.9)
|
||||
- DKPhotoGallery (0.0.19):
|
||||
- DKPhotoGallery/Core (= 0.0.19)
|
||||
- DKPhotoGallery/Model (= 0.0.19)
|
||||
- DKPhotoGallery/Preview (= 0.0.19)
|
||||
- DKPhotoGallery/Resource (= 0.0.19)
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Core (0.0.19):
|
||||
- DKPhotoGallery/Model
|
||||
- DKPhotoGallery/Preview
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Model (0.0.19):
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Preview (0.0.19):
|
||||
- DKPhotoGallery/Model
|
||||
- DKPhotoGallery/Resource
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Resource (0.0.19):
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- emoji_picker_flutter (0.0.1):
|
||||
- Flutter
|
||||
- ffmpeg-kit-ios-full-gpl (6.0)
|
||||
- ffmpeg_kit_flutter_full_gpl (6.0.3):
|
||||
- ffmpeg_kit_flutter_full_gpl/full-gpl (= 6.0.3)
|
||||
- Flutter
|
||||
- ffmpeg_kit_flutter_full_gpl/full-gpl (6.0.3):
|
||||
- ffmpeg-kit-ios-full-gpl (= 6.0)
|
||||
- Flutter
|
||||
- file_picker (0.0.1):
|
||||
- DKImagePickerController/PhotoGallery
|
||||
- Flutter
|
||||
- Firebase/CoreOnly (11.6.0):
|
||||
- FirebaseCore (~> 11.6.0)
|
||||
- Firebase/Messaging (11.6.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseMessaging (~> 11.6.0)
|
||||
- firebase_core (3.10.0):
|
||||
- Firebase/CoreOnly (= 11.6.0)
|
||||
- Flutter
|
||||
- firebase_messaging (15.2.0):
|
||||
- Firebase/Messaging (= 11.6.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- FirebaseCore (11.6.0):
|
||||
- FirebaseCoreInternal (~> 11.6.0)
|
||||
- GoogleUtilities/Environment (~> 8.0)
|
||||
- GoogleUtilities/Logger (~> 8.0)
|
||||
- FirebaseCoreInternal (11.6.0):
|
||||
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
||||
- FirebaseInstallations (11.6.0):
|
||||
- FirebaseCore (~> 11.6.0)
|
||||
- GoogleUtilities/Environment (~> 8.0)
|
||||
- GoogleUtilities/UserDefaults (~> 8.0)
|
||||
- PromisesObjC (~> 2.4)
|
||||
- FirebaseMessaging (11.6.0):
|
||||
- FirebaseCore (~> 11.6.0)
|
||||
- FirebaseInstallations (~> 11.0)
|
||||
- GoogleDataTransport (~> 10.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
||||
- GoogleUtilities/Environment (~> 8.0)
|
||||
- GoogleUtilities/Reachability (~> 8.0)
|
||||
- GoogleUtilities/UserDefaults (~> 8.0)
|
||||
- nanopb (~> 3.30910.0)
|
||||
- Flutter (1.0.0)
|
||||
- flutter_image_compress_common (1.0.0):
|
||||
- Flutter
|
||||
- Mantle
|
||||
- SDWebImage
|
||||
- SDWebImageWebPCoder
|
||||
- flutter_keyboard_visibility (0.0.1):
|
||||
- Flutter
|
||||
- flutter_local_notifications (0.0.1):
|
||||
- Flutter
|
||||
- flutter_native_splash (2.4.3):
|
||||
- Flutter
|
||||
- flutter_new_badger (0.0.1):
|
||||
- Flutter
|
||||
- flutter_openim_sdk (0.0.1):
|
||||
- Flutter
|
||||
- OpenIMSDKCore (= 3.8.3)
|
||||
- flutter_webrtc (0.11.3):
|
||||
- Flutter
|
||||
- WebRTC-SDK (= 125.6422.04)
|
||||
- geolocator_apple (1.2.0):
|
||||
- Flutter
|
||||
- getuiflut (0.0.1):
|
||||
- Flutter
|
||||
- GTSDK
|
||||
- GoogleDataTransport (10.1.0):
|
||||
- nanopb (~> 3.30910.0)
|
||||
- PromisesObjC (~> 2.4)
|
||||
- GoogleUtilities/AppDelegateSwizzler (8.0.2):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Network
|
||||
- GoogleUtilities/Privacy
|
||||
- GoogleUtilities/Environment (8.0.2):
|
||||
- GoogleUtilities/Privacy
|
||||
- GoogleUtilities/Logger (8.0.2):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/Privacy
|
||||
- GoogleUtilities/Network (8.0.2):
|
||||
- GoogleUtilities/Logger
|
||||
- "GoogleUtilities/NSData+zlib"
|
||||
- GoogleUtilities/Privacy
|
||||
- GoogleUtilities/Reachability
|
||||
- "GoogleUtilities/NSData+zlib (8.0.2)":
|
||||
- GoogleUtilities/Privacy
|
||||
- GoogleUtilities/Privacy (8.0.2)
|
||||
- GoogleUtilities/Reachability (8.0.2):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Privacy
|
||||
- GoogleUtilities/UserDefaults (8.0.2):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Privacy
|
||||
- GTCommonSDK (3.1.7.0):
|
||||
- ZXSDK
|
||||
- GTSDK (3.0.9.0):
|
||||
- GTCommonSDK (> 3.0.9.0)
|
||||
- image_cropper (0.0.4):
|
||||
- Flutter
|
||||
- TOCropViewController (~> 2.6.1)
|
||||
- image_gallery_saver_plus (0.0.1):
|
||||
- Flutter
|
||||
- image_picker_ios (0.0.1):
|
||||
- Flutter
|
||||
- just_audio (0.0.1):
|
||||
- Flutter
|
||||
- libwebp (1.3.2):
|
||||
- libwebp/demux (= 1.3.2)
|
||||
- libwebp/mux (= 1.3.2)
|
||||
- libwebp/sharpyuv (= 1.3.2)
|
||||
- libwebp/webp (= 1.3.2)
|
||||
- libwebp/demux (1.3.2):
|
||||
- libwebp/webp
|
||||
- libwebp/mux (1.3.2):
|
||||
- libwebp/demux
|
||||
- libwebp/sharpyuv (1.3.2)
|
||||
- libwebp/webp (1.3.2):
|
||||
- libwebp/sharpyuv
|
||||
- livekit_client (2.2.5):
|
||||
- Flutter
|
||||
- WebRTC-SDK (= 125.6422.04)
|
||||
- local_auth_darwin (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- Mantle (2.2.0):
|
||||
- Mantle/extobjc (= 2.2.0)
|
||||
- Mantle/extobjc (2.2.0)
|
||||
- map_launcher (0.0.1):
|
||||
- Flutter
|
||||
- media_kit_libs_ios_video (1.0.4):
|
||||
- Flutter
|
||||
- media_kit_native_event_loop (1.0.0):
|
||||
- Flutter
|
||||
- media_kit_video (0.0.1):
|
||||
- Flutter
|
||||
- MTBBarcodeScanner (5.0.11)
|
||||
- Mute (0.6.1)
|
||||
- nanopb (3.30910.0):
|
||||
- nanopb/decode (= 3.30910.0)
|
||||
- nanopb/encode (= 3.30910.0)
|
||||
- nanopb/decode (3.30910.0)
|
||||
- nanopb/encode (3.30910.0)
|
||||
- open_filex (0.0.2):
|
||||
- Flutter
|
||||
- OpenIMSDKCore (3.8.3)
|
||||
- package_info_plus (0.4.5):
|
||||
- Flutter
|
||||
- path_provider_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- permission_handler_apple (9.3.0):
|
||||
- Flutter
|
||||
- photo_manager (2.0.0):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- PromisesObjC (2.4.0)
|
||||
- qr_code_scanner_plus (0.2.6):
|
||||
- Flutter
|
||||
- MTBBarcodeScanner
|
||||
- record_darwin (1.0.0):
|
||||
- Flutter
|
||||
- scan (0.0.1):
|
||||
- Flutter
|
||||
- screen_brightness_ios (0.1.0):
|
||||
- Flutter
|
||||
- SDWebImage (5.20.0):
|
||||
- SDWebImage/Core (= 5.20.0)
|
||||
- SDWebImage/Core (5.20.0)
|
||||
- SDWebImageWebPCoder (0.14.6):
|
||||
- libwebp (~> 1.0)
|
||||
- SDWebImage/Core (~> 5.17)
|
||||
- sensors_plus (0.0.1):
|
||||
- Flutter
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- sound_mode (0.0.1):
|
||||
- Flutter
|
||||
- Mute (~> 0.6.0)
|
||||
- sqflite_darwin (0.0.4):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- SwiftyGif (5.4.5)
|
||||
- TOCropViewController (2.6.1)
|
||||
- url_launcher_ios (0.0.1):
|
||||
- Flutter
|
||||
- vibration (1.7.5):
|
||||
- Flutter
|
||||
- video_compress (0.3.0):
|
||||
- Flutter
|
||||
- video_player_avfoundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- volume_controller (0.0.1):
|
||||
- Flutter
|
||||
- wakelock_plus (0.0.1):
|
||||
- Flutter
|
||||
- WebRTC-SDK (125.6422.04)
|
||||
- webview_flutter_wkwebview (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- ZXSDK (3.3.2)
|
||||
|
||||
DEPENDENCIES:
|
||||
- audio_session (from `.symlinks/plugins/audio_session/ios`)
|
||||
- camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`)
|
||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/darwin`)
|
||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||
- emoji_picker_flutter (from `.symlinks/plugins/emoji_picker_flutter/ios`)
|
||||
- ffmpeg_kit_flutter_full_gpl (from `.symlinks/plugins/ffmpeg_kit_flutter_full_gpl/ios`)
|
||||
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
||||
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
|
||||
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_image_compress_common (from `.symlinks/plugins/flutter_image_compress_common/ios`)
|
||||
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
|
||||
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
|
||||
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
||||
- flutter_new_badger (from `.symlinks/plugins/flutter_new_badger/ios`)
|
||||
- flutter_openim_sdk (from `.symlinks/plugins/flutter_openim_sdk/ios`)
|
||||
- flutter_webrtc (from `.symlinks/plugins/flutter_webrtc/ios`)
|
||||
- geolocator_apple (from `.symlinks/plugins/geolocator_apple/ios`)
|
||||
- getuiflut (from `.symlinks/plugins/getuiflut/ios`)
|
||||
- image_cropper (from `.symlinks/plugins/image_cropper/ios`)
|
||||
- image_gallery_saver_plus (from `.symlinks/plugins/image_gallery_saver_plus/ios`)
|
||||
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
||||
- just_audio (from `.symlinks/plugins/just_audio/ios`)
|
||||
- livekit_client (from `.symlinks/plugins/livekit_client/ios`)
|
||||
- local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`)
|
||||
- map_launcher (from `.symlinks/plugins/map_launcher/ios`)
|
||||
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
|
||||
- media_kit_native_event_loop (from `.symlinks/plugins/media_kit_native_event_loop/ios`)
|
||||
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
|
||||
- open_filex (from `.symlinks/plugins/open_filex/ios`)
|
||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||
- photo_manager (from `.symlinks/plugins/photo_manager/ios`)
|
||||
- qr_code_scanner_plus (from `.symlinks/plugins/qr_code_scanner_plus/ios`)
|
||||
- record_darwin (from `.symlinks/plugins/record_darwin/ios`)
|
||||
- scan (from `.symlinks/plugins/scan/ios`)
|
||||
- screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`)
|
||||
- sensors_plus (from `.symlinks/plugins/sensors_plus/ios`)
|
||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||
- sound_mode (from `.symlinks/plugins/sound_mode/ios`)
|
||||
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
|
||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||
- vibration (from `.symlinks/plugins/vibration/ios`)
|
||||
- video_compress (from `.symlinks/plugins/video_compress/ios`)
|
||||
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
|
||||
- volume_controller (from `.symlinks/plugins/volume_controller/ios`)
|
||||
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
|
||||
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- DKImagePickerController
|
||||
- DKPhotoGallery
|
||||
- ffmpeg-kit-ios-full-gpl
|
||||
- Firebase
|
||||
- FirebaseCore
|
||||
- FirebaseCoreInternal
|
||||
- FirebaseInstallations
|
||||
- FirebaseMessaging
|
||||
- GoogleDataTransport
|
||||
- GoogleUtilities
|
||||
- GTCommonSDK
|
||||
- GTSDK
|
||||
- libwebp
|
||||
- Mantle
|
||||
- MTBBarcodeScanner
|
||||
- Mute
|
||||
- nanopb
|
||||
- OpenIMSDKCore
|
||||
- PromisesObjC
|
||||
- SDWebImage
|
||||
- SDWebImageWebPCoder
|
||||
- SwiftyGif
|
||||
- TOCropViewController
|
||||
- WebRTC-SDK
|
||||
- ZXSDK
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
audio_session:
|
||||
:path: ".symlinks/plugins/audio_session/ios"
|
||||
camera_avfoundation:
|
||||
:path: ".symlinks/plugins/camera_avfoundation/ios"
|
||||
connectivity_plus:
|
||||
:path: ".symlinks/plugins/connectivity_plus/darwin"
|
||||
device_info_plus:
|
||||
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||
emoji_picker_flutter:
|
||||
:path: ".symlinks/plugins/emoji_picker_flutter/ios"
|
||||
ffmpeg_kit_flutter_full_gpl:
|
||||
:path: ".symlinks/plugins/ffmpeg_kit_flutter_full_gpl/ios"
|
||||
file_picker:
|
||||
:path: ".symlinks/plugins/file_picker/ios"
|
||||
firebase_core:
|
||||
:path: ".symlinks/plugins/firebase_core/ios"
|
||||
firebase_messaging:
|
||||
:path: ".symlinks/plugins/firebase_messaging/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_image_compress_common:
|
||||
:path: ".symlinks/plugins/flutter_image_compress_common/ios"
|
||||
flutter_keyboard_visibility:
|
||||
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
|
||||
flutter_local_notifications:
|
||||
:path: ".symlinks/plugins/flutter_local_notifications/ios"
|
||||
flutter_native_splash:
|
||||
:path: ".symlinks/plugins/flutter_native_splash/ios"
|
||||
flutter_new_badger:
|
||||
:path: ".symlinks/plugins/flutter_new_badger/ios"
|
||||
flutter_openim_sdk:
|
||||
:path: ".symlinks/plugins/flutter_openim_sdk/ios"
|
||||
flutter_webrtc:
|
||||
:path: ".symlinks/plugins/flutter_webrtc/ios"
|
||||
geolocator_apple:
|
||||
:path: ".symlinks/plugins/geolocator_apple/ios"
|
||||
getuiflut:
|
||||
:path: ".symlinks/plugins/getuiflut/ios"
|
||||
image_cropper:
|
||||
:path: ".symlinks/plugins/image_cropper/ios"
|
||||
image_gallery_saver_plus:
|
||||
:path: ".symlinks/plugins/image_gallery_saver_plus/ios"
|
||||
image_picker_ios:
|
||||
:path: ".symlinks/plugins/image_picker_ios/ios"
|
||||
just_audio:
|
||||
:path: ".symlinks/plugins/just_audio/ios"
|
||||
livekit_client:
|
||||
:path: ".symlinks/plugins/livekit_client/ios"
|
||||
local_auth_darwin:
|
||||
:path: ".symlinks/plugins/local_auth_darwin/darwin"
|
||||
map_launcher:
|
||||
:path: ".symlinks/plugins/map_launcher/ios"
|
||||
media_kit_libs_ios_video:
|
||||
:path: ".symlinks/plugins/media_kit_libs_ios_video/ios"
|
||||
media_kit_native_event_loop:
|
||||
:path: ".symlinks/plugins/media_kit_native_event_loop/ios"
|
||||
media_kit_video:
|
||||
:path: ".symlinks/plugins/media_kit_video/ios"
|
||||
open_filex:
|
||||
:path: ".symlinks/plugins/open_filex/ios"
|
||||
package_info_plus:
|
||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||
path_provider_foundation:
|
||||
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
||||
permission_handler_apple:
|
||||
:path: ".symlinks/plugins/permission_handler_apple/ios"
|
||||
photo_manager:
|
||||
:path: ".symlinks/plugins/photo_manager/ios"
|
||||
qr_code_scanner_plus:
|
||||
:path: ".symlinks/plugins/qr_code_scanner_plus/ios"
|
||||
record_darwin:
|
||||
:path: ".symlinks/plugins/record_darwin/ios"
|
||||
scan:
|
||||
:path: ".symlinks/plugins/scan/ios"
|
||||
screen_brightness_ios:
|
||||
:path: ".symlinks/plugins/screen_brightness_ios/ios"
|
||||
sensors_plus:
|
||||
:path: ".symlinks/plugins/sensors_plus/ios"
|
||||
shared_preferences_foundation:
|
||||
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
||||
sound_mode:
|
||||
:path: ".symlinks/plugins/sound_mode/ios"
|
||||
sqflite_darwin:
|
||||
:path: ".symlinks/plugins/sqflite_darwin/darwin"
|
||||
url_launcher_ios:
|
||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||
vibration:
|
||||
:path: ".symlinks/plugins/vibration/ios"
|
||||
video_compress:
|
||||
:path: ".symlinks/plugins/video_compress/ios"
|
||||
video_player_avfoundation:
|
||||
:path: ".symlinks/plugins/video_player_avfoundation/darwin"
|
||||
volume_controller:
|
||||
:path: ".symlinks/plugins/volume_controller/ios"
|
||||
wakelock_plus:
|
||||
:path: ".symlinks/plugins/wakelock_plus/ios"
|
||||
webview_flutter_wkwebview:
|
||||
:path: ".symlinks/plugins/webview_flutter_wkwebview/darwin"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
audio_session: 088d2483ebd1dc43f51d253d4a1c517d9a2e7207
|
||||
camera_avfoundation: dd002b0330f4981e1bbcb46ae9b62829237459a4
|
||||
connectivity_plus: 18382e7311ba19efcaee94442b23b32507b20695
|
||||
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
|
||||
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
||||
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
||||
emoji_picker_flutter: fe2e6151c5b548e975d546e6eeb567daf0962a58
|
||||
ffmpeg-kit-ios-full-gpl: 80adc341962e55ef709e36baa8ed9a70cf4ea62b
|
||||
ffmpeg_kit_flutter_full_gpl: 8d15c14c0c3aba616fac04fe44b3d27d02e3c330
|
||||
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
|
||||
Firebase: 374a441a91ead896215703a674d58cdb3e9d772b
|
||||
firebase_core: feb37e79f775c2bd08dd35e02d83678291317e10
|
||||
firebase_messaging: e2f0ba891b1509668c07f5099761518a5af8fe3c
|
||||
FirebaseCore: 48b0dd707581cf9c1a1220da68223fb0a562afaa
|
||||
FirebaseCoreInternal: d98ab91e2d80a56d7b246856a8885443b302c0c2
|
||||
FirebaseInstallations: efc0946fc756e4d22d8113f7c761948120322e8c
|
||||
FirebaseMessaging: e1aca1fcc23e8b9eddb0e33f375ff90944623021
|
||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||
flutter_image_compress_common: ec1d45c362c9d30a3f6a0426c297f47c52007e3e
|
||||
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
|
||||
flutter_local_notifications: df98d66e515e1ca797af436137b4459b160ad8c9
|
||||
flutter_native_splash: f71420956eb811e6d310720fee915f1d42852e7a
|
||||
flutter_new_badger: e632df3f84b5bbd7f3b37b8122f105edf1b483b3
|
||||
flutter_openim_sdk: 170b54f6d5c7c287bd9079436d3280197ea27556
|
||||
flutter_webrtc: 75b868e4f9e817c7a9a42ca4b6169063de4eec9f
|
||||
geolocator_apple: 9bcea1918ff7f0062d98345d238ae12718acfbc1
|
||||
getuiflut: 8628ba2b64a738a847a07d2b67e0ac305778e2ee
|
||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||
GTCommonSDK: d3299839818ffc2629bf587e096256a7cd0f0dcc
|
||||
GTSDK: 4392fb9f02e370c8dd3e77fa51ffc511b5ac1ac1
|
||||
image_cropper: a3291c624a953049bc6a02e1f8c8ceb162a24b25
|
||||
image_gallery_saver_plus: 782ade975fe6a4600b53e7c1983e3a2979d1e9e5
|
||||
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
|
||||
just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa
|
||||
libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009
|
||||
livekit_client: 9c8080879256a0fb16da13c9be4845248209d896
|
||||
local_auth_darwin: 66e40372f1c29f383a314c738c7446e2f7fdadc3
|
||||
Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
|
||||
map_launcher: e325db1261d029ff33e08e03baccffe09593ffea
|
||||
media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1
|
||||
media_kit_native_event_loop: e6b2ab20cf0746eb1c33be961fcf79667304fa2a
|
||||
media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e
|
||||
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
|
||||
Mute: 20135a96076f140cc82bfc8b810e2d6150d8ec7e
|
||||
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
||||
open_filex: 6e26e659846ec990262224a12ef1c528bb4edbe4
|
||||
OpenIMSDKCore: 6fba8ae1b25e33e2d5cfb16f4eab934f3d7c5ee8
|
||||
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
|
||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
|
||||
photo_manager: ff695c7a1dd5bc379974953a2b5c0a293f7c4c8a
|
||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||
qr_code_scanner_plus: 3bfe4deb7f28996a63a2a580819d49dae80d5ed3
|
||||
record_darwin: 3b1a8e7d5c0cbf45ad6165b4d83a6ca643d929c3
|
||||
scan: aea35bb4aa59ccc8839c576a18cd57c7d492cc86
|
||||
screen_brightness_ios: 715ca807df953bf676d339f11464e438143ee625
|
||||
SDWebImage: 73c6079366fea25fa4bb9640d5fb58f0893facd8
|
||||
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
|
||||
sensors_plus: 7229095999f30740798f0eeef5cd120357a8f4f2
|
||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||
sound_mode: ef0072f20e7306c1c371984a443156e39be092d5
|
||||
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
|
||||
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
||||
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
|
||||
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
||||
vibration: 7d883d141656a1c1a6d8d238616b2042a51a1241
|
||||
video_compress: fce97e4fb1dfd88175aa07d2ffc8a2f297f87fbe
|
||||
video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3
|
||||
volume_controller: 531ddf792994285c9b17f9d8a7e4dcdd29b3eae9
|
||||
wakelock_plus: 373cfe59b235a6dd5837d0fb88791d2f13a90d56
|
||||
WebRTC-SDK: c3d69a87e7185fad3568f6f3cff7c9ac5890acf3
|
||||
webview_flutter_wkwebview: 0982481e3d9c78fd5c6f62a002fcd24fc791f1e4
|
||||
ZXSDK: 786338c0a18e98e03eda00699c3bfd2700b97117
|
||||
|
||||
PODFILE CHECKSUM: 3003a7d95e8a59d1b52038824bad0a4b90bc52ca
|
||||
|
||||
COCOAPODS: 1.15.2
|
||||
@@ -0,0 +1,823 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 54;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||
173BE1932A67E13300A4D9A9 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 173BE1922A67E13300A4D9A9 /* NotificationService.swift */; };
|
||||
173BE1972A67E13300A4D9A9 /* NotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 173BE1902A67E13200A4D9A9 /* NotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
55219944D9DA5CD2EDF4C8C3 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E6DB8DF4A03CB207F9CF840 /* Pods_Runner.framework */; };
|
||||
701BDEDF100D82D14BF9DC9C /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B4A878B5BD9E53AD68260EDF /* GoogleService-Info.plist */; };
|
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
173BE1952A67E13300A4D9A9 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 173BE18F2A67E13200A4D9A9;
|
||||
remoteInfo = NotificationService;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
173BE19C2A67E13300A4D9A9 /* Embed Foundation Extensions */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
173BE1972A67E13300A4D9A9 /* NotificationService.appex in Embed Foundation Extensions */,
|
||||
);
|
||||
name = "Embed Foundation Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
);
|
||||
name = "Embed Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
1706ED5D2AC2917E004FD73C /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = "<group>"; };
|
||||
1706ED5E2AC2917E004FD73C /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LaunchScreen.strings"; sourceTree = "<group>"; };
|
||||
173BE1902A67E13200A4D9A9 /* NotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
173BE1922A67E13300A4D9A9 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; };
|
||||
173BE1942A67E13300A4D9A9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
173BE19D2A67E16300A4D9A9 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
||||
173BE19E2A67E18F00A4D9A9 /* NotificationService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NotificationService.entitlements; sourceTree = "<group>"; };
|
||||
176C056E2AA9AAA20006F277 /* ReplayKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ReplayKit.framework; path = System/Library/Frameworks/ReplayKit.framework; sourceTree = SDKROOT; };
|
||||
1E6DB8DF4A03CB207F9CF840 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
5BB0FD4B4EF99F87CBCBE59A /* 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 = "<group>"; };
|
||||
5FF4A91C6E553A5915EBB93E /* 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 = "<group>"; };
|
||||
6BADC328EF88768955F7D03E /* 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 = "<group>"; };
|
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
B4A878B5BD9E53AD68260EDF /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
173BE18D2A67E13200A4D9A9 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
55219944D9DA5CD2EDF4C8C3 /* Pods_Runner.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
173BE1912A67E13300A4D9A9 /* NotificationService */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
173BE19E2A67E18F00A4D9A9 /* NotificationService.entitlements */,
|
||||
173BE1922A67E13300A4D9A9 /* NotificationService.swift */,
|
||||
173BE1942A67E13300A4D9A9 /* Info.plist */,
|
||||
);
|
||||
path = NotificationService;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */,
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */,
|
||||
);
|
||||
name = Flutter;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146E51CF9000F007C117D = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9740EEB11CF90186004384FC /* Flutter */,
|
||||
97C146F01CF9000F007C117D /* Runner */,
|
||||
173BE1912A67E13300A4D9A9 /* NotificationService */,
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
9B5BFEE13D0DBBAB9D1487A5 /* Pods */,
|
||||
C68B34A13F8B54B6D32ED277 /* Frameworks */,
|
||||
B4A878B5BD9E53AD68260EDF /* GoogleService-Info.plist */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146EF1CF9000F007C117D /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97C146EE1CF9000F007C117D /* Runner.app */,
|
||||
173BE1902A67E13200A4D9A9 /* NotificationService.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146F01CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
173BE19D2A67E16300A4D9A9 /* Runner.entitlements */,
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
||||
97C147021CF9000F007C117D /* Info.plist */,
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
|
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
|
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
|
||||
);
|
||||
path = Runner;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9B5BFEE13D0DBBAB9D1487A5 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6BADC328EF88768955F7D03E /* Pods-Runner.debug.xcconfig */,
|
||||
5BB0FD4B4EF99F87CBCBE59A /* Pods-Runner.release.xcconfig */,
|
||||
5FF4A91C6E553A5915EBB93E /* Pods-Runner.profile.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C68B34A13F8B54B6D32ED277 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
176C056E2AA9AAA20006F277 /* ReplayKit.framework */,
|
||||
1E6DB8DF4A03CB207F9CF840 /* Pods_Runner.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
173BE18F2A67E13200A4D9A9 /* NotificationService */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 173BE1982A67E13300A4D9A9 /* Build configuration list for PBXNativeTarget "NotificationService" */;
|
||||
buildPhases = (
|
||||
173BE18C2A67E13200A4D9A9 /* Sources */,
|
||||
173BE18D2A67E13200A4D9A9 /* Frameworks */,
|
||||
173BE18E2A67E13200A4D9A9 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = NotificationService;
|
||||
productName = NotificationService;
|
||||
productReference = 173BE1902A67E13200A4D9A9 /* NotificationService.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
97C146ED1CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
6D26B612E7CE061D882E2C44 /* [CP] Check Pods Manifest.lock */,
|
||||
9740EEB61CF901F6004384FC /* Run Script */,
|
||||
97C146EA1CF9000F007C117D /* Sources */,
|
||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||
97C146EC1CF9000F007C117D /* Resources */,
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
173BE19C2A67E13300A4D9A9 /* Embed Foundation Extensions */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
D93E9AE0652B0DF2EDE1169B /* [CP] Embed Pods Frameworks */,
|
||||
170C561DA4A2C0A19C3C3AB0 /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
173BE1962A67E13300A4D9A9 /* PBXTargetDependency */,
|
||||
);
|
||||
name = Runner;
|
||||
productName = Runner;
|
||||
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
97C146E61CF9000F007C117D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1430;
|
||||
LastUpgradeCheck = 1510;
|
||||
ORGANIZATIONNAME = "";
|
||||
TargetAttributes = {
|
||||
173BE18F2A67E13200A4D9A9 = {
|
||||
CreatedOnToolsVersion = 14.3;
|
||||
};
|
||||
97C146ED1CF9000F007C117D = {
|
||||
CreatedOnToolsVersion = 7.3.1;
|
||||
LastSwiftMigration = 1100;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
|
||||
compatibilityVersion = "Xcode 9.3";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
"zh-Hans",
|
||||
);
|
||||
mainGroup = 97C146E51CF9000F007C117D;
|
||||
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
97C146ED1CF9000F007C117D /* Runner */,
|
||||
173BE18F2A67E13200A4D9A9 /* NotificationService */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
173BE18E2A67E13200A4D9A9 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
97C146EC1CF9000F007C117D /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
|
||||
701BDEDF100D82D14BF9DC9C /* GoogleService-Info.plist in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
170C561DA4A2C0A19C3C3AB0 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
|
||||
);
|
||||
name = "Thin Binary";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
|
||||
};
|
||||
6D26B612E7CE061D882E2C44 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
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";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Run Script";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
||||
};
|
||||
D93E9AE0652B0DF2EDE1169B /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
173BE18C2A67E13200A4D9A9 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
173BE1932A67E13300A4D9A9 /* NotificationService.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
97C146EA1CF9000F007C117D /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
173BE1962A67E13300A4D9A9 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 173BE18F2A67E13200A4D9A9 /* NotificationService */;
|
||||
targetProxy = 173BE1952A67E13300A4D9A9 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
97C146FB1CF9000F007C117D /* Base */,
|
||||
1706ED5D2AC2917E004FD73C /* zh-Hans */,
|
||||
);
|
||||
name = Main.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
97C147001CF9000F007C117D /* Base */,
|
||||
1706ED5E2AC2917E004FD73C /* zh-Hans */,
|
||||
);
|
||||
name = LaunchScreen.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
173BE1992A67E13300A4D9A9 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 17;
|
||||
DEVELOPMENT_TEAM = V57RT7LMFH;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = NotificationService;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.3.1;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.openim.flutter.demoo.NotificationService;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
173BE19A2A67E13300A4D9A9 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 17;
|
||||
DEVELOPMENT_TEAM = V57RT7LMFH;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = NotificationService;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.3.1;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.openim.flutter.demoo.NotificationService;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
173BE19B2A67E13300A4D9A9 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 17;
|
||||
DEVELOPMENT_TEAM = V57RT7LMFH;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = NotificationService;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.3.1;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.openim.flutter.demoo.NotificationService;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
};
|
||||
name = Profile;
|
||||
};
|
||||
249021D3217E4FDB00AE95B9 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SUPPORTED_PLATFORMS = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Profile;
|
||||
};
|
||||
249021D4217E4FDB00AE95B9 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = V57RT7LMFH;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.8.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.openim.flutter.demoo;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Profile;
|
||||
};
|
||||
97C147031CF9000F007C117D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
97C147041CF9000F007C117D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SUPPORTED_PLATFORMS = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
97C147061CF9000F007C117D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = V57RT7LMFH;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.8.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.openim.flutter.demoo;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
97C147071CF9000F007C117D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = V57RT7LMFH;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.8.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.openim.flutter.demoo;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
173BE1982A67E13300A4D9A9 /* Build configuration list for PBXNativeTarget "NotificationService" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
173BE1992A67E13300A4D9A9 /* Debug */,
|
||||
173BE19A2A67E13300A4D9A9 /* Release */,
|
||||
173BE19B2A67E13300A4D9A9 /* Profile */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
97C147031CF9000F007C117D /* Debug */,
|
||||
97C147041CF9000F007C117D /* Release */,
|
||||
249021D3217E4FDB00AE95B9 /* Profile */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
97C147061CF9000F007C117D /* Debug */,
|
||||
97C147071CF9000F007C117D /* Release */,
|
||||
249021D4217E4FDB00AE95B9 /* Profile */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 97C146E61CF9000F007C117D /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1510"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Profile"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,74 @@
|
||||
import UIKit
|
||||
import Flutter
|
||||
import FirebaseCore
|
||||
|
||||
@main
|
||||
@objc class AppDelegate: FlutterAppDelegate {
|
||||
|
||||
var replayKitChannel: FlutterMethodChannel! = nil
|
||||
var observeTimer: Timer?
|
||||
var hasEmittedFirstSample = false;
|
||||
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||
) -> Bool {
|
||||
guard let controller = window?.rootViewController as? FlutterViewController else {
|
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
}
|
||||
|
||||
FirebaseApp.configure()
|
||||
|
||||
replayKitChannel = FlutterMethodChannel(name: "io.livekit.example.flutter/replaykit-channel",binaryMessenger: controller.binaryMessenger)
|
||||
|
||||
replayKitChannel.setMethodCallHandler({
|
||||
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
|
||||
self.handleReplayKitFromFlutter(result: result, call:call)
|
||||
})
|
||||
|
||||
GeneratedPluginRegistrant.register(with: self)
|
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
}
|
||||
|
||||
func handleReplayKitFromFlutter(result:FlutterResult, call: FlutterMethodCall){
|
||||
switch (call.method) {
|
||||
case "startReplayKit":
|
||||
self.hasEmittedFirstSample = false
|
||||
let group=UserDefaults(suiteName: "group.io.livekit.example.flutter")
|
||||
group!.set(false, forKey: "closeReplayKitFromNative")
|
||||
group!.set(false, forKey: "closeReplayKitFromFlutter")
|
||||
self.observeReplayKitStateChanged()
|
||||
break
|
||||
case "closeReplayKit":
|
||||
let group=UserDefaults(suiteName: "group.io.livekit.example.flutter")
|
||||
group!.set(true,forKey: "closeReplayKitFromFlutter")
|
||||
result(true)
|
||||
break
|
||||
default:
|
||||
return result(FlutterMethodNotImplemented)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func observeReplayKitStateChanged(){
|
||||
if (self.observeTimer != nil) {
|
||||
return
|
||||
}
|
||||
|
||||
let group=UserDefaults(suiteName: "group.io.livekit.example.flutter")
|
||||
self.observeTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { (timer) in
|
||||
let closeReplayKitFromNative=group!.bool(forKey: "closeReplayKitFromNative")
|
||||
let hasSampleBroadcast=group!.bool(forKey: "hasSampleBroadcast")
|
||||
|
||||
if (closeReplayKitFromNative) {
|
||||
self.hasEmittedFirstSample = false
|
||||
self.replayKitChannel.invokeMethod("closeReplayKitFromNative", arguments: true)
|
||||
} else if (hasSampleBroadcast) {
|
||||
if (!self.hasEmittedFirstSample) {
|
||||
self.hasEmittedFirstSample = true
|
||||
self.replayKitChannel.invokeMethod("hasSampleBroadcast", arguments: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "83.5x83.5",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "Icon-App-1024x1024@1x.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 579 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 970 B |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 68 B |
|
After Width: | Height: | Size: 68 B |
|
After Width: | Height: | Size: 68 B |
@@ -0,0 +1,5 @@
|
||||
# Launch Screen Assets
|
||||
|
||||
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="LaunchImage" width="168" height="185"/>
|
||||
</resources>
|
||||
</document>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Flutter View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>API_KEY</key>
|
||||
<string>AIzaSyC0BhV-mo84LvOuqWf2bS966jlf0f8mh74</string>
|
||||
<key>GCM_SENDER_ID</key>
|
||||
<string>299075855003</string>
|
||||
<key>PLIST_VERSION</key>
|
||||
<string>1</string>
|
||||
<key>BUNDLE_ID</key>
|
||||
<string>io.openim.flutter.base</string>
|
||||
<key>PROJECT_ID</key>
|
||||
<string>im-fer-c3347</string>
|
||||
<key>STORAGE_BUCKET</key>
|
||||
<string>im-fer-c3347.firebasestorage.app</string>
|
||||
<key>IS_ADS_ENABLED</key>
|
||||
<false></false>
|
||||
<key>IS_ANALYTICS_ENABLED</key>
|
||||
<false></false>
|
||||
<key>IS_APPINVITE_ENABLED</key>
|
||||
<true></true>
|
||||
<key>IS_GCM_ENABLED</key>
|
||||
<true></true>
|
||||
<key>IS_SIGNIN_ENABLED</key>
|
||||
<true></true>
|
||||
<key>GOOGLE_APP_ID</key>
|
||||
<string>1:299075855003:ios:23b06300e33d984309dc3e</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<array>
|
||||
<string>zh-CN</string>
|
||||
<string>en-US</string>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>F-DEMO</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSApplicationQueriesSchemes</key>
|
||||
<array>
|
||||
<string>comgooglemaps</string>
|
||||
<string>baidumap</string>
|
||||
<string>iosamap</string>
|
||||
<string>waze</string>
|
||||
<string>yandexmaps</string>
|
||||
<string>yandexnavi</string>
|
||||
<string>citymapper</string>
|
||||
<string>mapswithme</string>
|
||||
<string>osmandmaps</string>
|
||||
<string>dgis</string>
|
||||
<string>qqmap</string>
|
||||
<string>here-location</string>
|
||||
</array>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>NSAppleMusicUsageDescription</key>
|
||||
<string>请点击“好”以允许访问。若不允许,你将无法给好友发送或者上传本地相册图片及视频内容。</string>
|
||||
<key>NSBluetoothAlwaysUsageDescription</key>
|
||||
<string>App requires access to Bluetooth to connect to devices.</string>
|
||||
<key>NSBluetoothPeripheralUsageDescription</key>
|
||||
<string>App requires access to Bluetooth to communicate with peripheral devices.</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>请点击“好”以允许访问。若不允许,你将无法使用拍照、录制视频、扫一扫等功能。</string>
|
||||
<key>NSFaceIDUsageDescription</key>
|
||||
<string>请点击“好”以允许访问。若不允许,你将无法使用Touch ID 或 Face ID解锁功能。</string>
|
||||
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
||||
<string>请点击“好”以允许访问。若不允许,你将无法使用聊天时发送定位等功能。</string>
|
||||
<key>NSLocationAlwaysUsageDescription</key>
|
||||
<string>请点击“好”以允许访问。若不允许,你将无法使用聊天时发送定位等功能。</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string>请点击“好”以允许访问。若不允许,你将无法使用聊天时发送定位等功能。</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>请点击“好”以允许访问。若不允许,你将无法使用视频通话、发送语音消息或录制视频等功能。</string>
|
||||
<key>NSPhotoLibraryAddUsageDescription</key>
|
||||
<string>请点击“好”以允许访问。若不允许,你将无法给好友发送或者上传本地相册图片及视频内容。</string>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>请点击“好”以允许访问。若不允许,你将无法给好友发送或者上传本地相册图片及视频内容。</string>
|
||||
<key>RTCAppGroupIdentifier</key>
|
||||
<string>group.cn.rentsoft.openim.flutter.rtc</string>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIRequiresFullScreen</key>
|
||||
<true/>
|
||||
<key>UIStatusBarHidden</key>
|
||||
<false/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
</array>
|
||||
<key>UISupportsDocumentBrowser</key>
|
||||
<true/>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>io.flutter.embedded_views_preview</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1 @@
|
||||
#import "GeneratedPluginRegistrant.h"
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>aps-environment</key>
|
||||
<string>development</string>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.cn.rentsoft.openim.flutter.rtc</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
|
After Width: | Height: | Size: 68 KiB |
@@ -0,0 +1,113 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:openim_common/openim_common.dart';
|
||||
|
||||
import 'core/controller/im_controller.dart';
|
||||
import 'routes/app_pages.dart';
|
||||
import 'widgets/app_view.dart';
|
||||
|
||||
class ChatApp extends StatelessWidget {
|
||||
const ChatApp({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppView(
|
||||
builder: (locale, builder) => GetMaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
enableLog: true,
|
||||
builder: builder,
|
||||
logWriterCallback: Logger.print,
|
||||
translations: TranslationService(),
|
||||
localizationsDelegates: const [
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
fallbackLocale: TranslationService.fallbackLocale,
|
||||
locale: locale,
|
||||
localeResolutionCallback: (locale, list) {
|
||||
Get.locale ??= locale;
|
||||
return locale;
|
||||
},
|
||||
supportedLocales: const [Locale('zh', 'CN'), Locale('en', 'US')],
|
||||
getPages: AppPages.routes,
|
||||
initialBinding: InitBinding(),
|
||||
initialRoute: AppRoutes.splash,
|
||||
theme: _themeData,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
ThemeData get _themeData => ThemeData.light().copyWith(
|
||||
scaffoldBackgroundColor: Colors.grey.shade50,
|
||||
canvasColor: Colors.white,
|
||||
appBarTheme: const AppBarTheme(color: Colors.white),
|
||||
textSelectionTheme: const TextSelectionThemeData().copyWith(cursorColor: Colors.blue),
|
||||
checkboxTheme: const CheckboxThemeData().copyWith(
|
||||
checkColor: WidgetStateProperty.all(Colors.white),
|
||||
fillColor: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.disabled)) {
|
||||
return Colors.grey;
|
||||
}
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return Colors.blue;
|
||||
}
|
||||
return Colors.white;
|
||||
}),
|
||||
side: BorderSide(color: Colors.grey.shade500, width: 1),
|
||||
),
|
||||
dialogTheme: const DialogTheme().copyWith(
|
||||
backgroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: ButtonStyle(
|
||||
shape: WidgetStatePropertyAll(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(4.0),
|
||||
),
|
||||
),
|
||||
textStyle: WidgetStatePropertyAll(
|
||||
TextStyle(
|
||||
fontSize: 16.sp,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
foregroundColor: const WidgetStatePropertyAll(Colors.black),
|
||||
),
|
||||
),
|
||||
progressIndicatorTheme: const ProgressIndicatorThemeData()
|
||||
.copyWith(color: Colors.white, linearTrackColor: Colors.grey[300], circularTrackColor: Colors.grey[300]),
|
||||
cupertinoOverrideTheme: CupertinoThemeData(
|
||||
brightness: Brightness.light,
|
||||
primaryColor: CupertinoColors.systemBlue,
|
||||
barBackgroundColor: Colors.white,
|
||||
applyThemeToAll: true,
|
||||
textTheme: const CupertinoTextThemeData().copyWith(
|
||||
navActionTextStyle: TextStyle(color: CupertinoColors.label, fontSize: 17.sp),
|
||||
actionTextStyle: TextStyle(color: CupertinoColors.systemBlue, fontSize: 17.sp),
|
||||
textStyle: TextStyle(color: CupertinoColors.label, fontSize: 17.sp),
|
||||
navLargeTitleTextStyle: TextStyle(color: CupertinoColors.label, fontSize: 20.sp),
|
||||
navTitleTextStyle: TextStyle(color: CupertinoColors.label, fontSize: 17.sp),
|
||||
pickerTextStyle: TextStyle(color: CupertinoColors.label, fontSize: 17.sp),
|
||||
tabLabelTextStyle: TextStyle(color: CupertinoColors.label, fontSize: 17.sp),
|
||||
dateTimePickerTextStyle: TextStyle(color: CupertinoColors.label, fontSize: 17.sp),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class InitBinding extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
Get.put<IMController>(IMController());
|
||||
Get.put<PushController>(PushController());
|
||||
Get.put<CacheController>(CacheController());
|
||||
Get.put<DownloadController>(DownloadController());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:audio_session/audio_session.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_new_badger/flutter_new_badger.dart';
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:flutter_openim_sdk/flutter_openim_sdk.dart' as im;
|
||||
import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:just_audio/just_audio.dart';
|
||||
import 'package:openim/core/im_callback.dart';
|
||||
import 'package:openim_common/openim_common.dart';
|
||||
import 'package:sound_mode/sound_mode.dart';
|
||||
import 'package:sound_mode/utils/ringer_mode_statuses.dart';
|
||||
import 'package:vibration/vibration.dart';
|
||||
|
||||
import '../../utils/upgrade_manager.dart';
|
||||
import 'im_controller.dart';
|
||||
|
||||
class AppController extends GetxController with UpgradeManger {
|
||||
var isRunningBackground = false;
|
||||
|
||||
final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
|
||||
|
||||
final initializationSettingsAndroid = const AndroidInitializationSettings('@mipmap/ic_launcher');
|
||||
|
||||
final DarwinInitializationSettings initializationSettingsDarwin = const DarwinInitializationSettings(
|
||||
requestAlertPermission: false,
|
||||
requestBadgePermission: false,
|
||||
requestSoundPermission: false,
|
||||
);
|
||||
|
||||
RTCBridge? get rtcBridge => PackageBridge.rtcBridge;
|
||||
|
||||
bool get shouldMuted =>
|
||||
rtcBridge?.hasConnection == true ||
|
||||
Get.find<IMController>().imSdkStatusSubject.values.last.status != IMSdkStatus.syncEnded;
|
||||
|
||||
final _ring = 'assets/audio/message_ring.wav';
|
||||
final _audioPlayer = AudioPlayer();
|
||||
final configuration = const AudioSessionConfiguration(
|
||||
avAudioSessionCategory: AVAudioSessionCategory.ambient,
|
||||
avAudioSessionCategoryOptions: AVAudioSessionCategoryOptions.mixWithOthers,
|
||||
androidAudioFocusGainType: AndroidAudioFocusGainType.gainTransientMayDuck,
|
||||
androidAudioAttributes: AndroidAudioAttributes(
|
||||
contentType: AndroidAudioContentType.sonification,
|
||||
usage: AndroidAudioUsage.notification,
|
||||
),
|
||||
);
|
||||
late AudioSession session;
|
||||
|
||||
late BaseDeviceInfo deviceInfo;
|
||||
|
||||
final clientConfigMap = <String, dynamic>{}.obs;
|
||||
|
||||
Future<void> runningBackground(bool run) async {
|
||||
Logger.print('-----App running background : $run-------------');
|
||||
|
||||
if (isRunningBackground && !run) {}
|
||||
isRunningBackground = run;
|
||||
if (!run) {
|
||||
_cancelAllNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onInit() async {
|
||||
_initPlayer();
|
||||
final initializationSettings = InitializationSettings(
|
||||
android: initializationSettingsAndroid,
|
||||
iOS: initializationSettingsDarwin,
|
||||
);
|
||||
await flutterLocalNotificationsPlugin.initialize(
|
||||
initializationSettings,
|
||||
onDidReceiveNotificationResponse: (notificationResponse) {},
|
||||
);
|
||||
|
||||
autoCheckVersionUpgrade();
|
||||
super.onInit();
|
||||
}
|
||||
|
||||
void _requestPermissions() {
|
||||
flutterLocalNotificationsPlugin
|
||||
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
|
||||
?.requestNotificationsPermission();
|
||||
flutterLocalNotificationsPlugin
|
||||
.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()
|
||||
?.requestPermissions(
|
||||
alert: true,
|
||||
badge: true,
|
||||
sound: true,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> showNotification(im.Message message, {bool showNotification = true}) async {
|
||||
if (_isGlobalNotDisturb() ||
|
||||
message.attachedInfoElem?.notSenderNotificationPush == true ||
|
||||
message.contentType == im.MessageType.typing ||
|
||||
message.sendID == OpenIM.iMManager.userID ||
|
||||
(message.contentType! >= 1000 && message.contentType != 1400)) return;
|
||||
|
||||
var sourceID = message.sessionType == ConversationType.single ? message.sendID : message.groupID;
|
||||
if (sourceID != null && message.sessionType != null) {
|
||||
var i = await OpenIM.iMManager.conversationManager.getOneConversation(
|
||||
sourceID: sourceID,
|
||||
sessionType: message.sessionType!,
|
||||
);
|
||||
if (i.recvMsgOpt != 0) return;
|
||||
}
|
||||
|
||||
if (showNotification) {
|
||||
promptSoundOrNotification(message.seq!);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> promptSoundOrNotification(int seq) async {
|
||||
if (Get.find<IMController>().imSdkStatusSubject.values.lastOrNull?.status != IMSdkStatus.syncEnded) {
|
||||
return;
|
||||
}
|
||||
if (!isRunningBackground) {
|
||||
_playMessageSound();
|
||||
} else {
|
||||
if (Platform.isAndroid) {
|
||||
final id = seq;
|
||||
|
||||
const androidPlatformChannelSpecifics = AndroidNotificationDetails('chat', 'OpenIM聊天消息',
|
||||
channelDescription: '来自OpenIM的信息', importance: Importance.max, priority: Priority.high, ticker: 'ticker');
|
||||
const NotificationDetails platformChannelSpecifics =
|
||||
NotificationDetails(android: androidPlatformChannelSpecifics);
|
||||
await flutterLocalNotificationsPlugin.show(id, '您收到了一条新消息', '消息内容:.....', platformChannelSpecifics,
|
||||
payload: '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _cancelAllNotifications() async {
|
||||
await flutterLocalNotificationsPlugin.cancelAll();
|
||||
}
|
||||
|
||||
Future<void> _startForegroundService() async {
|
||||
await getAppInfo();
|
||||
const androidPlatformChannelSpecifics = AndroidNotificationDetails('pro', 'OpenIM后台进程',
|
||||
channelDescription: '保证app能收到信息', importance: Importance.max, priority: Priority.high, ticker: 'ticker');
|
||||
|
||||
await flutterLocalNotificationsPlugin
|
||||
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
|
||||
?.startForegroundService(1, packageInfo!.appName, '正在运行...',
|
||||
notificationDetails: androidPlatformChannelSpecifics, payload: '');
|
||||
}
|
||||
|
||||
Future<void> _stopForegroundService() async {
|
||||
await flutterLocalNotificationsPlugin
|
||||
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
|
||||
?.stopForegroundService();
|
||||
}
|
||||
|
||||
void showBadge(count) {
|
||||
OpenIM.iMManager.messageManager.setAppBadge(count);
|
||||
|
||||
if (count == 0) {
|
||||
removeBadge();
|
||||
PushController.resetBadge();
|
||||
} else {
|
||||
FlutterNewBadger.setBadge(count);
|
||||
PushController.setBadge(count);
|
||||
}
|
||||
}
|
||||
|
||||
void removeBadge() {
|
||||
FlutterNewBadger.removeBadge();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
closeSubject();
|
||||
_audioPlayer.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
Locale? getLocale() {
|
||||
var local = Get.locale;
|
||||
var index = DataSp.getLanguage() ?? 0;
|
||||
switch (index) {
|
||||
case 1:
|
||||
local = const Locale('zh', 'CN');
|
||||
break;
|
||||
case 2:
|
||||
local = const Locale('en', 'US');
|
||||
break;
|
||||
}
|
||||
return local;
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
queryClientConfig();
|
||||
_getDeviceInfo();
|
||||
_cancelAllNotifications();
|
||||
super.onReady();
|
||||
}
|
||||
|
||||
bool _isGlobalNotDisturb() {
|
||||
bool isRegistered = Get.isRegistered<IMController>();
|
||||
if (isRegistered) {
|
||||
var logic = Get.find<IMController>();
|
||||
return logic.userInfo.value.globalRecvMsgOpt == 2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void _initPlayer() async {
|
||||
session = await AudioSession.instance;
|
||||
await session.configure(configuration);
|
||||
|
||||
_audioPlayer.setAsset(_ring, package: 'openim_common');
|
||||
_audioPlayer.playerStateStream.listen((state) {
|
||||
switch (state.processingState) {
|
||||
case ProcessingState.idle:
|
||||
case ProcessingState.loading:
|
||||
case ProcessingState.buffering:
|
||||
case ProcessingState.ready:
|
||||
break;
|
||||
case ProcessingState.completed:
|
||||
_stopMessageSound();
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _playMessageSound() async {
|
||||
if (shouldMuted) {
|
||||
return;
|
||||
}
|
||||
bool isRegistered = Get.isRegistered<IMController>();
|
||||
bool isAllowVibration = true;
|
||||
bool isAllowBeep = true;
|
||||
if (isRegistered) {
|
||||
var logic = Get.find<IMController>();
|
||||
isAllowVibration = logic.userInfo.value.allowVibration == 1;
|
||||
isAllowBeep = logic.userInfo.value.allowBeep == 1;
|
||||
}
|
||||
|
||||
RingerModeStatus ringerStatus = await SoundMode.ringerModeStatus;
|
||||
|
||||
Logger.print('System ringer status: $ringerStatus, user is allow beep: $isAllowBeep',
|
||||
fileName: 'app_controller.dart');
|
||||
|
||||
if (!_audioPlayer.playerState.playing &&
|
||||
isAllowBeep &&
|
||||
(ringerStatus == RingerModeStatus.normal || ringerStatus == RingerModeStatus.unknown)) {
|
||||
await session.setActive(true);
|
||||
_audioPlayer.setAsset(_ring, package: 'openim_common');
|
||||
_audioPlayer.setLoopMode(LoopMode.off);
|
||||
_audioPlayer.setVolume(1.0);
|
||||
_audioPlayer.play();
|
||||
}
|
||||
|
||||
if (isAllowVibration &&
|
||||
(ringerStatus == RingerModeStatus.normal ||
|
||||
ringerStatus == RingerModeStatus.vibrate ||
|
||||
ringerStatus == RingerModeStatus.unknown)) {
|
||||
if (await Vibration.hasVibrator() == true) {
|
||||
Vibration.vibrate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _stopMessageSound() async {
|
||||
if (_audioPlayer.playerState.playing) {
|
||||
_audioPlayer.stop();
|
||||
}
|
||||
await session.setActive(false);
|
||||
}
|
||||
|
||||
void _getDeviceInfo() async {
|
||||
final deviceInfoPlugin = DeviceInfoPlugin();
|
||||
deviceInfo = await deviceInfoPlugin.deviceInfo;
|
||||
}
|
||||
|
||||
Future queryClientConfig() async {
|
||||
final map = await Apis.getClientConfig();
|
||||
clientConfigMap.assignAll(map);
|
||||
|
||||
return clientConfigMap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:openim_common/openim_common.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:openim_live/openim_live.dart';
|
||||
|
||||
import '../im_callback.dart';
|
||||
|
||||
class IMController extends GetxController with IMCallback, OpenIMLive {
|
||||
late Rx<UserFullInfo> userInfo;
|
||||
late String atAllTag;
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
super.close();
|
||||
onCloseLive();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
@override
|
||||
void onInit() async {
|
||||
super.onInit();
|
||||
onInitLive();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => initOpenIM());
|
||||
}
|
||||
|
||||
void initOpenIM() async {
|
||||
final initialized = await OpenIM.iMManager.initSDK(
|
||||
platformID: IMUtils.getPlatform(),
|
||||
apiAddr: Config.imApiUrl,
|
||||
wsAddr: Config.imWsUrl,
|
||||
dataDir: Config.cachePath,
|
||||
logLevel: Config.logLevel,
|
||||
logFilePath: Config.cachePath,
|
||||
listener: OnConnectListener(
|
||||
onConnecting: () {
|
||||
imSdkStatus(IMSdkStatus.connecting);
|
||||
},
|
||||
onConnectFailed: (code, error) {
|
||||
imSdkStatus(IMSdkStatus.connectionFailed);
|
||||
},
|
||||
onConnectSuccess: () {
|
||||
imSdkStatus(IMSdkStatus.connectionSucceeded);
|
||||
},
|
||||
onKickedOffline: kickedOffline,
|
||||
onUserTokenExpired: kickedOffline,
|
||||
onUserTokenInvalid: userTokenInvalid,
|
||||
),
|
||||
);
|
||||
|
||||
OpenIM.iMManager
|
||||
..setUploadLogsListener(OnUploadLogsListener(onUploadProgress: uploadLogsProgress))
|
||||
..userManager.setUserListener(OnUserListener(
|
||||
onSelfInfoUpdated: (u) {
|
||||
selfInfoUpdated(u);
|
||||
|
||||
userInfo.update((val) {
|
||||
val?.nickname = u.nickname;
|
||||
val?.faceURL = u.faceURL;
|
||||
|
||||
val?.remark = u.remark;
|
||||
val?.ex = u.ex;
|
||||
val?.globalRecvMsgOpt = u.globalRecvMsgOpt;
|
||||
});
|
||||
},
|
||||
onUserStatusChanged: userStausChanged))
|
||||
..messageManager.setAdvancedMsgListener(OnAdvancedMsgListener(
|
||||
onRecvC2CReadReceipt: recvC2CMessageReadReceipt,
|
||||
onRecvNewMessage: recvNewMessage,
|
||||
onNewRecvMessageRevoked: recvMessageRevoked,
|
||||
onRecvOfflineNewMessage: recvOfflineMessage,
|
||||
onRecvOnlineOnlyMessage: (msg) {
|
||||
if (msg.isCustomType) {
|
||||
final data = msg.customElem!.data;
|
||||
final map = jsonDecode(data!);
|
||||
final customType = map['customType'];
|
||||
if (customType == CustomMessageType.callingInvite ||
|
||||
customType == CustomMessageType.callingAccept ||
|
||||
customType == CustomMessageType.callingReject ||
|
||||
customType == CustomMessageType.callingCancel ||
|
||||
customType == CustomMessageType.callingHungup) {
|
||||
final signaling = SignalingInfo(invitation: InvitationInfo.fromJson(map['data']));
|
||||
signaling.userID = signaling.invitation?.inviterUserID;
|
||||
|
||||
switch (customType) {
|
||||
case CustomMessageType.callingInvite:
|
||||
receiveNewInvitation(signaling);
|
||||
break;
|
||||
case CustomMessageType.callingAccept:
|
||||
inviteeAccepted(signaling);
|
||||
break;
|
||||
case CustomMessageType.callingReject:
|
||||
inviteeRejected(signaling);
|
||||
break;
|
||||
case CustomMessageType.callingCancel:
|
||||
invitationCancelled(signaling);
|
||||
break;
|
||||
case CustomMessageType.callingHungup:
|
||||
beHangup(signaling);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
))
|
||||
..messageManager.setMsgSendProgressListener(OnMsgSendProgressListener(
|
||||
onProgress: progressCallback,
|
||||
))
|
||||
..messageManager.setCustomBusinessListener(OnCustomBusinessListener(
|
||||
onRecvCustomBusinessMessage: recvCustomBusinessMessage,
|
||||
))
|
||||
..friendshipManager.setFriendshipListener(OnFriendshipListener(
|
||||
onBlackAdded: blacklistAdded,
|
||||
onBlackDeleted: blacklistDeleted,
|
||||
onFriendApplicationAccepted: friendApplicationAccepted,
|
||||
onFriendApplicationAdded: friendApplicationAdded,
|
||||
onFriendApplicationDeleted: friendApplicationDeleted,
|
||||
onFriendApplicationRejected: friendApplicationRejected,
|
||||
onFriendInfoChanged: friendInfoChanged,
|
||||
onFriendAdded: friendAdded,
|
||||
onFriendDeleted: friendDeleted,
|
||||
))
|
||||
..conversationManager.setConversationListener(OnConversationListener(
|
||||
onConversationChanged: conversationChanged,
|
||||
onNewConversation: newConversation,
|
||||
onTotalUnreadMessageCountChanged: totalUnreadMsgCountChanged,
|
||||
onInputStatusChanged: inputStateChanged,
|
||||
onSyncServerFailed: (reInstall) {
|
||||
imSdkStatus(IMSdkStatus.syncFailed, reInstall: reInstall ?? false);
|
||||
},
|
||||
onSyncServerFinish: (reInstall) {
|
||||
imSdkStatus(IMSdkStatus.syncEnded, reInstall: reInstall ?? false);
|
||||
if (Platform.isAndroid) {
|
||||
Permissions.request([Permission.systemAlertWindow]);
|
||||
}
|
||||
},
|
||||
onSyncServerStart: (reInstall) {
|
||||
imSdkStatus(IMSdkStatus.syncStart, reInstall: reInstall ?? false);
|
||||
},
|
||||
onSyncServerProgress: (progress) {
|
||||
imSdkStatus(IMSdkStatus.syncProgress, progress: progress);
|
||||
}))
|
||||
..groupManager.setGroupListener(OnGroupListener(
|
||||
onGroupApplicationAccepted: groupApplicationAccepted,
|
||||
onGroupApplicationAdded: groupApplicationAdded,
|
||||
onGroupApplicationDeleted: groupApplicationDeleted,
|
||||
onGroupApplicationRejected: groupApplicationRejected,
|
||||
onGroupInfoChanged: groupInfoChanged,
|
||||
onGroupMemberAdded: groupMemberAdded,
|
||||
onGroupMemberDeleted: groupMemberDeleted,
|
||||
onGroupMemberInfoChanged: groupMemberInfoChanged,
|
||||
onJoinedGroupAdded: joinedGroupAdded,
|
||||
onJoinedGroupDeleted: joinedGroupDeleted,
|
||||
));
|
||||
|
||||
initializedSubject.sink.add(initialized);
|
||||
}
|
||||
|
||||
Future login(String userID, String token) async {
|
||||
try {
|
||||
var user = await OpenIM.iMManager.login(
|
||||
userID: userID,
|
||||
token: token,
|
||||
defaultValue: () async => UserInfo(userID: userID),
|
||||
);
|
||||
ApiService().setToken(token);
|
||||
userInfo = UserFullInfo.fromJson(user.toJson()).obs;
|
||||
_queryMyFullInfo();
|
||||
_queryAtAllTag();
|
||||
} catch (e, s) {
|
||||
Logger.print('e: $e s:$s');
|
||||
await _handleLoginRepeatError(e);
|
||||
|
||||
return Future.error(e, s);
|
||||
}
|
||||
}
|
||||
|
||||
Future logout() {
|
||||
return OpenIM.iMManager.logout();
|
||||
}
|
||||
|
||||
void _queryAtAllTag() async {
|
||||
atAllTag = OpenIM.iMManager.conversationManager.atAllTag;
|
||||
}
|
||||
|
||||
void _queryMyFullInfo() async {
|
||||
final data = await Apis.queryMyFullInfo();
|
||||
if (data is UserFullInfo) {
|
||||
userInfo.update((val) {
|
||||
val?.allowAddFriend = data.allowAddFriend;
|
||||
val?.allowBeep = data.allowBeep;
|
||||
val?.allowVibration = data.allowVibration;
|
||||
val?.nickname = data.nickname;
|
||||
val?.faceURL = data.faceURL;
|
||||
val?.phoneNumber = data.phoneNumber;
|
||||
val?.email = data.email;
|
||||
val?.birth = data.birth;
|
||||
val?.gender = data.gender;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_handleLoginRepeatError(e) async {
|
||||
if (e is PlatformException && (e.code == "13002" || e.code == '1507')) {
|
||||
await logout();
|
||||
await DataSp.removeLoginCertificate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:openim_common/openim_common.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
|
||||
import 'controller/app_controller.dart';
|
||||
|
||||
enum IMSdkStatus {
|
||||
connectionFailed,
|
||||
connecting,
|
||||
connectionSucceeded,
|
||||
syncStart,
|
||||
synchronizing,
|
||||
syncEnded,
|
||||
syncFailed,
|
||||
syncProgress,
|
||||
}
|
||||
|
||||
enum KickoffType {
|
||||
kickedOffline,
|
||||
userTokenInvalid,
|
||||
userTokenExpired,
|
||||
}
|
||||
|
||||
mixin IMCallback {
|
||||
final initLogic = Get.find<AppController>();
|
||||
|
||||
Function(RevokedInfo info)? onRecvMessageRevoked;
|
||||
|
||||
Function(List<ReadReceiptInfo> list)? onRecvC2CReadReceipt;
|
||||
|
||||
Function(Message msg)? onRecvNewMessage;
|
||||
|
||||
Function(Message msg)? onRecvOfflineMessage;
|
||||
|
||||
Function(String msgId, int progress)? onMsgSendProgress;
|
||||
|
||||
Function(BlacklistInfo u)? onBlacklistAdd;
|
||||
|
||||
Function(BlacklistInfo u)? onBlacklistDeleted;
|
||||
|
||||
Function(int current, int size)? onUploadProgress;
|
||||
|
||||
final conversationAddedSubject = BehaviorSubject<List<ConversationInfo>>();
|
||||
|
||||
final conversationChangedSubject = BehaviorSubject<List<ConversationInfo>>();
|
||||
|
||||
final unreadMsgCountEventSubject = PublishSubject<int>();
|
||||
|
||||
final friendApplicationChangedSubject = BehaviorSubject<FriendApplicationInfo>();
|
||||
|
||||
final friendAddSubject = BehaviorSubject<FriendInfo>();
|
||||
|
||||
final friendDelSubject = BehaviorSubject<FriendInfo>();
|
||||
|
||||
final friendInfoChangedSubject = PublishSubject<FriendInfo>();
|
||||
|
||||
final selfInfoUpdatedSubject = BehaviorSubject<UserInfo>();
|
||||
|
||||
final userStatusChangedSubject = BehaviorSubject<UserStatusInfo>();
|
||||
|
||||
final groupInfoUpdatedSubject = BehaviorSubject<GroupInfo>();
|
||||
|
||||
final groupApplicationChangedSubject = BehaviorSubject<GroupApplicationInfo>();
|
||||
|
||||
final initializedSubject = PublishSubject<bool>();
|
||||
|
||||
final memberAddedSubject = BehaviorSubject<GroupMembersInfo>();
|
||||
|
||||
final memberDeletedSubject = BehaviorSubject<GroupMembersInfo>();
|
||||
|
||||
final memberInfoChangedSubject = PublishSubject<GroupMembersInfo>();
|
||||
|
||||
final joinedGroupDeletedSubject = BehaviorSubject<GroupInfo>();
|
||||
|
||||
final joinedGroupAddedSubject = BehaviorSubject<GroupInfo>();
|
||||
|
||||
final onKickedOfflineSubject = PublishSubject<KickoffType>();
|
||||
|
||||
final imSdkStatusSubject = ReplaySubject<({IMSdkStatus status, bool reInstall, int? progress})>();
|
||||
|
||||
final imSdkStatusPublishSubject = PublishSubject<({IMSdkStatus status, bool reInstall, int? progress})>();
|
||||
|
||||
final inputStateChangedSubject = PublishSubject<InputStatusChangedData>();
|
||||
|
||||
void imSdkStatus(IMSdkStatus status, {bool reInstall = false, int? progress}) {
|
||||
imSdkStatusSubject.add((status: status, reInstall: reInstall, progress: progress));
|
||||
imSdkStatusPublishSubject.add((status: status, reInstall: reInstall, progress: progress));
|
||||
}
|
||||
|
||||
void kickedOffline() {
|
||||
onKickedOfflineSubject.add(KickoffType.kickedOffline);
|
||||
}
|
||||
|
||||
void userTokenInvalid() {
|
||||
onKickedOfflineSubject.add(KickoffType.userTokenInvalid);
|
||||
}
|
||||
|
||||
void selfInfoUpdated(UserInfo u) {
|
||||
selfInfoUpdatedSubject.addSafely(u);
|
||||
}
|
||||
|
||||
void userStausChanged(UserStatusInfo u) {
|
||||
userStatusChangedSubject.addSafely(u);
|
||||
}
|
||||
|
||||
void uploadLogsProgress(int current, int size) {
|
||||
onUploadProgress?.call(current, size);
|
||||
}
|
||||
|
||||
void recvMessageRevoked(RevokedInfo info) {
|
||||
onRecvMessageRevoked?.call(info);
|
||||
}
|
||||
|
||||
void recvC2CMessageReadReceipt(List<ReadReceiptInfo> list) {
|
||||
onRecvC2CReadReceipt?.call(list);
|
||||
}
|
||||
|
||||
void recvNewMessage(Message msg) {
|
||||
initLogic.showNotification(msg);
|
||||
onRecvNewMessage?.call(msg);
|
||||
}
|
||||
|
||||
void recvOfflineMessage(Message msg) {
|
||||
initLogic.showNotification(msg);
|
||||
onRecvOfflineMessage?.call(msg);
|
||||
}
|
||||
|
||||
void recvCustomBusinessMessage(String s) {}
|
||||
|
||||
void progressCallback(String msgId, int progress) {
|
||||
onMsgSendProgress?.call(msgId, progress);
|
||||
}
|
||||
|
||||
void blacklistAdded(BlacklistInfo u) {
|
||||
onBlacklistAdd?.call(u);
|
||||
}
|
||||
|
||||
void blacklistDeleted(BlacklistInfo u) {
|
||||
onBlacklistDeleted?.call(u);
|
||||
}
|
||||
|
||||
void friendApplicationAccepted(FriendApplicationInfo u) {
|
||||
friendApplicationChangedSubject.addSafely(u);
|
||||
}
|
||||
|
||||
void friendApplicationAdded(FriendApplicationInfo u) {
|
||||
friendApplicationChangedSubject.addSafely(u);
|
||||
}
|
||||
|
||||
void friendApplicationDeleted(FriendApplicationInfo u) {
|
||||
friendApplicationChangedSubject.addSafely(u);
|
||||
}
|
||||
|
||||
void friendApplicationRejected(FriendApplicationInfo u) {
|
||||
friendApplicationChangedSubject.addSafely(u);
|
||||
}
|
||||
|
||||
void friendInfoChanged(FriendInfo u) {
|
||||
friendInfoChangedSubject.addSafely(u);
|
||||
}
|
||||
|
||||
void friendAdded(FriendInfo u) {
|
||||
friendAddSubject.addSafely(u);
|
||||
}
|
||||
|
||||
void friendDeleted(FriendInfo u) {
|
||||
friendDelSubject.addSafely(u);
|
||||
}
|
||||
|
||||
void conversationChanged(List<ConversationInfo> list) {
|
||||
conversationChangedSubject.addSafely(list);
|
||||
}
|
||||
|
||||
void newConversation(List<ConversationInfo> list) {
|
||||
conversationAddedSubject.addSafely(list);
|
||||
}
|
||||
|
||||
void groupApplicationAccepted(GroupApplicationInfo info) {
|
||||
groupApplicationChangedSubject.add(info);
|
||||
}
|
||||
|
||||
void groupApplicationAdded(GroupApplicationInfo info) {
|
||||
groupApplicationChangedSubject.add(info);
|
||||
}
|
||||
|
||||
void groupApplicationDeleted(GroupApplicationInfo info) {
|
||||
groupApplicationChangedSubject.add(info);
|
||||
}
|
||||
|
||||
void groupApplicationRejected(GroupApplicationInfo info) {
|
||||
groupApplicationChangedSubject.add(info);
|
||||
}
|
||||
|
||||
void groupInfoChanged(GroupInfo info) {
|
||||
groupInfoUpdatedSubject.addSafely(info);
|
||||
}
|
||||
|
||||
void groupMemberAdded(GroupMembersInfo info) {
|
||||
memberAddedSubject.add(info);
|
||||
}
|
||||
|
||||
void groupMemberDeleted(GroupMembersInfo info) {
|
||||
memberDeletedSubject.add(info);
|
||||
}
|
||||
|
||||
void groupMemberInfoChanged(GroupMembersInfo info) {
|
||||
memberInfoChangedSubject.add(info);
|
||||
}
|
||||
|
||||
void joinedGroupAdded(GroupInfo info) {
|
||||
joinedGroupAddedSubject.add(info);
|
||||
}
|
||||
|
||||
void joinedGroupDeleted(GroupInfo info) {
|
||||
joinedGroupDeletedSubject.add(info);
|
||||
}
|
||||
|
||||
void totalUnreadMsgCountChanged(int count) {
|
||||
initLogic.showBadge(count);
|
||||
unreadMsgCountEventSubject.addSafely(count);
|
||||
}
|
||||
|
||||
void inputStateChanged(InputStatusChangedData status) {
|
||||
inputStateChangedSubject.addSafely(status);
|
||||
}
|
||||
|
||||
void close() {
|
||||
initializedSubject.close();
|
||||
friendApplicationChangedSubject.close();
|
||||
friendAddSubject.close();
|
||||
friendDelSubject.close();
|
||||
friendInfoChangedSubject.close();
|
||||
selfInfoUpdatedSubject.close();
|
||||
groupInfoUpdatedSubject.close();
|
||||
conversationAddedSubject.close();
|
||||
conversationChangedSubject.close();
|
||||
memberAddedSubject.close();
|
||||
memberDeletedSubject.close();
|
||||
memberInfoChangedSubject.close();
|
||||
onKickedOfflineSubject.close();
|
||||
groupApplicationChangedSubject.close();
|
||||
imSdkStatusSubject.close();
|
||||
imSdkStatusPublishSubject.close();
|
||||
joinedGroupDeletedSubject.close();
|
||||
joinedGroupAddedSubject.close();
|
||||
}
|
||||
}
|
||||