style: align native me surfaces with wechat ui
This commit is contained in:
@@ -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` 降成轻量列表说明
|
||||
|
||||
## 本地启动
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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`)
|
||||
|
||||
当前不要误判成已经用了:
|
||||
|
||||
|
||||
@@ -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 队列
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -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"
|
||||
}
|
||||
|
||||
BIN
public/downloads/boss-android-v2.5.4-release.aab
Normal file
BIN
public/downloads/boss-android-v2.5.4-release.aab
Normal file
Binary file not shown.
BIN
public/downloads/boss-android-v2.5.4-release.apk
Normal file
BIN
public/downloads/boss-android-v2.5.4-release.apk
Normal file
Binary file not shown.
Reference in New Issue
Block a user