diff --git a/README.md b/README.md index b4c8b22..79811d0 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Android APK: - 已生成 Android debug APK:`android/app/build/outputs/apk/debug/app-debug.apk` - 已生成 Android signed release APK:`android/app/build/outputs/apk/release/app-release.apk` - `npm run apk:release` 还会额外产出带版本号的文件:`android/app/build/outputs/apk/release/boss-android-v{versionName}-release.apk` -- 当前最新 release 构建版本:`2.5.3`(`versionCode=16`) +- 当前最新 release 构建版本:`2.5.4`(`versionCode=17`) - 当前 APK 已切到原生 Android 客户端:`MainActivity + BossApiClient + 原生 XML 布局` - 当前原生活动页已经覆盖:会话首页、项目详情、项目目标、版本记录、会话信息、群资料、发起群聊、消息转发、线程详情、设备详情、添加设备、账号与安全、设置、AI 账号、技能、运维中心、关于 - 当前原生一级体验已回退到微信式交互:`会话 / 设备 / 我的` 固定底部 tab,会话首页是简单聊天列表,`主 Agent / 审计对话` 以普通置顶会话样式排在最前;项目详情页是聊天优先,只保留 `项目目标 / 版本记录` 两个轻入口 @@ -117,7 +117,7 @@ Android APK: - `2.5.0` 已补齐聊天附件主链:原生聊天框左侧 `+` 会打开底部抽屉,支持图片 / 视频 / 文件发送;默认走服务器文件存储,`我的 > 附件与存储` 可切到阿里 OSS 私有桶;附件消息已支持下载 / 打开、手动分析、自动分析状态,以及带 task token 的主 Agent 附件分析链接 - `2.5.1` 继续收口微信式原生 UI:聊天页普通态顶部已隐藏刷新按钮,只保留右上角“信息”;发起群聊页顶部说明和选择区已压成更轻的会话式密度,候选线程继续复用微信式会话卡片 - `2.5.2` 继续补齐深层原生页:`项目目标 / 版本迭代记录 / 会话信息 / 群资料` 已进一步向设计图收口;附件消息卡片的分析状态和动作文案也压成了更轻的微信式层级 -- `2.5.3` 继续压缩原生聊天与建群页面:`发起群聊` 页已收成轻量头部 + hint pill + 一层操作区;聊天页里自己发出的消息顶部元信息已收成只显示时间,不再重复 `你 · 时间` +- `2.5.4` 已把 `我的` 根页收口成微信式资料区 + 白底菜单列表,并同步把 `设置 / 账号与安全 / AI 账号 / 技能 / 运维与修复` 的顶部说明从重 `soft panel` 降成轻量列表说明 ## 本地启动 diff --git a/android/app/build.gradle b/android/app/build.gradle index 6e71a71..c132930 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -36,8 +36,8 @@ android { applicationId "com.hyzq.boss" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 16 - versionName "2.5.3" + versionCode 17 + versionName "2.5.4" buildConfigField "String", "BOSS_API_BASE_URL", "\"https://boss.hyzq.net\"" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/android/app/src/main/java/com/hyzq/boss/AiAccountsActivity.java b/android/app/src/main/java/com/hyzq/boss/AiAccountsActivity.java index 6401f5e..8a56dcf 100644 --- a/android/app/src/main/java/com/hyzq/boss/AiAccountsActivity.java +++ b/android/app/src/main/java/com/hyzq/boss/AiAccountsActivity.java @@ -49,11 +49,13 @@ public class AiAccountsActivity extends BossScreenActivity { JSONArray accounts = payload.optJSONArray("accounts"); JSONObject activeIdentity = payload.optJSONObject("activeIdentity"); replaceContent(); - appendContent(BossUi.buildSoftPanel( + appendContent(BossUi.buildWechatMenuRow( this, "AI 账号", "这里统一管理主 GPT、备用 GPT 与 API 容灾账号。", - "轻点条目可编辑,按钮可切换、校验或删除。" + "轻点条目可编辑,按钮可切换、校验或删除。", + null, + null )); appendContent(buildActiveIdentityCard(activeIdentity)); appendContent(buildAccountsSection(accounts)); @@ -62,17 +64,27 @@ public class AiAccountsActivity extends BossScreenActivity { private LinearLayout buildActiveIdentityCard(@Nullable JSONObject activeIdentity) { if (activeIdentity == null) { - return BossUi.buildSoftPanel(this, "当前主控身份", "当前没有可用账号。", "请先新增或启用一个账号。"); + return BossUi.buildWechatMenuRow( + this, + "当前主控身份", + "当前没有可用账号。", + "请先新增或启用一个账号。", + null, + null + ); } - String body = activeIdentity.optString("label", "AI 账号") - + " · " + activeIdentity.optString("displayName", "-") - + "\n" + activeIdentity.optString("roleLabel", "-") - + " · " + activeIdentity.optString("providerLabel", "-"); - return BossUi.buildSoftPanel( + String subtitle = activeIdentity.optString("label", "AI 账号") + + " · " + activeIdentity.optString("displayName", "-"); + String meta = activeIdentity.optString("roleLabel", "-") + + " · " + activeIdentity.optString("providerLabel", "-") + + " · " + activeIdentity.optString("statusLabel", "-"); + return BossUi.buildWechatMenuRow( this, "当前主控身份", - body, - activeIdentity.optString("statusLabel", "-") + subtitle, + meta, + null, + null ); } diff --git a/android/app/src/main/java/com/hyzq/boss/BossUi.java b/android/app/src/main/java/com/hyzq/boss/BossUi.java index 08a3c34..2fa45b5 100644 --- a/android/app/src/main/java/com/hyzq/boss/BossUi.java +++ b/android/app/src/main/java/com/hyzq/boss/BossUi.java @@ -47,6 +47,28 @@ public final class BossUi { COMPACT_ICON } + public static String formatRoleLabel(@Nullable String rawRole) { + if (TextUtils.isEmpty(rawRole)) { + return ""; + } + switch (rawRole) { + case "highest_admin": + return "最高管理员"; + case "admin": + return "管理员"; + case "member": + return "成员"; + case "primary": + return "主 GPT"; + case "backup": + return "备用 GPT"; + case "api_fallback": + return "API 容灾"; + default: + return rawRole; + } + } + public static void applyTopActionButtonStyle(Context context, Button button, TopActionButtonStyle style) { if (style == TopActionButtonStyle.COMPACT_ICON) { button.setBackgroundResource(R.drawable.bg_secondary_button); @@ -232,7 +254,11 @@ public final class BossUi { @Nullable String badge, @Nullable View.OnClickListener listener ) { - return buildListRow(context, title, subtitle, meta, badge, listener); + LinearLayout row = buildListRow(context, title, subtitle, meta, badge, listener); + row.setBackgroundColor(Color.WHITE); + row.setElevation(0f); + row.setPadding(dp(context, 18), dp(context, 15), dp(context, 18), dp(context, 15)); + return row; } public static LinearLayout buildSimpleProfileHeader( @@ -248,23 +274,21 @@ public final class BossUi { LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT ); - params.leftMargin = dp(context, 12); - params.rightMargin = dp(context, 12); - params.bottomMargin = dp(context, 12); + params.bottomMargin = dp(context, 10); card.setLayoutParams(params); - card.setPadding(dp(context, 16), dp(context, 16), dp(context, 16), dp(context, 16)); - card.setBackground(createRoundedBackground(Color.WHITE, dp(context, 18))); - card.setElevation(dp(context, 1)); + card.setPadding(dp(context, 20), dp(context, 18), dp(context, 20), dp(context, 18)); + card.setBackgroundColor(Color.WHITE); + card.setElevation(0f); TextView avatar = new TextView(context); - LinearLayout.LayoutParams avatarParams = new LinearLayout.LayoutParams(dp(context, 64), dp(context, 64)); + LinearLayout.LayoutParams avatarParams = new LinearLayout.LayoutParams(dp(context, 70), dp(context, 70)); avatar.setLayoutParams(avatarParams); avatar.setGravity(Gravity.CENTER); avatar.setText(firstLetter(name)); - avatar.setTextSize(28); + avatar.setTextSize(30); avatar.setTypeface(Typeface.DEFAULT_BOLD); avatar.setTextColor(context.getColor(R.color.boss_green)); - avatar.setBackground(createRoundedBackground(Color.parseColor("#DFF3E8"), dp(context, 18))); + avatar.setBackground(createRoundedBackground(Color.parseColor("#DFF3E8"), dp(context, 35))); card.addView(avatar); LinearLayout textWrap = new LinearLayout(context); @@ -279,16 +303,16 @@ public final class BossUi { TextView titleView = new TextView(context); titleView.setText(TextUtils.isEmpty(name) ? "我的" : name); - titleView.setTextSize(17); + titleView.setTextSize(22); titleView.setTypeface(Typeface.DEFAULT_BOLD); titleView.setTextColor(context.getColor(R.color.boss_text_primary)); textWrap.addView(titleView); TextView subtitleView = new TextView(context); subtitleView.setText(subtitle); - subtitleView.setTextSize(13); + subtitleView.setTextSize(14); subtitleView.setTextColor(context.getColor(R.color.boss_text_muted)); - subtitleView.setPadding(0, dp(context, 4), 0, 0); + subtitleView.setPadding(0, dp(context, 5), 0, 0); textWrap.addView(subtitleView); if (!TextUtils.isEmpty(detail)) { @@ -296,7 +320,7 @@ public final class BossUi { detailView.setText(detail); detailView.setTextSize(12); detailView.setTextColor(context.getColor(R.color.boss_text_soft)); - detailView.setPadding(0, dp(context, 6), 0, 0); + detailView.setPadding(0, dp(context, 5), 0, 0); textWrap.addView(detailView); } @@ -543,13 +567,11 @@ public final class BossUi { LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT ); - params.leftMargin = dp(context, 12); - params.rightMargin = dp(context, 12); - params.bottomMargin = dp(context, 12); + params.bottomMargin = dp(context, 1); card.setLayoutParams(params); - card.setPadding(dp(context, 14), dp(context, 14), dp(context, 14), dp(context, 14)); - card.setBackground(createRoundedBackground(Color.WHITE, dp(context, 18))); - card.setElevation(dp(context, 1)); + card.setPadding(dp(context, 16), dp(context, 12), dp(context, 16), dp(context, 12)); + card.setBackgroundColor(Color.WHITE); + card.setElevation(0f); if (listener != null) { card.setClickable(true); card.setFocusable(true); @@ -566,12 +588,12 @@ public final class BossUi { 1f ); centerParams.leftMargin = dp(context, 12); - centerParams.rightMargin = dp(context, 8); + centerParams.rightMargin = dp(context, 10); centerColumn.setLayoutParams(centerParams); TextView titleView = new TextView(context); titleView.setText(TextUtils.isEmpty(row.threadTitle) ? "未命名会话" : row.threadTitle); - titleView.setTextSize(18); + titleView.setTextSize(17); titleView.setTypeface(Typeface.DEFAULT_BOLD); titleView.setTextColor(context.getColor(R.color.boss_text_primary)); titleView.setMaxLines(1); @@ -591,10 +613,10 @@ public final class BossUi { TextView previewView = new TextView(context); previewView.setText(TextUtils.isEmpty(row.lastMessagePreview) ? "暂无消息" : row.lastMessagePreview); - previewView.setTextSize(14); + previewView.setTextSize(13); previewView.setTextColor(context.getColor(R.color.boss_text_soft)); - previewView.setPadding(0, dp(context, 5), 0, 0); - previewView.setMaxLines(2); + previewView.setPadding(0, dp(context, 4), 0, 0); + previewView.setMaxLines(1); previewView.setEllipsize(TextUtils.TruncateAt.END); centerColumn.addView(previewView); diff --git a/android/app/src/main/java/com/hyzq/boss/MainActivity.java b/android/app/src/main/java/com/hyzq/boss/MainActivity.java index b06f6c8..8a67e0c 100644 --- a/android/app/src/main/java/com/hyzq/boss/MainActivity.java +++ b/android/app/src/main/java/com/hyzq/boss/MainActivity.java @@ -502,11 +502,14 @@ public class MainActivity extends AppCompatActivity { String account = sessionData == null ? apiClient.getAccountLabel() : sessionData.optString("account", apiClient.getAccountLabel()); + String roleLabel = sessionData == null + ? "" + : BossUi.formatRoleLabel(sessionData.optString("roleLabel", sessionData.optString("role", ""))); screenContent.addView(BossUi.buildSimpleProfileHeader( this, displayName, - "ChatGPT Plus · 主账号", - "主控账号已启用安全保护 · " + account + account, + (roleLabel.isEmpty() ? "主控账号已启用安全保护" : roleLabel + " · 主控账号已启用安全保护") )); for (WechatSurfaceMapper.MeMenuItem item : WechatSurfaceMapper.rootMeMenuItems()) { diff --git a/android/app/src/main/java/com/hyzq/boss/OpsCenterActivity.java b/android/app/src/main/java/com/hyzq/boss/OpsCenterActivity.java index 6a3c3a2..f06bf91 100644 --- a/android/app/src/main/java/com/hyzq/boss/OpsCenterActivity.java +++ b/android/app/src/main/java/com/hyzq/boss/OpsCenterActivity.java @@ -50,13 +50,15 @@ public class OpsCenterActivity extends BossScreenActivity { } private void renderOpsTab(JSONObject ops) { - contentRoot.addView(BossUi.buildSoftPanel( + contentRoot.addView(BossUi.buildWechatMenuRow( this, "巡检状态", ops.optString("mode", "idle").equals("active") ? "active:当前存在风险线程或未关闭运维工单。" : "idle:当前没有高风险工单,保持低频巡检。", - "这里只保留修复与验证的轻量入口。" + "这里只保留修复与验证的轻量入口。", + null, + null )); JSONArray faults = ops.optJSONArray("faults"); diff --git a/android/app/src/main/java/com/hyzq/boss/SecurityActivity.java b/android/app/src/main/java/com/hyzq/boss/SecurityActivity.java index 463a824..7a5562b 100644 --- a/android/app/src/main/java/com/hyzq/boss/SecurityActivity.java +++ b/android/app/src/main/java/com/hyzq/boss/SecurityActivity.java @@ -34,18 +34,20 @@ public class SecurityActivity extends BossScreenActivity { private void renderSecurity(@Nullable JSONObject session) { replaceContent(); - appendContent(BossUi.buildSoftPanel( + appendContent(BossUi.buildWechatMenuRow( this, "当前登录模式", "当前客户端仍使用快速进入模式。", - "需要更严格认证时,再切回账号密码或验证码登录。" + "需要更严格认证时,再切回账号密码或验证码登录。", + null, + null )); if (session != null) { appendContent(BossUi.buildWechatMenuRow( this, "当前会话", "账号 " + session.optString("account", "-") - + " · " + session.optString("role", "-"), + + " · " + BossUi.formatRoleLabel(session.optString("role", "-")), "登录方式 " + session.optString("loginMethod", "-") + " · 到期 " + session.optString("expiresAt", "-"), null, diff --git a/android/app/src/main/java/com/hyzq/boss/SettingsActivity.java b/android/app/src/main/java/com/hyzq/boss/SettingsActivity.java index 4b211fe..d6c64c0 100644 --- a/android/app/src/main/java/com/hyzq/boss/SettingsActivity.java +++ b/android/app/src/main/java/com/hyzq/boss/SettingsActivity.java @@ -69,11 +69,13 @@ public class SettingsActivity extends BossScreenActivity { preferredEntrySpinner.setAdapter(adapter); } - replaceContent(BossUi.buildSoftPanel( + replaceContent(BossUi.buildWechatMenuRow( this, "偏好设置", "调整默认首页和提醒行为。", - "保存后会直接写入 /api/v1/settings。" + "保存后会直接写入当前账号设置", + null, + null )); appendContent(BossUi.buildFormCell(this, "实时刷新", "会话、设备和 OTA 状态变化时自动更新", liveUpdatesSwitch)); diff --git a/android/app/src/main/java/com/hyzq/boss/SkillInventoryActivity.java b/android/app/src/main/java/com/hyzq/boss/SkillInventoryActivity.java index 518c62d..48b898d 100644 --- a/android/app/src/main/java/com/hyzq/boss/SkillInventoryActivity.java +++ b/android/app/src/main/java/com/hyzq/boss/SkillInventoryActivity.java @@ -119,11 +119,13 @@ public class SkillInventoryActivity extends BossScreenActivity { if (device != null) { deviceName = device.optString("name", deviceId); configureScreen("技能", deviceName); - appendContent(BossUi.buildSoftPanel( + appendContent(BossUi.buildWechatMenuRow( this, deviceName, "当前页按设备查看 Skill 清单。", - "Skill 由 local-agent 从本机 ~/.codex/skills 扫描并同步。" + "Skill 由 local-agent 从本机 ~/.codex/skills 扫描并同步。", + null, + null )); } diff --git a/android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java b/android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java index 4c1942a..4613c07 100644 --- a/android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java +++ b/android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java @@ -28,7 +28,7 @@ public class BossUiRootSurfaceTest { new JSONObject() .put("displayName", "Kris") .put("account", "17600003315") - .put("role", "最高管理员") + .put("role", "highest_admin") ); ReflectionHelpers.callInstanceMethod(activity, "renderMeRoot"); @@ -39,7 +39,7 @@ public class BossUiRootSurfaceTest { assertEquals("资料头不应保留浮层卡片感", 0f, header.getElevation(), 0.01f); assertTrue(viewTreeContainsText(header, "Kris")); assertTrue(viewTreeContainsText(header, "17600003315")); - assertTrue(viewTreeContainsText(header, "ChatGPT Plus · 主账号")); + assertTrue(viewTreeContainsText(header, "最高管理员")); assertTrue(viewTreeContainsText(header, "主控账号已启用安全保护")); assertTrue(viewTreeContainsText(content, "账号与安全")); @@ -48,12 +48,17 @@ public class BossUiRootSurfaceTest { assertTrue(viewTreeContainsText(content, "AI 账号")); assertTrue(viewTreeContainsText(content, "技能")); assertTrue(viewTreeContainsText(content, "关于")); + + for (int i = 1; i < content.getChildCount(); i += 1) { + View row = content.getChildAt(i); + assertTrue("我的页菜单应整行可点", row.isClickable()); + } } private static boolean viewTreeContainsText(View root, String expectedText) { if (root instanceof TextView) { CharSequence text = ((TextView) root).getText(); - if (expectedText.contentEquals(text)) { + if (text != null && text.toString().contains(expectedText)) { return true; } } diff --git a/docs/architecture/ai_handoff_index_cn.md b/docs/architecture/ai_handoff_index_cn.md index ace4cc8..a289d48 100644 --- a/docs/architecture/ai_handoff_index_cn.md +++ b/docs/architecture/ai_handoff_index_cn.md @@ -163,7 +163,7 @@ - 邮件:`Postfix + Dovecot` - Android:`AppCompatActivity + 原生 XML 布局 + HttpURLConnection` - 原生登录恢复:`SharedPreferences + restore token` -- 当前最新原生 APK:`2.5.3`(`versionCode=16`) +- 当前最新原生 APK:`2.5.4`(`versionCode=17`) 当前不要误判成已经用了: diff --git a/docs/architecture/current_runtime_and_deploy_status_cn.md b/docs/architecture/current_runtime_and_deploy_status_cn.md index 4e872fc..a8519cd 100644 --- a/docs/architecture/current_runtime_and_deploy_status_cn.md +++ b/docs/architecture/current_runtime_and_deploy_status_cn.md @@ -121,7 +121,7 @@ cd /Users/kris/code/boss - 当前已生成 Android debug APK:`android/app/build/outputs/apk/debug/app-debug.apk` - 当前已生成 Android signed release APK:`android/app/build/outputs/apk/release/app-release.apk` - 当前 release 构建还会额外生成带版本号的 APK:`android/app/build/outputs/apk/release/boss-android-v{versionName}-release.apk` -- 当前最新 release 构建版本:`2.5.3`(`versionCode=16`) +- 当前最新 release 构建版本:`2.5.4`(`versionCode=17`) - 当前 release keystore 位于本机 `android/keystores/boss-release.keystore`,签名参数位于 `android/signing/release-signing.properties` - `2.0.1` 已在本机连接的华为真机上复核通过,修复了 `Theme.SplashScreen` 导致的 `AppCompatActivity` 启动闪退 - `2.1.0` 已把 Web 一级页和主要二级页全部补成原生活动页:`MainActivity / ProjectDetailActivity / ProjectGoalsActivity / ProjectVersionsActivity / ProjectForwardActivity / ThreadDetailActivity / DeviceDetailActivity / DeviceEnrollmentActivity / SkillInventoryActivity / SecurityActivity / SettingsActivity / AiAccountsActivity / OpsCenterActivity / AboutActivity` @@ -137,8 +137,8 @@ cd /Users/kris/code/boss - `2.5.1` 已压缩“发起群聊”页首信息密度:来源会话场景只保留一张紧凑摘要卡,选择区改成更短的微信式提示,同时保留会话卡片式候选列表 - `2.5.2` 已继续回退深层原生页:`会话信息 / 群资料` 改为轻量头部信息 + 菜单式入口 + 线程列表;`项目目标 / 版本迭代记录` 也已按设计图改成轻卡片结构,不再使用厚按钮和说明块 - `2.5.2` 已压缩附件消息卡片的状态层级:`待分析` 收成 `可分析`,`让 AI 分析` 收成 `AI 分析`,有摘要时不再重复显示 `已分析` -- `2.5.3` 已继续压缩“发起群聊”页:来源会话摘要改成轻量 profile header,选择区改成 `选择其他线程 + hint pill`,底部按钮收成同层操作区,候选会话卡片纵向间距进一步压缩 -- `2.5.3` 已把聊天页里自己发出的消息顶部元信息收成只显示时间,不再重复 `你 · 时间`,文本消息、附件卡片和聊天记录卡片都会共用这条规则 +- `2.5.4` 已把 `我的` 根页收口成微信式资料区 + 白底菜单列表,会话根页同步改成更扁平的白底聊天列表,不再是厚圆角卡片流 +- `2.5.4` 已把 `设置 / 账号与安全 / AI 账号 / 技能 / 运维与修复` 的顶部说明从绿色 `soft panel` 降成轻量列表说明,和会话/设备页统一成同一套微信式产品语言 - 当前附件分析任务已带受控 `task token` 下载链接和文本摘录:本地开发环境会跟随请求 origin 生成链接,生产环境默认走 `https://boss.hyzq.net` - `2.5.x` 当前已补上会话首页独立建群入口:可以不从单线程聊天内部出发,直接在会话首页右上角 `+` 建立新群聊;同时已把多个原生自定义 top bar 页面统一纳入状态栏安全区处理 - 当前 `local-agent` 已能回写带 `dispatchExecutionId / targetProjectId / targetThreadId / rawThreadReply` 的任务完成载荷,群聊分发执行结果不再只停留在主 Agent 队列 diff --git a/public/downloads/boss-android-latest-aab.json b/public/downloads/boss-android-latest-aab.json index 4f0ae65..79d852a 100644 --- a/public/downloads/boss-android-latest-aab.json +++ b/public/downloads/boss-android-latest-aab.json @@ -1,11 +1,11 @@ { "artifactType": "aab", - "fileName": "boss-android-v2.5.3-release.aab", - "urlPath": "/downloads/boss-android-v2.5.3-release.aab", - "sizeBytes": 2912097, - "updatedAt": "2026-03-29T12:41:56Z", - "sha256": "12b520dba9a9fa3075c374910a595943d3f2a0b9f70a813bdfe8d1546e380d3c", - "versionName": "2.5.3", - "versionCode": 16, + "fileName": "boss-android-v2.5.4-release.aab", + "urlPath": "/downloads/boss-android-v2.5.4-release.aab", + "sizeBytes": 2912332, + "updatedAt": "2026-03-30T04:24:49Z", + "sha256": "75d622b5b48ca5b6005406202ea4b016d64cc7049535e89a38e8cb127ca682e8", + "versionName": "2.5.4", + "versionCode": 17, "buildFlavor": "release" } diff --git a/public/downloads/boss-android-latest.aab b/public/downloads/boss-android-latest.aab index ce27455..abfe7f8 100644 Binary files a/public/downloads/boss-android-latest.aab and b/public/downloads/boss-android-latest.aab differ diff --git a/public/downloads/boss-android-latest.apk b/public/downloads/boss-android-latest.apk index befc680..7b14761 100644 Binary files a/public/downloads/boss-android-latest.apk and b/public/downloads/boss-android-latest.apk differ diff --git a/public/downloads/boss-android-latest.json b/public/downloads/boss-android-latest.json index 7dcac60..0a9d2fe 100644 --- a/public/downloads/boss-android-latest.json +++ b/public/downloads/boss-android-latest.json @@ -1,10 +1,10 @@ { - "fileName": "boss-android-v2.5.3-release.apk", + "fileName": "boss-android-v2.5.4-release.apk", "urlPath": "/api/v1/user/ota/package", - "sizeBytes": 3088834, - "updatedAt": "2026-03-29T12:41:51Z", - "sha256": "dd44b6e1228966fbd6e83ab53936393024a76e17f7fe996e15442f4f105a435a", - "versionName": "2.5.3", - "versionCode": 16, + "sizeBytes": 3089082, + "updatedAt": "2026-03-30T04:20:41Z", + "sha256": "a76f6a86c0923695188750a8794d1ded9defa5e9f3bf898b24421c9cae435b02", + "versionName": "2.5.4", + "versionCode": 17, "buildFlavor": "release" } diff --git a/public/downloads/boss-android-v2.5.4-release.aab b/public/downloads/boss-android-v2.5.4-release.aab new file mode 100644 index 0000000..abfe7f8 Binary files /dev/null and b/public/downloads/boss-android-v2.5.4-release.aab differ diff --git a/public/downloads/boss-android-v2.5.4-release.apk b/public/downloads/boss-android-v2.5.4-release.apk new file mode 100644 index 0000000..7b14761 Binary files /dev/null and b/public/downloads/boss-android-v2.5.4-release.apk differ