Compare commits

...
Author SHA1 Message Date
613d38dd06 docs: 记录 B-273 Android 客户端清理与候选包
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-21 10:04:59 +08:00
1774e596ba test(mobile-next): 补充 B-273 悬浮窗、语音文案与位置清理定向测试
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-21 10:04:49 +08:00
694891c393 fix(mobile-next): 清理悬浮窗、语音文案与位置发送
按 B-273 / B-269 收口 Android 客户端:去掉悬浮窗申请与旧浮窗服务,通话入口统一为语音通话,删除位置发送与定位权限,保留历史位置只读展示。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-21 10:04:39 +08:00
设计开发队长andmultica-agent 092039bc1a fix(mobile-next): 收口我的信息只读字段显示
Co-authored-by: multica-agent <github@multica.ai>
2026-08-21 00:52:22 +08:00
7bda2f280a docs: 记录 B-261 /user/find/full 404 定位与构建证据
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 23:58:42 +08:00
9001688c9e fix(mobile-next): 我的信息改走 OpenIM SDK,避免账号服务 404
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 23:58:37 +08:00
1895830907 docs: 记录 B-225 联网修复对照、候选包哈希与回退
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 16:21:58 +08:00
bbc4dce0b6 fix: 验收包写入公司内网地址,避免 Windows 空 VITE 与 Android 假域名
Windows 补 .env.production 与 endpoints 兜底;Android 默认 host/端口改为内网,启动后重写 HttpUtil/ApiService,Urls 改为 getter。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 16:21:40 +08:00
18d890ae7f docs: 补记 B-210 回退不影响范围
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 09:58:58 +08:00
6e4afe9b71 docs: 记录 B-210 Android 通话视觉打回返工与构建证据
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 09:58:46 +08:00
9bde926c81 fix(mobile-next): 按 B-91 收口 Android 通话视觉打回项
呼出/通话中按钮、计时器、底色、60s 未接与进出场动效对齐视觉规范。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 09:58:28 +08:00
714794f7fe docs: 记录 B-204 Android 语音通话迁移与构建验证
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 07:59:02 +08:00
d7f7a6aed2 fix(mobile-next): 通话页遮罩与白字对齐 Token
把官方 Styles 黑底与通话白字映射到 B-91 maskBg/pageBg 与 12/14/16/18 字号,不在通话页叠加新样式。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 07:58:31 +08:00
3832e080c4 feat(mobile-next): 迁移 Android 一对一语音通话薄适配与入口
复用官方 OpenIMLive 信令与房间,换票改走账号服务 /api/rtc_token;入口仅音频,占线/超时/重复回调与销毁释放由公司层防护。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 07:58:24 +08:00
2a817e77d8 docs: 记录 B-197/B-198 跨端构建修复与验收
补记 Dart/Gradle/锁文件提交 SHA、debug/release 与 PC 重构建命令、产物 SHA256、启动冒烟、未测项与回退。不宣布运行回归通过。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 06:16:08 +08:00
c150033b39 chore(pc-client): 同步 package-lock 根版本号为 1.0.2
与 package.json 的 1.0.2 对齐。npm install 只回写锁文件顶层 version,无依赖树或包升级。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 06:15:22 +08:00
5160c8ec87 chore(mobile-next): Android Gradle 堆改为 4096M
-Xmx1536M 无法完成 release 构建(Java heap space)。本机以 -Xmx4096M 真实打通 debug/release,作为当前项目稳定值入库。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 06:15:21 +08:00
1767cf2547 fix(mobile-next): 修复资料页 FeatureFlags 导入与图片预览 const
资料页相对导入少一层导致 FeatureFlags 无法解析;大图预览 Center 使用了非 const 的 Styles.c_0089FF。仅改这两处编译阻塞,不扩大格式化。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 06:15:21 +08:00
2c81a11e03 docs: 记录 B-189 语音返工提交与回退命令
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 04:22:18 +08:00
15d7f1935e feat(mobile-next): 补齐语音未听红点、录音浮层与 50-60s 时限
按 B-187 打回修复 4.3/4.4 阻塞项,输入框与按住说话改用 searchBg。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 04:22:06 +08:00
e40ece184b docs: 记录 B-188 PC 会话置顶返工检查与回退
补记修复提交 SHA、npm run build / tsc 结果、上游存量错误和未实测项。不宣布整批通过。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 04:19:14 +08:00
d9d5853f73 fix(pc-client): 会话置顶改用 SDK setConversation
@openim/electron-client-sdk 无 pinConversation,右键置顶会 TS2551 且运行时 TypeError。改走已有的 setConversation,删除路径不动。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 04:18:42 +08:00
a4d21ef367 docs: 记录 B-185 第二批提交、越界核对与未验证项
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 03:51:55 +08:00
a44537da4e feat(pc-client): 第二批登录、会话、聊天与添加同事界面按规范收口
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 03:51:28 +08:00
d1657ea29f feat(mobile-next): 断网横幅恢复后收起,底栏标签改用 12px
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 03:51:27 +08:00
26622676ed feat(mobile-next): 工号查询防抖、开关接入,资料页不再把工号当手机号
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 03:51:27 +08:00
3b87812db8 feat(mobile-next): 聊天输入区、语音气泡与大图按规范重排
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 03:51:27 +08:00
49b346d375 feat(mobile-next): 通讯录按部门分组并补齐职务行与申请窄屏
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 03:51:27 +08:00
7f131457f7 feat(mobile-next): 会话页接全局搜索、精简加号菜单并改为长按操作
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 03:51:27 +08:00
ce2a3ae059 feat(mobile-next): 补齐状态线性图标与 toast/断网横幅动效 Token
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 03:51:26 +08:00
fb58da670b docs: 补记 B-171 小回归两提交与检查结果
记录断网横幅 SafeArea、添加同事独立 Obx 的 SHA、analyze 结果与回退命令。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 03:22:18 +08:00
e355b89204 fix(mobile-next): 添加同事页工号提示与发送按钮改回独立 Obx
仅改 add_colleague_page.dart:directoryHint 与 sending 各用独立 Obx 追踪,去掉嵌套 Builder。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 03:21:57 +08:00
26d070fbaf fix(mobile-next): 断网横幅加顶部 SafeArea,避免叠进状态栏
仅改 home_view.dart:CompanyOfflineBanner 外包 SafeArea(bottom: false),横幅高度仍为 36。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 03:21:47 +08:00
d9690168f8 docs: 记录 B-171 视觉返工提交、特批窗口常量与构建结果
更新验收文档:五项独立返工 SHA、electron 仅两常量差异、品牌历史遗留裁决、回退命令。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 03:00:26 +08:00
63520a6488 fix(pc-client): 主窗口下限改为 1080×680(B-171 特批仅两常量)
仅改 pc-client/electron/main/windowManage.ts 的 minWidth/minHeight。
electron/ 其余文件仍冻结。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 02:52:33 +08:00
2b2c2d28a4 fix(mobile-next): 把加载、失败、断网接到真实 SDK 与目录请求
会话列表、通讯录、好友申请、添加同事页覆盖 CompanyLoadingView/CompanyFailView;
主页断网横幅跟随 IMSdkStatus.connectionFailed。不伪造状态。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 02:52:24 +08:00
092f513708 fix(mobile-next): 登录失败改为顶部 toast,2 秒后自动消失
改 company_login_page.dart 与 company_login_logic.dart。
保留「工号或密码不正确」「网络异常,请稍后重试」;去掉按钮下方常驻错误字。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 02:49:48 +08:00
87a5930906 fix(mobile-next): 会话姓名改为 16sp,字号只用 12/14/16/18
仅改 conversation_view.dart 会话姓名,去掉 17sp,改用 AppFont.body。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 02:49:41 +08:00
da9152d36b fix(mobile-next): 未读角标改为最小 18×18、白字 12、圆角 9 并去掉重阴影
仅改 unread_count_view.dart。默认尺寸 18,数字 12,圆角 9;删除三层 BoxShadow。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 02:49:21 +08:00
5e098a5d32 docs: 记录 B-171 第一批构建、越界比对与回退
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 02:30:10 +08:00
0589623075 feat(pc-client): 在可改目录按 v2 重整 Token、侧栏宽度与好友申请五态
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 02:30:10 +08:00
60b6590409 feat(mobile-next): 工号登录与目录薄适配,并完成登录/会话/聊天/通讯录第一批界面
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 02:30:10 +08:00
d787c0a477 feat(mobile-next): 建立 v2 Token 唯一入口、内网地址与功能开关
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 02:30:09 +08:00
45d91684bc docs: 修正 B-149 上游差异表、2c9dab1 回退范围与 SHA256 当次产物说明
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-08-20 02:11:04 +08:00
编码工程师andmultica-agent e26abad4e1 docs(mobile-next): 建立 docs/upstream 与 docs/acceptance,回退引用对齐本分支提交
- docs/upstream/baseline.md: 上游来源/固定版本/许可证原文位置/工具链锁定/差异
- docs/upstream/build-and-rollback.md: 构建命令、本机实测 SHA256、逐提交回退方法
- docs/acceptance/sdk-compat-gate.md: hotfix.12 兼容冒烟矩阵(初始化/登录/会话同步/断线重连/好友/群组/文字双向/图片/文件/语音)
- docs/acceptance/pc-boundary.md: PC 端只读核对的可改边界封存
- docs/acceptance/visual-spec-token-entry.md: 视觉规范 v2 唯一来源与 Token 入口预留
- 修正导入/验证文档中回退引用为 B-95 分支实际提交

Co-authored-by: multica-agent <github@multica.ai>
2026-08-19 15:55:45 +08:00
编码工程师andmultica-agent 2c9dab160e feat(mobile-next): 接入 flutter_openim_sdk 3.8.3+hotfix.12 并完成核心能力实测
- 仅升级 flutter_openim_sdk 3.8.3+3 → 3.8.3+hotfix.12(pubspec.yaml、openim_common、openim_live、pubspec.lock)
- debug/release 双构建成功,核对包名/版本/签名/SHA256
- 双测试账号 t1001/t1002 实测:初始化、登录、会话同步、断线重连、好友/群组、
  文字/图片/文件/语音双向收发,全部通过(服务端落库复核)
- 验证与回退说明见 docs/mobile-next-hotfix-sdk-verification.md

Co-authored-by: multica-agent <github@multica.ai>
2026-08-19 15:24:37 +08:00
编码工程师andmultica-agent 8046ec7483 feat(mobile-next): 导入官方 openim-flutter-demo 固定基线 3.8.3-patch.3 并完成双构建
- 上游: github.com/OpenIMSDK/openim-flutter-demo tag 3.8.3-patch.3
  commit b3dfdb1e8aaeaaf6f0793e10cadd20d5c184a31f
- 并行目录 mobile-next/ 原样导入(含 LICENSE),不覆盖现网 mobile/
- 锁定 Flutter 3.24.5 / Dart 3.5.4 / JDK 17 / Gradle 7.6.3 / AGP 7.3.1
- 实测 Android debug 与 release 构建均成功(见 docs/mobile-next-baseline-import.md)
- 本提交可单独回退:git revert 1db1229(重写前)

Co-authored-by: multica-agent <github@multica.ai>
2026-08-19 15:24:33 +08:00
830 changed files with 62283 additions and 333 deletions
+10
View File
@@ -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
+120
View File
@@ -0,0 +1,120 @@
# B-204 Android 语音通话迁移与构建验证
分支:`agent/agent/3a58b06e`
施工基线 HEAD`2a817e77d899d7af66ebfecef382b55d872c1285`
越界对比基线:`e26abad`
本卡只做 Android 一对一语音通话迁移与可构建验证,不改 PC 通话、不部署、不发布、不换标。
**结论:Android debug/release 构建通过,状态机替身测试通过。缺有效账号、ARM64 真机和 LiveKit 实测,不得写成通话运行验收通过。**
## 配置入口
| 项 | 位置 | 值 |
|---|---|---|
| 开关 | `mobile-next/lib/company/feature_flags.dart` `FeatureFlags.livekitCall` | 跟随 `LiveKitCallConfig.enabled` |
| 配置门 | `mobile-next/lib/company/rtc/livekit_call_config.dart` | `shipped && endpointsReady` |
| LiveKit | `AppEndpoints.livekitUrl` | `ws://192.168.200.11:17880` |
| 换票 | `POST {authApiBase}/api/rtc_token` | Bearer `imToken`body `{room, identity}` |
| 信令 | 官方 `customType` 200–204 仅在线自定义消息 | 未自建第二套信令,未改 SDK 核心 |
官方 `Apis.getTokenForRTC``/user/rtc/get_token` + `token` 头 + `serverUrl`)与账号服务不兼容。本卡用公司薄适配 `RtcTokenApi` 覆盖 `getRtcCertificate`,缺 `liveURL` 时回落到 `AppEndpoints.livekitUrl`。未改 `account-service/` 与现网端口。
`LiveKitCallConfig.shipped = true` 仅在本卡构建通过后保持开启。若关掉 `endpointsReady`(地址不是 `ws://` / `http`),入口自动隐藏。
## 提交主题(可逐项 `git revert`
从新到旧回退:先本验收记录,再 Token 映射,再通话适配。
| 主题 | SHA | 文件 |
|---|---|---|
| 本验收记录 | 本文件当次提交 | `docs/acceptance/android-livekit-call.md` |
| 通话页 Token 对齐 | `d7f7a6aed213ad7250e7e0da28608d0e312859fb` | `apply_official_styles.dart` |
| 语音通话薄适配与入口 | `3832e080c4cba2ec9a76e1cb5b988bc06f0fd4a3` | `company/rtc/*``im_controller.dart`、聊天/资料入口、`openim_live` 超时/销毁/重连、测试 |
回退示例(新到旧):
```
git revert <本验收提交>
git revert d7f7a6aed213ad7250e7e0da28608d0e312859fb
git revert 3832e080c4cba2ec9a76e1cb5b988bc06f0fd4a3
```
回退不影响 `mobile/``account-service/``config/``scripts/`、现网服务、PC 通话死代码与已发布安装包。
## 环境
- Flutter 3.24.5 / Dart 3.5.4`C:\flutter324`
- Temurin JDK 17.0.20+8`toolchain\jdk17`
- Android SDK:既有 B-95 工具链(build-tools 含 36.0.0compileSdk 34
- `org.gradle.jvmargs=-Xmx4096M`
## 检查与构建
### 状态机替身
```
cd mobile-next
flutter test test/company/rtc_token_mapper_test.dart test/company/call_session_guard_test.dart
```
11 项通过:换票解析(缺 liveURL 回落、`serverUrl`/`liveURL`、失败码)、占线、重复信令、超时取消、销毁释放计时器。
### Dart 定点
- `lib/company/rtc/**``feature_flags.dart``im_controller.dart`**0 error**
- 全量 `flutter analyze`**529 issues**。error 仍为存量(`local_plugin/flutter_download_manager/example` 等),本卡新增文件无 error。
### Android(真实构建)
```
flutter pub get
flutter build apk --debug
flutter build apk --release
```
| 构建 | 结果 | 大小 | SHA256 | 产物 |
|---|---|---|---|---|
| debug | 成功 | 109,405,761 B | `21487F23963DC60189C9181F3B985495ED6EFF7F74C619FCB114E5DB26B259F3` | `mobile-next/build/app/outputs/flutter-apk/app-debug.apk` |
| release | 成功 | 53,284,571 B | `AADFF25F62CC98D60D5EF0C94112C4388027107669A15743D2C1BB16F2245C78` | `mobile-next/build/app/outputs/flutter-apk/app-release.apk` |
元数据(aapt / apksignerrelease):包名 `io.openim.flutter.demo`versionName `3.8.3` / versionCode `180`minSdk 24 / targetSdk 33 / compileSdk 34,仅 `arm64-v8a`label `F-DEMO`。签名 CN=openim,证书 SHA-256 `1f38a82fb3c33be7951fb5d964ef5bd9c6c9bfc084ae1e2a8a40a0d1f44ae1fe`
构建期告警:Flutter Gradle apply-script 弃用;部分依赖 Kotlin metadata 1.8.0 vs 工程预期 1.6.0。均属上游,debug/release 均通过。APK 内嵌时间戳,哈希不可位级复现。
## 越界比对
相对 `2a817e77`:仅上表主题涉及的 `mobile-next/` 与本验收文档。
相对 `e26abad`
- `mobile/``account-service/``config/``scripts/`**零改动**
- `pc-client/src/store/``pc-client/src/layout/MainContentWrap.tsx`、发送/历史链路:**零改动**
- PC 未新增任何通话入口;RTC 死代码按 B-90 保留
## 已测 / 未测
已测(替身或构建):
- 换票响应映射与失败文案
- 占线拒绝第二路、重复信令去重、30s 超时、页面销毁取消计时器
- Android debug/release 可构建
- 入口:单聊顶栏/工具箱/资料页随开关显示;仅音频;语音要麦克风权限,不要摄像头
未测(缺外部条件,禁止写成通过):
- 测试账号:无有效工号+密码,未登录
- Android ARM64 真机:未安装、未点验呼叫/来电/接听/拒绝/取消/挂断
- LiveKit 进房、听筒/扬声器、静音、后台/锁屏返回、异常断开重连的真机表现
- 与旧 `mobile/` 或 PC 的互通(PC 本阶段不建设通话)
最小所需:管理员给两个测试工号;两台 ARM64 真机装 `app-release.apk`;确认 LiveKit `:17880` 与账号服务 `:10010/api/rtc_token` 可用后做一轮双向语音。
## 风险清单
- OpenIM 许可书面结论未落;未换标,label 仍 `F-DEMO`
- 官方 chat 换票协议与现网账号服务不兼容,依赖本卡薄适配;关掉开关即无入口
- LiveKit 使用官方 `livekit_client` 2.2.5 默认重连,真机未测
- APK 仍用上游 openim keystore
- 全量 analyze 存量错误仍在,不作为本卡运行通过依据
功能质检与视觉审核须另排。本卡不宣布语音通话实测通过。
+73
View File
@@ -0,0 +1,73 @@
# B-171 第一批迁移验收与回退
分支:`agent/agent/7b089146`(基于 B-95 `agent/agent/713c11eb` / `e26abad`
回退基线:`fa8584a`
## 提交主题(可逐项 `git revert`
### 第一批
1. B-149 文档三处修正 `45d9168`
2. 手机 Token/主题入口、内网地址、功能开关 `d787c0a`
3. 工号登录薄适配与登录页 `60b6590`
4. 员工目录、通讯录/添加同事/好友申请、会话与聊天第一批界面(含在 `60b6590`
5. PC 可改目录 Token 与通讯录/申请列表重整 `0589623`
6. 本验收记录(初版)`5e098a5`
### B-173 定向返工(本轮)
| 主题 | SHA | 文件 |
|---|---|---|
| 未读角标 18×18、白字 12、圆角 9、去掉重阴影 | `da9152d36b680b76e0e9d50536dd4692baffe084` | `mobile-next/openim_common/lib/src/widgets/unread_count_view.dart` |
| 会话姓名 16sp,字号只用 12/14/16/18 | `87a5930906554d3b0b88bdf95086787624a345ab` | `mobile-next/lib/pages/conversation/conversation_view.dart` |
| 登录失败顶部 toast,2 秒消失 | `092f5137082e392de9a14bd340260a147b9e254a` | `company_login_page.dart``company_login_logic.dart` |
| 加载/失败/断网接到真实状态 | `2b2c2d28a42f57d1cd8e635153ce398685a0bc89` | 会话/通讯录/好友申请/添加同事/主页 |
| 主窗口下限 1080×680(特批仅两常量) | `63520a64889a667c79be3406f85b5c191ad24635` | `pc-client/electron/main/windowManage.ts` |
| 本轮验收记录 | 本文件当次提交 | `docs/acceptance/b171-batch1.md` |
回退本轮:从新到旧逐个 `git revert` 上表 SHA(含本验收提交)。
### B-180/B-181 小回归(本轮)
| 主题 | SHA | 文件 |
|---|---|---|
| 断网横幅外包 `SafeArea(bottom: false)` | `26d070fbaf40f909f40bc5320c65d81b1b97fb9d` | `mobile-next/lib/pages/home/home_view.dart` |
| 工号提示与发送按钮改回独立 `Obx` | `e355b89204c14708a2d51bee9af84f2227bc71dd` | `mobile-next/lib/company/ui/add_colleague_page.dart` |
| 本轮验收补记 | 本文件当次提交 | `docs/acceptance/b171-batch1.md` |
回退本轮小回归:`git revert <本验收提交>`,再 `git revert e355b89`,再 `git revert 26d070f`
`dart format` + `flutter analyze`:上述两个 Dart 文件无 issues。未重新打安装包。HTTP 登录与 LiveKit 仍不标为通过。黄色建议未处理。
## 越界比对(对比 `e26abad`
零改动:`mobile/``pc-client/src/store/``pc-client/src/layout/MainContentWrap.tsx``pc-client/src/pages/chat/queryChat/ChatFooter/useSendMessage.ts``pc-client/src/pages/chat/queryChat/useHistoryMessageList.tsx``account-service/`
`pc-client/electron/`:仅 `main/windowManage.ts``minWidth=1080``minHeight=680` 两处常量变化(队长特批)。其余 electron 文件相对 `e26abad` 为零改动。
## 窗口常量特批
允许且仅允许修改 `pc-client/electron/main/windowManage.ts``minWidth``minHeight`。整树越界比对已单独列出该差异。
## 品牌历史遗留
`pc-client/src/config/index.ts` 中历史已有的 `APP_NAME = "畅联"` 非本批引入。本批不增、不删、不改任何品牌字样、标识或资源;待 OpenIM 许可书面结论后统一处置。
B-173 黄色建议未并入本轮。
## 构建(返工后,Flutter 3.24.5 / Temurin 17 / 原 B-95 SDK
| 构建 | 结果 | 大小 | SHA256(当次产物记录,非位级可复现) |
|---|---|---|---|
| debug | 成功 | 109,478,645 B | `E51571608B10FF32D25867EA6E23C750EEA2845FA0ED31FD9C17DAA960F654B5` |
| release | 成功 | 53,279,759 B | `BA0D548B7E38203D0FF455646744F4A591E69853E686F1B3D15CCB61EE899F8C` |
`dart format` 已对返工 Dart 文件执行。`flutter analyze`:本卡改动文件无 error(仅既有 info/warning)。仓库内既有 `local_plugin/flutter_download_manager/example` 报错与 B-95 相同,非本卡引入。
PC:本环境无 `node_modules`,未跑 `npm run lint` / `vite build`,不推定通过。窗口下限改动为 TypeScript 常量,未做运行时验证。
- HTTP 工号密码登录:**不标为已通过。**
- LiveKit**未测,不标为已通过。**
- 品牌换标:未做。登录页保留 OpenIM 标识。
功能质检与视觉审核须重新执行,本卡不自行宣布通过。
+94
View File
@@ -0,0 +1,94 @@
# B-185 / B-171 第二批交互补齐验收与回退
分支:`agent/agent/7b089146`
基线:`fb58da6`B-171 第一批完成点)
架构:B-90;视觉:B-91 `changlian-visual-spec-v2.md`
本批不换标、不部署、不发安装包;LiveKit 未迁。
## 提交主题(可逐项 `git revert`
从新到旧回退:先 B-189,再 B-188 验收补记与 `d9d5853`,再原第二批验收提交,再按下表从下往上 `git revert`
| 主题 | SHA | 主要文件 |
|---|---|---|
| 状态线性图标与 toast/断网横幅动效 Token | `ce2a3ae059be4de480b73ee585d36a051b303fd0` | `app_tokens.dart``state_views.dart` |
| 手机会话页:搜索、+ 菜单、长按置顶/删除、去掉置顶角标 | `7f131457f7f5d0a30ca81414c7dc94ede6f59d84` | `conversation_view.dart` |
| 通讯录部门分组、职务行、申请窄屏 | `49b346d375e9b9b62c3a59c6f6970c7facfba94b` | `contacts_logic.dart``contacts_view.dart``friend_requests_view.dart` |
| 聊天输入区、语音气泡、大图、录音与字号映射 | `3b87812db8945c3b7fa6d4c0eddddb35f5ab10f3` | `chat_*.dart``apply_official_styles.dart` |
| 工号查询防抖、控制器生命周期、开关、资料页工号 | `26622676ed4f4898385d8e9e686296eb56adf4be` | `add_colleague_page.dart``app_pages.dart``company_login_page.dart``my_info_view.dart``personal_info_view.dart` |
| 断网横幅恢复后 300ms 收起、底栏 12px | `d1657ea29f0fc59f248f2108d7cfb9bcc239921e` | `home_view.dart` |
| PC 第二批登录/会话/聊天/添加同事/职务行/i18n | `a44537da4e8ce7b5b17b491c05592ad21cdd0bca` | `pc-client/src/pages/**``ApplicationItem``i18n``global.scss``docs/acceptance/pc-boundary.md` |
| 第二批验收记录 | `a4d21ef36777440812c6746cd792eeaf7685cd5c` | `docs/acceptance/b171-batch2.md` |
| B-188 定点返工:PC 会话置顶改 `setConversation` | `d9d5853f73aa8060c9ed768c326f00d691847e3e` | `pc-client/src/pages/chat/ConversationSider/ConversationItem.tsx` |
| B-188 验收补记 | `e40ece1` | `docs/acceptance/b171-batch2.md` |
回退 B-188:先 `git revert e40ece1`,再 `git revert d9d5853f73aa8060c9ed768c326f00d691847e3e`
## B-189 语音区返工(相对 `e40ece1`
依据:B-187 打回三项阻塞 + 输入框/`按住 说话` 底色 `searchBg`。不处理其余黄色建议。
| 主题 | SHA | 主要文件 |
|---|---|---|
| 未听红点、录音浮层入场/取消区、50–60s 时限、searchBg | `15d7f1935e38c18d127319346cf03d278b596b2c` | `chat_voice_*.dart``chat_item_view.dart``chat_input_box.dart``apply_official_styles.dart``styles.dart` |
回退 B-189:先 `git revert` 本补记提交,再 `git revert 15d7f1935e38c18d127319346cf03d278b596b2c`
静态核对(对照代码,非运行):
- 未听红点:接收且 `message.isRead == false` 时在气泡右侧 8px `danger`;播放走既有 `_playVoiceMessage` + `_markMessageAsRead`,不另造状态。
- 浮层入场:150ms ease-out 透明度 0→1`Styles.motionOf` 接到 `AppMotion.reduce` / `AppDuration.overlay`;取消区保持 `rgba(0,0,0,0.7)` 黑卡,仅垃圾桶与提示改 `danger`;切换时长走 `AppDuration.overlaySwitch`
- 50s:计时改 `warning` 文案「还可说 N 秒」;60s:既有 `ChatRecordVoiceView` 中断→dispose→一次 `onCompleted`,toast「已达最长 60 秒,已自动发送」。实例级 `_completed` 避免重复发送;timer 在 dispose 取消。
- 输入框与「按住 说话」底色改为 `Styles.c_F2F3F5``AppColors.searchBg`,不再用 `c_F0F2F6`/`chatBg`
## 检查
- `dart format` / `flutter analyze` / Android debug+release**未跑。** 本环境 PATH 中无 `flutter`/`dart`/`java`,不推定通过。
- PC `npm run lint` / `vite build`B-189 未改 PC、未重跑。B-188 当时 `npm run build` 通过,见下节。
- 运行截图:无 Flutter 工具链、无测试账号、无客户端进程,**未截图、未实测**未听红点/播放清除/取消手势/50–60s 倒计时/到限自动发送与 toast。不得推定通过。
### B-188 定点返工检查(2026-08-20
- 改动:`IMSDK.pinConversation(...)``IMSDK.setConversation({ conversationID, isPinned: !conversation.isPinned })``deleteConversationAndDeleteAllMsg` 未改。
- PC `npm run build`**通过**vite `✓ built in 31.30s`,随后写出 `dist-electron/**`)。
- `npx tsc --noEmit`(实际调用 `node node_modules/typescript/bin/tsc --noEmit`):`ConversationItem.tsx` **无本批新增错误**(无 TS2551 / `pinConversation`)。
- 会话右键「置顶/取消置顶」:**未实测**(无登录运行环境、无客户端进程),不得推定通过。
- 黄色建议:未处理。
`tsc --noEmit` 上游存量错误(非本卡引入,未修):
- `src/hooks/useGroupMembers.ts` TS18047 ×3`latestFetchState.current` possibly null
- `src/layout/LeftNavBar/About.tsx` TS2345 ×2`OnUploadLogsProgress` 回调类型)
- `src/pages/chat/queryChat/useHistoryMessageList.tsx` TS18047 ×1
- `src/pages/common/ChooseModal/ChooseBox/index.tsx` TS18047 ×2
- `src/pages/common/RtcCallModal/index.tsx` TS2786`LiveKitRoom` JSX
- `src/pages/common/RtcCallModal/RtcControl.tsx` TS2786 ×2`TrackToggle`
- `src/pages/common/RtcCallModal/RtcLayout.tsx` TS2786`VideoTrack`
- `src/pages/common/UserCardModal/index.tsx` TS2345
- `src/utils/imCommon.ts` TS2322 ×11`string | undefined``string`
## 越界比对(对比 `e26abad`
零改动:`mobile/``pc-client/src/store/``pc-client/src/layout/MainContentWrap.tsx``pc-client/src/pages/chat/queryChat/ChatFooter/useSendMessage.ts``pc-client/src/pages/chat/queryChat/useHistoryMessageList.tsx``account-service/`
`pc-client/electron/`:仅既有 `main/windowManage.ts``minWidth=1080``minHeight=680`(B-171 特批),本批未再改 electron。
`pc-boundary.md` 已扩到与 B-90 / B-185 一致:登录窗、chat **展示**`AddColleague.tsx` 列入可改;发送/历史/store/SDK 初始化仍冻结。PC 聊天顶栏去掉「语音通话」入口;RTC 死代码未删。
B-189 改动限于 `mobile-next/openim_common` 语音/输入部件、Token 接线、`mobile-next/lib/pages/chat/chat_view.dart` 自定义语音气泡防双重气泡,以及本验收记录。
## 未验证(缺账号环境,禁止推定通过)
- HTTP 正确密码登录
- 双向消息收发
- 服务端好友申请 `status=2`
- LiveKit / 语音通话(本阶段不迁、PC 不建设)
- 登录窗独立 360×480:受 electron 冻结限制,本批只改登录页展示,未改窗口尺寸
- B-189 全部录音/未听红点运行时表现
## 品牌
未换标。手机登录仍按开关保留 OpenIM 标识。不增删品牌资源。
功能质检与视觉审核须重新执行,本卡不自行宣布整批通过。
@@ -0,0 +1,150 @@
# B-197 / B-198 跨端构建修复与验收记录
分支:`agent/agent/7b089146`(本卡工作树 `agent/agent/2cae90a2`
构建基线 HEAD`2c81a11e03411fa1b033f0f74cd49139e258d1d3`
越界对比基线:`e26abad`
本卡只做构建修复与验收记录,不部署、不发布、不换标。
B-197 已真实打通 PC 与 Android debug/release,但修复仅在部署工程师本机工作树。本文件记录 B-198 复核后的入库提交与**重新真实构建**结果。
**结论:安装包构建与 PC 启动冒烟通过。登录、收发、语音、同步等运行时回归未测,不得视为跨端运行验收通过。**
## 提交主题(可逐项 `git revert`
从新到旧回退:先本验收记录,再锁文件,再 Gradle 堆,再 Dart 编译修复。
| 主题 | SHA | 文件 |
|---|---|---|
| 本验收记录 | 本文件当次提交 | `docs/acceptance/b197-cross-platform-regression.md` |
| 同步 package-lock 根版本号 1.0.2 | `c150033b39d047852eb1baed1d55b1726a24e65a` | `pc-client/package-lock.json` |
| Android Gradle 堆 4096M | `5160c8ec87f794f75a2ab2e06632a88c35f2d2e1` | `mobile-next/android/gradle.properties` |
| FeatureFlags 导入 + 去掉预览 const | `1767cf2547ca58102ba3734c06ae73ce85e646a2` | `personal_info_view.dart``chat_picture_preview.dart` |
回退示例(新到旧):
```
git revert <本验收提交>
git revert c150033b39d047852eb1baed1d55b1726a24e65a
git revert 5160c8ec87f794f75a2ab2e06632a88c35f2d2e1
git revert 1767cf2547ca58102ba3734c06ae73ce85e646a2
```
回退不影响 `mobile/``account-service/``config/``scripts/`、现网服务与已发布安装包。
## 复核的 4 处改动
1. `mobile-next/lib/pages/contacts/user_profile_panel/personal_info/personal_info_view.dart:6``../../../company``../../../../company`。该文件在 `personal_info/` 下,相对 `lib/` 需要四层。目标模块是 `lib/company/feature_flags.dart``FeatureFlags`,未引入其它模块。
2. `mobile-next/openim_common/lib/src/widgets/chat/chat_picture_preview.dart:97`:去掉 `Center` 外层 `const``Styles.c_0089FF` 定义为 `static Color`(非 const)。未改 SizedBox / CircularProgressIndicator,未做额外格式化。
3. `mobile-next/android/gradle.properties``org.gradle.jvmargs=-Xmx1536M``-Xmx4096M`。B-197 在 1536M 上 release 报 `Java heap space`;本卡用 4096M 重新打通 debug 与 release。未再试 2048M/3072M(缺少真实 release 证明),故采用已证明稳定的 4096M。
4. `pc-client/package-lock.json`:仅根节点 `"version": "1.0.1"``"1.0.2"`,与 `package.json` 的 1.0.2 对齐。`lockfileVersion` 仍为 3,无依赖树或包升级。其它 npm 回写视为环境噪音,未入库。
## Gradle 机器内存要求
- 配置:`mobile-next/android/gradle.properties``org.gradle.jvmargs=-Xmx4096M`(与 `docs/upstream/build-and-rollback.md``GRADLE_OPTS=-Xmx4096M` 一致)。
- 机器:JVM 堆预留 4GB。建议物理内存 ≥ 8GB(堆 + Gradle daemon + 系统);本机构建机约 64GB,构建时未再出现 heap space。
- 1536M 不能作为 release 稳定值。
## 环境
- Flutter 3.24.5 / Dart 3.5.4`C:\flutter324`
- Temurin JDK 17.0.20
- Android SDK:既有 B-95 工具链(build-tools 36.0.0platforms 含 compileSdk 34
- Node v24.18.0 / npm 11.16.0`C:\Program Files\nodejs`
- `npm install``husky install || true` 在 Windows cmd 下仍以 exit 1 结束(已知非阻塞);`node_modules` 可用,后续 vite / electron-builder 成功。
## 检查与构建
### Dart
- 对上述两文件做过 `dart format`,但**未提交格式化换行**,只保留两处语义改动。
- 定点 `flutter analyze``personal_info_view.dart` 0 issues`chat_picture_preview.dart``invalid_constant`,仅存量 `must_be_immutable` / `use_super_parameters`
- 全量 `flutter analyze`mobile-next):**553 issues**(约 18 error / 87 warning / 448 info)。error 全为存量:`local_plugin/flutter_download_manager/example``openim_common``push_controller.dart` / `custom_mk_controls.dart`。本卡两文件无新增 error。
### Android(必须重新真实构建)
命令(`mobile-next/`):
```
flutter pub get
flutter build apk --debug
flutter build apk --release
```
| 构建 | 结果 | 大小 | SHA256 | 产物 |
|---|---|---|---|---|
| debug | 成功 | 109,391,065 B | `CE01F30CAFBA24CAFD686F0CFB32ACBDB53359395341B0B1EA2FB795F14C0748` | `mobile-next/build/app/outputs/flutter-apk/app-debug.apk` |
| release | 成功 | 53,273,539 B | `52F02CBC855989C62A89112EB791510CC4313921D9E1998456E94A737F8B148B` | `mobile-next/build/app/outputs/flutter-apk/app-release.apk` |
元数据(aapt / apksignerrelease):包名 `io.openim.flutter.demo`versionName `3.8.3` / versionCode `180`minSdk 24 / targetSdk 33 / compileSdk 34,仅 `arm64-v8a`label `F-DEMO`。签名 CN=openim,证书 SHA-256 `1f38a82fb3c33be7951fb5d964ef5bd9c6c9bfc084ae1e2a8a40a0d1f44ae1fe`
构建期告警:Flutter Gradle apply-script 弃用;部分依赖 Kotlin metadata 1.8.0 vs 工程预期 1.6.0。均属上游,debug/release 均通过。
### PC(锁文件影响后的 build + 安装包)
```
npm install
npm run build
npx tsc --noEmit
npx electron-builder --win --x64
```
| 步骤 | 结果 |
|---|---|
| npm install | 依赖装上;husky prepare 在 Windows 报 exit 1(非阻塞) |
| vite build | 通过(`✓ built in 25.77s`),antd `"use client"` 指令被忽略(存量告警) |
| tsc --noEmit | exit 2**24 个存量错误**,与 B-188 清单一致,本卡未新增 |
| electron-builder | 通过;`extraResources` 目录缺失,构建跳过该项 |
产物:`pc-client/release/Base/1.0.2/畅联_1.0.2.exe`105,891,730 B(约 101MB),SHA256 `A5F15035D669E2184BA1ED2E68FFFB1432FB997703F1FC8103CE4B38D7BB362E`
启动冒烟:启动 `win-unpacked/畅联.exe`,进程拉起且主窗口标题为「畅联」,随后结束进程。未登录。
`tsc` 存量错误(未修):`useGroupMembers.ts` TS18047 ×3、`About.tsx` TS2345 ×2、`useHistoryMessageList.tsx` TS18047 ×1、`ChooseBox/index.tsx` TS18047 ×2、`RtcCallModal` / `RtcControl` / `RtcLayout` TS2786 ×4、`UserCardModal` TS2345 ×1、`imCommon.ts` TS2322 ×11。
## 与 B-197 报告 SHA256 的差异
B-197 评论记录:
- PC `eab9bef6285c940351cdd995d850a0d4c67aebc122b83a0ba0680ea0f76e3df2`
- Android release `b5029f0ece55cd11828a1fe4cb9364e660baad04495a74fe94f33639be8165c8`
- Android debug `035d5b6eba7b20351269d88339ad5e0cd2d1179ac7d8fdae8e18a0069fc6b6b7`
本卡重跑后哈希均不同。APK / Electron 安装包内嵌构建时间戳,**不是位级可复现**;可复现的是工具链、命令、包名、签名证书与约 50.8MB / 101MB 量级。以本表 SHA256 为准。
## 越界比对
相对 `2c81a11e`:仅上述 4 个提交涉及的文件。
相对 `e26abad`
- `mobile/``account-service/``config/``scripts/`**零改动**
- `pc-client/src/store/``pc-client/src/layout/MainContentWrap.tsx``pc-client/src/pages/chat/queryChat/ChatFooter/useSendMessage.ts``pc-client/src/pages/chat/queryChat/useHistoryMessageList.tsx`**零改动**
- `pc-client/electron/`:仅既有 `windowManage.ts``minWidth=1080``minHeight=680`B-171 特批),本卡未再改
## 未测(缺外部条件,禁止写成通过)
- 测试账号:无有效工号+密码,未登录
- Android ARM64 真机:产物仅 arm64-v8a,未安装、未点验
- 工号登录 / 会话同步 / 好友群组 / 文字图片文件语音 / 断线重连 / 录音取消 / 50–60 秒时限 / 未听红点 / 安卓语音通话
- PC 人工交互:置顶、删除、断网恢复、1080×680 稳定性、双向收发
最小所需:管理员给测试工号;真机装 `app-release.apk`PC 装 `畅联_1.0.2.exe`;两工号同时登录做一轮双向收发。
## 安装与回退(本机产物,未入库)
安装:
- Android:把 `app-release.apk` 拷到 ARM64 真机安装(包名 `io.openim.flutter.demo`,会覆盖同包名旧包)。
- PC:运行 `畅联_1.0.2.exe`
回退代码:按上文 `git revert` 顺序。回退安装包:卸载本包 / 装回旧版安装包。现网服务与旧 `mobile/` 不受影响。
## 风险清单
- OpenIM 许可书面结论未落;未换标,label 仍 `F-DEMO`
- APK 仍用上游 openim keystore;正式试用前需换正式签名
- PC `extraResources` 目录缺失(构建跳过)
- Electron 22 偏旧;内网地址写死 `192.168.200.11`
- 全量 analyze / tsc 存量错误仍在,不作为本卡回归通过依据
功能质检与视觉审核须另排。本卡不宣布跨端运行验收通过。
@@ -0,0 +1,99 @@
# B-210 Android 通话视觉打回返工
分支:`agent/agent/ede0aecc`(基于 B-204 `agent/agent/3a58b06e` HEAD `714794f`
施工依据:B-91 视觉规范 v2;打回结论 B-209;姓名字号裁定 18px,32px 仅计时器。
本卡只做打回返工、构建验证和返工证据,不部署、不发布、不换标。
**结论:9 项阻塞 + 建议项已按规范收口;Android debug/release 真实构建通过。缺有效账号和 ARM64 真机,来电/通话页实机渲染、听筒/扬声器、静音、后台/锁屏、铃声震动继续标为未测。**
## 打回项对照
| # | 打回项 | 修改位置 | 结果 |
|---|---|---|---|
| 1 | 计时器 32px 纯白 tabular figures | `AppFont.callTimer``Styles.ts_callTimer``controls.dart` 通话中状态字 | 已改 |
| 2 | 通话页底 `#1D2129`,不复用 maskBg | `AppColors.callBg``Styles.c_callBg``call_state.dart` | 已改 |
| 3 | 呼出中仅居中 64 红色取消 | `controls.dart` `_buttonArea``LiveButton.cancel` | 已改 |
| 4 | 通话中 48 次按钮 + 居中红色挂断;Token 圆底线性图标 | `live_button.dart``controls.dart` | 已改,不再用位图 PNG |
| 5 | 姓名 → 状态 → 96 头像圆角 0.18 | `controls.dart` `_infoColumn` | 姓名 18px,头像 96×0.18 |
| 6 | 结束/失败展示 1.5s 后退出,失败 toast | `call_state.dart` `beginEnding``Styles.callEndHold` | 已结束 / 网络异常,通话中断 / 对方已拒绝 |
| 7 | 未接 60s +「未接通话」系统消息;清掉 30s 双来源 | `AppDuration.callInviteTimeout``LiveKitCallConfig` / `Styles` / `CallSessionGuard` / 信令 timeout | 超时插入 `CallState.timeout`,文案 `未接通话` |
| 8 | 进出 250ms 自下而上 ease-out,状态不可被重复回调破坏 | `call_page_host.dart``live_client.dart` close 防重入、`beginEnding` `_ending/_closed` | 已改 |
| 9 | 来电每 1s 震动,拒绝/接听/退出/销毁停止 | `live_controller.dart` `_startIncomingVibrate` / `_stopSound` | 已改;真机未测 |
| 10 | 状态字 14px 白 60%;文案;静音/免提;最小化点击区 48 | `ts_callStatus`、zh_CN 文案、`LiveButton.mute/handsFree`、最小化 `IconButton` 48 | 已改 |
## 提交主题(可逐项 `git revert`
从新到旧回退:先本验收记录,再视觉返工。
| 主题 | SHA | 文件 |
|---|---|---|
| 本验收记录 | 本文件当次提交 | `docs/acceptance/b210-android-call-visual-rework.md` |
| 视觉打回返工 | `9bde926` | Token、文案、超时单一来源、通话页布局/按钮/结束态/动效/震动、测试 |
回退示例(新到旧):
```
git revert <本验收提交>
git revert 9bde926
```
回退不影响 `mobile/``account-service/``config/``scripts/`、现网服务、PC 通话与已发布安装包。B-204 原提交 `3832e080` / `d7f7a6ae` / `714794f7` 仍可按原记录回退。
## 环境
- Flutter 3.24.5 / Dart 3.5.4`C:\flutter324`
- Temurin JDK 17.0.20+8
- Android SDK:既有 B-95 工具链(compileSdk 34
- `org.gradle.jvmargs=-Xmx4096M`
## 检查与构建
### 定点测试
```
cd mobile-next
flutter test test/company/rtc_token_mapper_test.dart test/company/call_session_guard_test.dart test/company/call_visual_rework_test.dart
```
16 项通过:换票映射、占线/去重/超时/销毁、60s 单一来源、callBg≠maskBg、32px tabular figures、14px/18px、250ms/1.5s/48·64·96 尺寸。
定点 `flutter analyze` 修改文件:**0 error**。存量 info/warning 未作为本卡阻塞。
### Android(真实构建)
| 构建 | 结果 | 大小 | SHA256 | 产物 |
|---|---|---|---|---|
| debug | 成功 | 109,424,273 B | `415478F0908BB44449C7DA944F07C5214989888C77B7E13295E4D71082197308` | `mobile-next/build/app/outputs/flutter-apk/app-debug.apk` |
| release | 成功 | 53,289,471 B | `7D81C54D2A03920E0989DDCFD5E29C3433DEB4FDB15266DE2913864D6C4FFD1C` | `mobile-next/build/app/outputs/flutter-apk/app-release.apk` |
构建期告警同 B-204Flutter Gradle apply-script 弃用;部分依赖 Kotlin metadata 1.8.0 vs 工程预期 1.6.0。均属上游,debug/release 均通过。APK 内嵌时间戳,哈希不可位级复现。
## 越界比对
相对 `714794f`(本卡开工 HEAD):仅 `mobile-next/` 与本验收文档。
相对 `e26abad``mobile/``account-service/``config/``scripts/` **零改动**。本卡工作区 diff 不含 `pc-client/`
`FeatureFlags.livekitCall` 门控保持:配置不足时入口隐藏。
## 已测 / 未测
已测(替身或构建):
- Token 映射:callBg `#1D2129`、计时器 32px tabular figures、状态字 14px 白 60%、姓名 18px
- 未接超时 60s 单一来源(配置 / Styles / Guard
- 占线、重复信令、超时取消、销毁释放计时器
- Android debug/release 可构建
未测(缺外部条件,禁止写成通过):
- 无有效工号+密码,未登录
- Android ARM64 真机:呼入呼出、听筒/扬声器、静音、后台/锁屏、铃声与每秒震动
- 结束/失败 1.5s 退场与 250ms 滑入滑出的真机观感
- 「未接通话」系统消息在会话里的真机展示
## 风险与回退
- 真机铃声/震动依赖设备振动器与勿扰模式,静态审查不能代替点验
- 结束态 1.5s 内重复回调被 `_ending` 吞掉,属有意防护
- 回退:先 `git revert` 本验收提交,再 `git revert` 视觉返工提交
+99
View File
@@ -0,0 +1,99 @@
# B-225 双端验收包无法联网
分支:`agent/agent/a4ad7eed`(基于问题基线 `18d890ae7fdf66fa4df67360469f0f143641666a`
施工依据:B-148 第13阶段返工;对照旧包 `v1.0.6-internal-test`、故障预发布 `v3.8.3-internal-acceptance`、本卡新源码与新产物。
本卡只修客户端/构建配置并重打候选包,不改现网服务、不覆盖 Gitea 预发布 tag、不把构建成功当成真机联网通过。
**结论:Windows 根因是 Vite 未注入 `VITE_*`,登录打到 `undefined`Android 根因是默认 host 为官方占位域名,且回退端口 10008/10009 已关闭。候选包产物级已写入公司内网地址。真机登录未测。**
## 根因(产物对照,不是猜)
公司内网现况(构建机只读探测 `192.168.200.11`):10001 / 10002 / 10010 / 17880 开;官方 chat 默认口 10008 / 10009 关。账号服务 `POST /api/login` 有业务响应。
| 对照项 | 旧可用包 `v1.0.6-internal-test` | 故障预发布 `v3.8.3-internal-acceptance` | 本卡源码 + 候选包 |
|---|---|---|---|
| Windows 登录 | asar 字面量 `http://192.168.200.11:10010/api/login` | asar 为 `` `${{}.VITE_ACCOUNT_URL}/api/login` ``Vite 空对象) | asar 字面量 `http://192.168.200.11:10010` 等四条地址 |
| Windows IM / LiveKit | `:10002` / `:10001` / `:17880` 字面量 | 同样未注入 | 同上,四条均字面量 |
| Android `libapp.so` | 仅公司地址 | 公司地址 + `your-server-ip or your-domain` + `:10008` | 公司四条地址;`your-server-ip` / `:10008` / `:10009` 为 0 |
Windows 直接原因:仓库根 `.gitignore` 忽略 `.env`B-213 打包时没有 `.env` / `.env.production``vite build` 把 `import.meta.env.VITE_*` 编成空对象属性。
Android 直接原因:`Config._host` 不是 IP,启动默认走 HTTPS 假域名;`HttpUtil.init()` 在 `CompanyBootstrap` 之前拍死 `dio.baseUrl``ApiService.setBaseUrl` 曾只写 host 不带 `http://` 和端口;`Urls` 的 `static final` 第一次读取会冻结错误 URL;官方 chat 口已关,公司账号口是 10010。
## 最小修复
| 端 | 改动 | 作用 |
|---|---|---|
| PC | 新增 `pc-client/.env.production`(可入库) | `vite build` 默认 production 能注入内网地址 |
| PC | 新增 `pc-client/src/config/endpoints.ts`,登录/目录/RTC/IM 改走兜底常量 | 即使漏加载 env,也不会变成 `undefined` |
| Android | `Config._host = 192.168.200.11`auth/chatToken 回退 10008/10009 → 10010 | 默认不再走假域名和已关闭端口 |
| Android | `HttpUtil.setBaseUrl`bootstrap 写入完整 `AppEndpoints.apiAddr` | 启动后 Dio / ApiService 指向 `http://192.168.200.11:10002` |
| Android | `Urls` 改为 getter | DataSp 写入后 URL 会跟着更新 |
未改:`account-service/`、docker、端口、现网数据、`mobile/` 旧工程。
## 提交与回退
从新到旧回退:先本验收记录,再联网修复。
| 主题 | SHA | 文件 |
|---|---|---|
| 本验收记录 | 本文件当次提交 | `docs/acceptance/b225-network-fix.md` |
| 联网修复 | `bbc4dce0b61b44447f84732d841b8a66e3a2f4be` | `pc-client/.env.production`、`pc-client/src/config/endpoints.ts`、PC 调用点、Android Config/Urls/HttpUtil/bootstrap |
回退示例(新到旧):
```
git revert <本验收提交>
git revert bbc4dce0b61b44447f84732d841b8a66e3a2f4be
```
用户侧继续用旧包 `v1.0.6-internal-test`。不要回退到故障预发布 `v3.8.3-internal-acceptance`。
代码侧也可把分支重置回 `18d890ae7fdf66fa4df67360469f0f143641666a`。回退不影响现网服务与已发布旧包。
## 环境
- Flutter 3.24.5 / Dart 3.5.4`C:\devtools\flutter_3.24.5`
- Temurin JDK 17.0.20
- Android SDKplatform-tools、platforms;android-34、build-tools;34.0.0
- Node v24.5.0`pc-client` `npm install --ignore-scripts` 后 `npm run build` + `npx electron-builder --win --x64`
- `GRADLE_OPTS=-Xmx4096M`
## 候选包(未发布,未覆盖 `v3.8.3-internal-acceptance`
构建基线 HEAD`18d890ae7fdf66fa4df67360469f0f143641666a` + 本卡两提交。
| 产物 | 版本 | 大小 | SHA256 | 路径 |
|---|---|---|---|---|
| Android release APK | 3.8.3 | 53,288,459 B | `3709E9B24F2F8B12B9BD931D6633DC101C186367B5C3E704DD91D67DCB791B86` | `mobile-next/build/app/outputs/flutter-apk/app-release.apk` |
| Windows NSIS EXE | 1.0.2 | 105,893,401 B | `F16B421857C341016E4375A869C53FF80B1028E49F84A59FE43C93D50FCC866C` | `pc-client/release/Base/1.0.2/畅联_1.0.2.exe` |
故障预发布对照(不要当候选):
| 产物 | SHA256 |
|---|---|
| APK `v3.8.3-internal-acceptance` | `41261A1BEBD00597D16B50A0D01A261AF592129C5F28014B423A1AAE07AE7C73` |
| EXE `v3.8.3-internal-acceptance` | `25491BA9A19E181144602F81991993DBF3350A3981BD1CC82354949A83B0E645` |
产物抽检:
- 新 EXE `app.asar``http://192.168.200.11:10010` / `:10002` / `ws://...:10001` / `:17880` 各 1 次;`VITE_ACCOUNT_URL`、`{}.VITE_`、`undefined/api/login` 为 0。
- 新 APK `lib/arm64-v8a/libapp.so`:上述四条公司地址各 1 次;`your-server-ip`、`:10008`、`:10009` 为 0。
APK 内嵌时间戳,哈希不可位级复现。构建期告警同前:Flutter Gradle apply-script 弃用;部分依赖 Kotlin metadata 1.8.0 vs 工程预期 1.6.0。均属上游,release 通过。
## 已测 / 未测
已测:
- 构建机到 `192.168.200.11` 的 10001/10002/10010/17880 端口开,10008/10009 关
- 账号服务对错误工号返回业务 JSON(服务本身在)
- `npm run build`、`electron-builder --win --x64`、`flutter build apk --release` 成功
- 新旧产物字符串对照如上
未测(不得写成已通过):
- 公司内网真机 / 真 PC 用工号登录
- 登录后会话列表、发消息、音视频
- 本候选包安装覆盖旧包后的升级路径
@@ -0,0 +1,64 @@
# B-261 Android「我的信息」404
分支:本卡施工分支(基于联网修复复测包 `1895830` / `agent/agent/a4ad7eed`
对照用户安装包:Gitea `v3.8.3-network-fix-retest``changlian-android-3.8.3-b225.apk`
本卡只改客户端用户资料读取,不改现网服务、不改账号数据、不覆盖旧 Release。
**结论:404 是客户端把官方 chat 接口打到了账号服务。责任在客户端。已改为走 OpenIM SDK,不再请求 `/user/find/full`。**
## 直接原因
用户截图:`GET http://192.168.200.11:10010/user/find/full` → 404。
| 核对项 | 结果 |
|---|---|
| 账号服务真实路由 | 只有 `/api/login``/api/directory``/api/rtc_token`、管理接口;没有 `/user/find/full` |
| 现网探测 | `GET/POST http://192.168.200.11:10010/user/find/full` 均 404`GET /api/health` 200,员工数 3 |
| 当前发布包调用方 | 官方页「我的信息」走 `Apis.queryMyFullInfo()``HttpUtil.post(Urls.getUsersFullInfo)` |
| URL 来源 | B-225 把 `Config.appAuthUrl` 从已关闭的 :10008 改到 :10010,登录能通,但这条 chat 路径仍打到账号服务 |
| 代码方法 | 源码是 POST;GET/POST 对不存在的路径都是 404,和截图一致 |
`mobile/` 和 PC 早已用 OpenIM SDK 取资料,不打这条路径。新 `mobile-next/` 漏改。
责任边界:客户端请求了账号服务没有的接口。不是工号密码错误,也不是服务器宕机。不需要改现网。
## 最小修复
`Apis.getUserFullInfo` / `queryMyFullInfo` / `searchUserFullInfo` / `updateUserInfo` 改为 OpenIM SDK(与 PC `pc-client/src/api/login.ts` 同一策略)。
- 能同步:工号、昵称、头像、勿扰
- 不再有值:手机号、邮箱、性别、生日等原 chat 业务字段
- 未改:`account-service/`、docker、旧 `mobile/`、PC
## 回退
从新到旧:`git revert` 本验收记录提交,再 `git revert` 代码提交。用户侧可继续用 `v3.8.3-network-fix-retest` 或旧包 `v1.0.6-internal-test`
## 构建
- Flutter 3.24.5 / Dart 3.5.4 / Temurin 17.0.20
- `flutter build apk --release` 成功
- 上游告警同 B-225Flutter Gradle apply-script 弃用;部分依赖 Kotlin metadata 1.8.0 vs 工程预期 1.6.0。release 通过。
| 产物 | 版本 | 包名 | 大小 | SHA256 |
|---|---|---|---|---|
| Android release APK | 3.8.3+180 | `io.openim.flutter.demo` | 53,286,915 B | `42D74E85AEC52A3889ED79CE7345C3BA5F69B4B3FA994032C2D38DF6A9CF5987` |
路径:`mobile-next/build/app/outputs/flutter-apk/app-release.apk`(APK 内嵌时间戳,哈希不可位级复现)
## 已测 / 未测
已测:
- 现网 `:10010/user/find/full` GET/POST 404`/api/health` 200
- `UserFullInfoMapper` 单测 3 项通过
- 改动文件 `flutter analyze` 无新增 error(剩余 8 条均为 `apis.dart` 原有 warning/info
- Android release 构建通过,校验值见上表
- `Apis` 不再引用 `Urls.getUsersFullInfo` / `updateUserInfo` / `searchUserFullInfo`
未测(不得写成已通过):
- 公司内网真机登录后打开「我的信息」
- 登录、联系人、发消息完整回归
残余:官方 `searchFriendInfo`、改密、验证码仍指向已下线 chat 路径;工号登录主路径和「我的信息」不再走这些接口。
@@ -0,0 +1,103 @@
# B-273 Android 悬浮窗、语音文案与位置发送清理
分支:`agent/agent/3f3d8cc3`(基于 `agent/agent/2b5c0459` HEAD `092039b`
施工依据:B-269 第七、八、十节;B-91 视觉规范 v2(本卡不做换肤)。
本卡只改 `mobile-next/` 客户端,不发布、不改现网、不覆盖 Gitea Release。
**结论:三项清理已落地;Android release 真实构建通过。缺真机账号,首次安装权限弹窗、前后台语音、历史位置消息展示继续标为未测。**
## 基线
- 开工 HEAD`092039b` `fix(mobile-next): 收口我的信息只读字段显示`
- 远端 `origin/agent/agent/2b5c0459` 与开工提交一致,未覆盖他人变更
## 三项对照
| # | 目标 | 修改位置 | 结果 |
|---|---|---|---|
| 1 | 去掉悬浮窗 | `AndroidManifest.xml``tools:node="remove"` 剔除 `SYSTEM_ALERT_WINDOW`;删除 IM 同步后申请;删除旧 `CallService` 声明;来电不再走 overlay 分支 | 合并清单无悬浮窗权限、无 `CallService` |
| 2 | 通话入口改成语音 | `toolboxCall` / `audioAndVideoCall` →「语音通话」;资料页改麦克风图标;通话选择表只留语音;三个入口仍只发 `CallType.audio` | 相册「拍摄」和「视频」消息文案未改 |
| 3 | 去掉位置发送 | 工具箱/选点页/`sendLocation` 删除;去掉 `geolocator`;定位权限 `tools:node="remove"`;保留历史位置气泡与 `MapView`,解析失败回退「位置消息」+ 地址 | 合并清单无定位权限 |
旧插件 `local_plugin/flutter_openim_live_alert` 未物理删除(B-269:可先停用、另卡再删),应用清单已不再声明其服务。
`REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` 仍由 `flutter_background`(已接通通话前台服务)合并进来;客户端登录/同步不再申请。`CALL_PHONE` / `READ_PHONE_STATE` / `REQUEST_INSTALL_PACKAGES` 仍有拨号、WebRTC、升级外链用途,未动。
## 提交主题(可逐项 `git revert`
从新到旧回退:先本验收记录,再测试,再代码。
| 主题 | SHA | 文件 |
|---|---|---|
| 本验收记录 | 本文件当次提交 | `docs/acceptance/b273-android-client-cleanup.md` |
| 定向测试 | `1774e59` | `mobile-next/test/company/b273_client_cleanup_test.dart` |
| 三项清理代码 | `694891c` | 悬浮窗、语音文案、位置发送 |
回退示例(新到旧):
```
git revert <本验收提交>
git revert 1774e59
git revert 694891c
```
回退不影响 `mobile/``pc-client/``account-service/``config/``scripts/`、现网服务与已发布安装包。
## 环境
- Flutter 3.24.5 / Dart 3.5.4`C:\flutter324`
- Temurin JDK 17.0.20+8
- Android SDK:既有 B-95 工具链(compileSdk 34
- `org.gradle.jvmargs=-Xmx4096M`
## 检查与构建
### 定点测试
```
cd mobile-next
flutter test test/company/b273_client_cleanup_test.dart test/company/call_visual_rework_test.dart test/company/call_session_guard_test.dart test/company/rtc_token_mapper_test.dart test/company/user_full_info_mapper_test.dart
```
25 项通过:清理清单/文案/位置回退、通话视觉 Token、占线/去重/超时、换票映射、「我的信息」映射。
定点 `flutter analyze` 修改文件:**0 error**。存量 info/warning 未作为本卡阻塞。
### Android(真实构建)
```
cd mobile-next
flutter build apk --release
```
| 产物 | 版本 | 包名 | 大小 | SHA256 |
|---|---|---|---|---|
| Android release APK | 3.8.3+180 | `io.openim.flutter.demo` | 53,096,372 B | `F50D9DAA57D4BCCA6A4841F2B8156E034C794C859CEDD3C02B7856103E084913` |
路径:`mobile-next/build/app/outputs/flutter-apk/app-release.apk`(APK 内嵌时间戳,哈希不可位级复现)
构建期告警同 B-261Flutter Gradle apply-script 弃用;部分依赖 Kotlin metadata 1.8.0 vs 工程预期 1.6.0。release 通过。
合并清单 `build/app/intermediates/merged_manifests/release/AndroidManifest.xml`**无** `SYSTEM_ALERT_WINDOW`、**无** `ACCESS_*LOCATION`、**无** `CallService`
候选包只附本卡,未发布 Gitea Release。
## 已测 / 未测
已测:
- 定点测试 25 项通过
- 改动文件 `flutter analyze` 无新增 error
- Android release 构建通过,合并清单无悬浮窗/定位权限
- 通话三个入口源码仍只发 `CallType.audio`;相册/拍摄/视频消息代码未删
未测(不得写成已通过):
- 真机首次安装、登录、IM 同步是否还弹出「显示在其他应用上层」
- 前后台/锁屏语音呼出与来电
- 历史位置消息真机展示与地图不可用回退
- 工具箱相册/拍摄/文件/名片真机回归
## 越界比对
相对 `092039b`:仅 `mobile-next/` 与本验收文档。`mobile/``pc-client/``account-service/`、现网配置 **零改动**
+37
View File
@@ -0,0 +1,37 @@
# PC 端可改边界封存(docs/acceptance
> 依据架构方案 B-90 的 PC 目录边界。B-185 第二批只改界面层,通信核心仍冻结。
## 不可动(通信核心,冻结)
| 目录/文件 | 内容 | 理由 |
|---|---|---|
| `pc-client/electron/` | 主进程、预加载、SDK 资产与打包核心 | 进程/打包核心。特批仅 `windowManage.ts``minWidth=1080``minHeight=680` |
| `pc-client/src/store/` | 会话 / 联系人 / 用户状态 | 状态唯一来源 |
| `pc-client/src/layout/MainContentWrap.tsx` | SDK 初始化与连接 | SDK 入口 |
| `pc-client/src/pages/chat/queryChat/ChatFooter/useSendMessage.ts` | 消息发送 | 发送核心 |
| `pc-client/src/pages/chat/queryChat/useHistoryMessageList.tsx` | 历史消息 | 历史核心 |
| SDK 版本 | `@openim/electron-client-sdk ^3.8.3-patch.10``@openim/wasm-client-sdk ^3.8.3-patch.10` | 锁定版本 |
## 可改(界面层)
| 目录 | 内容 |
|---|---|
| `pc-client/src/layout/LeftNavBar/` | 导航外观 |
| `pc-client/src/pages/login/**` | 登录窗展示(校验三态、窗内顶栏提示;不改登录接口) |
| `pc-client/src/pages/chat/**` | 会话栏、空会话页、聊天窗**展示**(顶栏/气泡/输入区样式、右键置顶删除、大图预览样式) |
| `pc-client/src/pages/contact/**` | 联系人展示、职务行、部门分组 |
| `pc-client/src/pages/common/AddColleague.tsx` | 添加同事弹窗五态与文案 |
| `pc-client/src/components/**` | 通用 UI 组件 |
| `pc-client/src/styles/` | 统一视觉 Token 唯一来源 |
| `pc-client/src/i18n/resources/` | 界面文案 |
聊天目录中下列文件仍冻结,即使位于 `pages/chat/**`
- `queryChat/ChatFooter/useSendMessage.ts`
- `queryChat/useHistoryMessageList.tsx`
## 明确禁止
- 不建设 PC 语音通话:不提供发起/接听/来电入口;本批已从聊天顶栏去掉「语音通话」。RTC 死代码按 B-90 保留以便回滚。
- 不改 `electron/`(窗口下限两常量除外)、`src/store/`、SDK 初始化、消息发送与历史逻辑。
+44
View File
@@ -0,0 +1,44 @@
# mobile-next SDK 兼容门禁验收记录(docs/acceptance
> 目标:官方 `mobile-next` 基线只把 `flutter_openim_sdk` 切到 `3.8.3+hotfix.12` 后,对接现网
> OpenIM API `http://192.168.200.11:10002` / WS `ws://192.168.200.11:10001`)完成双机冒烟。
> 任一核心门禁失败即停止后续迁移并在本卡汇报;不得以「同属 3.8.3」代替实测。
## 冒烟矩阵(2026-08-19,两 x86_64 模拟器 emulator-5554/5556,真实 OpenIM 现网)
- 测试账号:`t1001`Test Oneemulator-5554)、`t1002`Test Twoemulator-5556)。
- 登录凭据: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`GoLog 日志) |
| 2 | 登录(userID+imToken | 双端自动登录 | 通过 | 双端 `login start``login success`82ms/161ms)→ `conn start`ws sendID/tokensdkVersion=3.8.0)→ `onConnectSuccess` |
| 3 | 会话同步 | 启动拉取会话 | 通过 | 双端 `get_full_conversation_ids` 返回 `si_t1001_t1002`;UI 会话列表可见「Test Two」及群会话 |
| 4 | 断线重连 | 开/关飞行模式 | 通过 | 断网 `onConnectFailed` + `reConn`dial tcp network unreachable);恢复后 `reConn``connSuccess``onConnectSuccess``syncEnded` |
| 5 | 好友 | 通讯录→My Friends / 服务端 `get_friend_list` | 通过 | 服务端返回 t1001↔t1002 好友关系(friendUser t1002 "Test Two"addSource 2);UI 通讯录可见 |
| 6 | 群组 | 服务端 `get_joined_group_list` / UI 群会话 | 通过 | t1001 已入群 `hotfix-grp-test`groupID 1893538836 / 1481671100);UI 会话列表可见群会话 |
| 7 | 文字消息 A→B | t1001 发送 | 通过 | `B95TextAtoB_154855`seq 13status 2),t1002 收到(received a new messageunreadCount 1),服务端落库复核 |
| 8 | 文字消息 B→A | t1002 发送 | 通过 | `B95TextBtoA_155112`seq 14status 2),t1001 收到,服务端落库复核 |
| 9 | 图片消息 | 相册选图发送 | 通过 | contentType 102URL `msg_picture_…png`t1002 收到(B-137 基线同码实测,服务端 `/msg/search_msg` status 2 |
| 10 | 文件消息 | 文件选择器发送 | 通过 | contentType 105`hotfix-file-test.txt` 66B 上传,t1002 UI 显示文件卡片(B-137 基线同码实测,status 2 |
| 11 | 语音消息 | 按住说话 | 通过 | contentType 103`.m4a` 33,866B 上传,t1002 收到(B-137 基线同码实测,status 2 |
服务端 `/msg/search_msg` 复核:消息均 `status=2`(已发送)。
## 完成标准核对
- [x] `mobile-next` 官方原版 debug/release 可复现构建(见 `docs/upstream/build-and-rollback.md`,本卡实测 SHA256 与包/签名)。
- [x] SDK hotfix.12 兼容冒烟逐项有「通过」结果与证据(初始化/登录/会话同步/断线重连/好友/群组/文字双向/图片/文件/语音),非版本号相近代替实测。
- [x] 任一核心门禁失败即停止:本阶段全部通过,可进入后续公司功能迁移(第 4 阶段)。
- [x] 旧版 `mobile/``pc-client/``account-service/`、现网服务器与已发布安装包均未改动。
## 已知差异 / 备注
- 登录链路:HTTP 工号密码校验(account-service `/api/login`)属公司业务层,本阶段未接入 mobile-next(符合「不得公司业务迁移」);SDK 登录使用与账号服务同源的 userID+imToken 实测通过。
- hotfix 插件自身 `android/build.gradle` 声明 AGP 8.7.3/compileSdk 35,被应用工程工具链(AGP 7.3.1/compileSdk 34)覆盖,行为以应用工程为准,双构建均通过。
- 语音通话(LiveKit)不在本阶段范围,未测。
- 图片/文件/语音三条在 B-137 基线以相同代码完成实测,本卡按同码基线复核服务端落库记录。
## 回退
`docs/upstream/build-and-rollback.md`SDK 接入提交(`2c9dab1`)改 3 个 `pubspec.yaml` + 1 个 `pubspec.lock` + 1 个实测记录文档,可单独 `git revert`(会一并撤掉该文档)。
@@ -0,0 +1,18 @@
# 视觉规范唯一来源与 Token 入口(docs/acceptance
唯一视觉规范:B-91 附件 `changlian-visual-spec-v2.md`(自发布起替代 v1)。本阶段按 v2 落地 Token,保留 OpenIM 标识,**不做「畅联」换标**。
## 手机端唯一 Token 入口
| 层级 | 路径 | 职责 |
|---|---|---|
| 规范取值(唯一来源) | `mobile-next/lib/company/brand/app_tokens.dart` | 色值/字号/间距/圆角/动效时长,禁止页面硬编码 |
| 官方映射 | `mobile-next/lib/company/brand/apply_official_styles.dart` | 启动时把 `openim_common` `Styles` 静态色对齐到 Token |
| 主题 | `mobile-next/lib/company/brand/app_theme.dart` | `ThemeData`,由 `lib/app.dart` 使用 |
| 内网地址 | `mobile-next/lib/company/config/app_endpoints.dart` | IP/端口唯一入口,页面不得再写死 |
施工铁律:改样式只改 Token 与上述映射,禁止在页面叠加新 CSS/颜色覆盖旧样式。
## PC 端唯一 Token 入口
`pc-client/src/styles/global.scss``:root` CSS 变量为 PC 唯一来源。界面层只改 `docs/acceptance/pc-boundary.md` 列明的目录。
+115
View File
@@ -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 stablerevision `dec2ee5c1f`engine `a18df97ca5` |
| Dart | 3.5.4(随 Flutter 3.24.5 分发) |
| JDK | OpenJDK 17.0.20+8Temurin |
| 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 34minSdk 24targetSdk 33build-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)高于工程 Kotlin1.9.23 预期 1.6.0/1.8.0)的警告,属于上游依赖组合特性,debug/release 均通过。
## 失败证据
本阶段 debug 与 release 均构建成功,无失败步骤。若后续步骤出现构建失败,按完成标准须明确到具体依赖或构建步骤并留存日志,不再继续后续兼容迁移。
## 回退方法
本任务为独立提交,仅新增 `mobile-next/` 与本文档,未触碰 `mobile/``pc-client/``account-service/` 及现网服务。
回退命令:
```
git revert 8046ec7483d68f67011913da12e5e671479b5ff0
```
或直接删除并行目录(不影响现网):
```
git rm -r mobile-next
```
## 备注
- 本目录仅证明「官方固定基线可稳定构建」,不含任何公司定制逻辑,尚未接入公司账号/品牌,属后续阶段工作。
+109
View File
@@ -0,0 +1,109 @@
# mobile-next 通信组件热修接入与核心能力实测记录(B-95/B-137)
> 基线:`8046ec7`(官方 openim-flutter-demo 3.8.3-patch.3 固定基线导入)。
> 本阶段只做一件事:把 `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.20Temurin)、Android SDKplatforms 34/35/36build-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 badgingdebug 与 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` 送达 t1002seq 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 8hasReadTime 回执) |
| 9 | 文件消息 | 文件选择器发送 | 通过 | `contentType 105``hotfix-file-test.txt` 66B 上传,t1002 UI 显示文件卡片(seq 9 |
| 10 | 语音消息 | 按住说话 | 通过 | `contentType 103``.m4a` 33,866B 上传,t1002 收到(seq 10duration 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 2c9dab160eefcaa5a4ad76a24ec2948bffaccc7e
```
或手动把 4 个文件的 `flutter_openim_sdk` 改回 `3.8.3+3``flutter pub get``mobile/``pc-client/``account-service/`、服务器与现网均不受影响。
+58
View File
@@ -0,0 +1,58 @@
# mobile-next 官方固定基线(docs/upstream
## 上游来源与固定版本
| 项 | 值 |
|---|---|
| 上游仓库 | `https://github.com/OpenIMSDK/openim-flutter-demo.git` |
| 固定标签 | `3.8.3-patch.3` |
| 固定提交 | `b3dfdb1e8aaeaaf6f0793e10cadd20d5c184a31f`"Updated IM SDK"2025-03-07 |
| 校验方式 | `git ls-remote --tags` 解析 tag `^{}` 指向即上述提交 |
| 许可证 | OpenIM Open Source LicenseAGPL-3.0 + 附加条款),原文随导入保留在 `mobile-next/LICENSE`;子包 `openim_common/LICENSE``openim_live/LICENSE``local_plugin/flutter_openim_live_alert/LICENSE` |
> 必须固定在该提交,禁止追随上游 `main`。重建基线命令见 `docs/upstream/build-and-rollback.md`。
## 与本卡仓库(tongxunruanjian)的差异
基线在官方原版基础上只做了「必须才能构建/入库」的最小改动,**业务代码零改动**。与上游提交 `b3dfdb1e` 整树比对(`git diff b3dfdb1e 8046ec7:mobile-next`)的实际差异如下。
| 项 | 差异 | 说明 |
|---|---|---|
| `mobile-next/pubspec.lock` | `flutter_openim_sdk` 由锁文件 `3.8.3+2` 对齐为 `3.8.3+3` | `flutter pub get``pubspec.yaml` 声明 `3.8.3+3` 重新解析;上游锁文件落后于 pubspec。属官方产物,已披露。 |
| 6 个 `.dart` 文件 | 仅文件模式/权限位变化,blob 哈希完全相同 | 内容零改动,不属于业务差异。 |
| `.DS_Store` | 上游工作树中的 macOS 垃圾文件未随导入入库 | 删除/忽略,无源码改动。 |
| `mobile-next/.gitignore` | **与上游完全一致** | Flutter 构建产物忽略规则加在了**仓库根** `.gitignore`,不是 `mobile-next/.gitignore`。 |
除上表外,`mobile-next/` 与上游提交 `b3dfdb1e` 的跟踪内容一致(不含 `.git``build/``.dart_tool/` 等非跟踪内容)。**不存在未披露的业务改动。**
## 工具链锁定
| 工具 | 版本 | 位置 |
|---|---|---|
| Flutter | 3.24.5 stablerevision `dec2ee5c1f`engine `a18df97ca5` | `C:\flutter324` |
| Dart | 3.5.4(随 Flutter 3.24.5 分发) | 同上 |
| Java / JDK | Temurin 17.0.20+8 | `toolchain\jdk17` |
| Gradle | 7.6.3`mobile-next/android/gradle/wrapper/gradle-wrapper.properties` 锁定) | 自动下载缓存 |
| Android Gradle Plugin | 7.3.1`mobile-next/android/build.gradle` | - |
| Kotlin | 1.9.23`mobile-next/android/build.gradle` `ext.kotlin_version` | - |
| compileSdk / targetSdk / minSdk | 34 / 33 / 24`mobile-next/android/app/build.gradle` | - |
| build-tools | 36.0.0 | Android SDK |
| 依赖锁文件 | `mobile-next/pubspec.lock` | 已入库 |
### 关键依赖(对照)
| 依赖 | 版本 | 说明 |
|---|---|---|
| `flutter_openim_sdk` | 3.8.3+3(基线自带,仅对照);兼容门禁目标 `3.8.3+hotfix.12`(SDK 接入提交) | 升级差异见 SDK 接入提交与 `docs/acceptance/sdk-compat-gate.md` |
| `livekit_client` | 2.2.5(上游自带,仅对照;正式迁移不采用,保留现有 2.5.0+hotfix.3 | 不随本卡迁移 |
| `flutter_webrtc` / `dart_webrtc` | 0.12.10 / 1.5.2+hotfix.1(上游自带,仅对照) | 不随本卡迁移 |
## 许可证状态与门禁
- 本卡只构建并保留 OpenIM 标识与许可证的官方基线,不做「畅联」换标,不产出/发布试用或生产安装包。
- AGPL-3.0 附加条款(禁止未经授权的商业使用、禁止删除/修改/隐藏 OpenIM LOGO 与版权信息)的内部商用与换标边界,尚未取得书面结论;未确认前不得进入品牌迁移或对外/内部试用发布。
## 回退
- 基线导入提交:`git revert 8046ec7483d68f67011913da12e5e671479b5ff0`(本卡固定基线导入提交),可单独回退,不影响 `mobile/``pc-client/``account-service/` 与现网。
- 或直接删除并行目录:`git rm -r mobile-next`
+65
View File
@@ -0,0 +1,65 @@
# mobile-next 构建与回退方法(docs/upstream
## 前置环境
```bat
set JAVA_HOME=<JDK17 目录>
set ANDROID_HOME=<Android SDK 目录>
set PATH=%JAVA_HOME%\bin;<Flutter SDK 目录>\bin;%PATH%
set GRADLE_OPTS=-Xmx4096M
```
`mobile-next/android/local.properties` 需包含(本机路径,不入库):
```
sdk.dir=<Android SDK 目录,反斜杠转义>
flutter.sdk=<Flutter SDK 目录,反斜杠转义>
```
首次依赖解析(生成 `.dart_tool`,不产生源码改动):
```
cd mobile-next
flutter pub get
```
## 构建命令
```bat
flutter build apk --debug :: 产物 build/app/outputs/flutter-apk/app-debug.apk
flutter build apk --release :: 产物 build/app/outputs/flutter-apk/app-release.apk
```
- release 使用上游自带 keystore `android/app/openim`alias/password 均为 `openim`),保留 OpenIM 标识与签名。
- 注意:上游 `android/app/build.gradle``ndk { abiFilters "arm64-v8a" }` 只打 arm64;如需 x86_64 模拟器联调,临时放开 `"x86_64"` 再还原(本地产物,不入库)。
## 本卡实测结果(2026-08-19,本机锁定环境)
| 构建 | 结果 | 产物 | 大小 | SHA256 |
|---|---|---|---|---|
| debug | 成功 | `app-debug.apk` | 109,454,925 B | `DD7D9700BC1F5830B7495875387948AAD536CA63FDC3EF66B4C0F4D152407B72` |
| release | 成功 | `app-release.apk` | 53,323,411 B | `4969AF4A4800A8E7C0B0C2F50687CB8C765925E4F2B3B7A53762D1D9E49CA604` |
> SHA256 与字节大小仅为**当次构建产物记录**,不是位级可复现承诺。APK 内嵌构建时间戳,换机/换次重跑时哈希必然不同;大小差通常在时间戳/元数据量级。可复现的是工具链、构建命令与包名/签名证书。B-149 复核重跑:debug 109,454,749 B(差 176 B)、release 53,323,375 B(差 36 B),签名证书 SHA-256 与上表一致。
APK 元数据(aapt badging):package `io.openim.flutter.demo`versionCode `180`versionName `3.8.3`minSdk 24 / targetSdk 33 / compileSdk 34。
release 签名(apksigner verify --print-certs):CN=openim,证书 SHA-256 `1f38a82fb3c33be7951fb5d964ef5bd9c6c9bfc084ae1e2a8a40a0d1f44ae1fe`,与官方基线同一 keystore。
构建期告警(不影响产物):Flutter Gradle 插件 apply-script 弃用提示;部分依赖 Kotlin metadata 版本(1.8.x)高于工程 Kotlin1.9.23 预期 1.6.0/1.8.0)的警告,均属上游依赖组合特性,debug/release 均通过。
## 失败停止点
任一核心门禁失败即停止后续迁移,在本卡汇报并附错误证据,不得继续迁移。本阶段 debug/release 均构建成功,无失败步骤。
## 逐提交回退
本卡分支基于回退基线 `fa8584a`,主题提交相互独立,可单独回退:
| 主题 | 提交 | 回退命令 |
|---|---|---|
| 官方基线导入 + 双构建 | 8046ec7483d68f67011913da12e5e671479b5ff0 | `git revert 8046ec7483d68f67011913da12e5e671479b5ff0``git rm -r mobile-next` |
| SDK hotfix.12 接入 + 核心能力实测 | 2c9dab160eefcaa5a4ad76a24ec2948bffaccc7e | `git revert 2c9dab160eefcaa5a4ad76a24ec2948bffaccc7e` |
`2c9dab1` 实际包含 **5 个文件**`mobile-next/pubspec.yaml``openim_common/pubspec.yaml``openim_live/pubspec.yaml``mobile-next/pubspec.lock`,以及实测记录文档 `docs/mobile-next-hotfix-sdk-verification.md``git revert` 会一并撤掉该文档,不只是 4 个依赖文件。
回退任一提交均不影响 `mobile/``pc-client/``account-service/`、现网服务器与已发布安装包。SDK hotfix 提交的手动回退:把上述 3 个 `pubspec.yaml``flutter_openim_sdk` 改回 `3.8.3+3``flutter pub get`(锁文件随之回写;实测记录文档需另行保留或删除)。
+4
View File
@@ -0,0 +1,4 @@
/.flutter-plugins
/.flutter-plugins-dependencies
/.packages
/.dart_tool/
+88
View File
@@ -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.
+88
View File
@@ -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. 海外地区使用 [FCMFirebase 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';
```
完成配置后即可启用地图功能。
+45
View File
@@ -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/>.
+257
View File
@@ -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
![ios cpu](https://user-images.githubusercontent.com/7018230/155913400-6231329a-aee9-4082-8d24-a25baad55261.png)
##### 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)
+253
View File
@@ -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。
```
![ios cpu](https://user-images.githubusercontent.com/7018230/155913400-6231329a-aee9-4082-8d24-a25baad55261.png)
##### 7. iOS 最低运行版本是多少?
答:13.0
##### 8. 地图为什么不能使用?
答: [文档](CONFIGKEY.zh-CN.md)
##### 9. 离线推送为什么不能使用?
答: [文档](CONFIGKEY.zh-CN.md)
+29
View File
@@ -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
+13
View File
@@ -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
+188
View File
@@ -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"
}
Binary file not shown.
+206
View File
@@ -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,154 @@
<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" />
<!-- B-273: 彻底移除悬浮窗;合并清单也禁止依赖再声明 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" tools:node="remove" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<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" />
<!-- B-273: 位置发送已移除,合并清单禁止再声明定位权限 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" tools:node="remove" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" tools:node="remove" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" tools:node="remove" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" tools:node="remove" />
<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_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.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" />
<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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

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>
+64
View File
@@ -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
}
+3
View File
@@ -0,0 +1,3 @@
org.gradle.jvmargs=-Xmx4096M
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
+11
View File
@@ -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"
+52
View File
@@ -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
}
}
+3
View File
@@ -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:
Binary file not shown.

After

Width:  |  Height:  |  Size: 496 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 KiB

+1
View File
@@ -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"}}}}}}
+13
View File
@@ -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
+138
View File
@@ -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'
BIN
View File
Binary file not shown.
+34
View File
@@ -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>
+2
View File
@@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
+2
View File
@@ -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)
}
}
}
+99
View File
@@ -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
+505
View File
@@ -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>
+74
View File
@@ -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"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 970 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

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"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

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>
+99
View File
@@ -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>

Some files were not shown because too many files have changed in this diff Show More