android: simplify wechat device and me surfaces
This commit is contained in:
@@ -10,8 +10,6 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.provider.Settings;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -40,7 +38,7 @@ public class AboutActivity extends BossScreenActivity {
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
configureScreen("关于 / OTA", "原生版本中心");
|
||||
configureScreen("关于", "版本与更新");
|
||||
IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
registerReceiver(otaDownloadReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
|
||||
@@ -89,51 +87,58 @@ public class AboutActivity extends BossScreenActivity {
|
||||
replaceContent();
|
||||
otaPayload = ota;
|
||||
if (user != null) {
|
||||
appendContent(BossUi.buildCard(
|
||||
appendContent(BossUi.buildListRow(
|
||||
this,
|
||||
"当前版本",
|
||||
user.optString("version", "-")
|
||||
+ "\n当前账号:" + user.optString("account", "-")
|
||||
+ "\n绑定 Codex:" + user.optString("boundCodexNodeLabel", "未绑定"),
|
||||
session == null ? "-" : "会话到期 " + session.optString("expiresAt", "-")
|
||||
+ " · 账号 " + user.optString("account", "-"),
|
||||
"绑定 Codex " + user.optString("boundCodexNodeLabel", "未绑定")
|
||||
+ (session == null ? "" : " · 会话到期 " + session.optString("expiresAt", "-")),
|
||||
null,
|
||||
null
|
||||
));
|
||||
}
|
||||
|
||||
JSONObject availableRelease = ota.optJSONObject("availableRelease");
|
||||
String otaBody = availableRelease == null
|
||||
String otaSubtitle = availableRelease == null
|
||||
? "当前已经是最新版本。"
|
||||
: availableRelease.optString("version", "未知版本")
|
||||
+ "\n" + availableRelease.optString("summary", "暂无摘要")
|
||||
+ "\n文件:" + availableRelease.optString("packageFileName", "-");
|
||||
appendContent(BossUi.buildCard(
|
||||
: "可用版本 " + availableRelease.optString("version", "未知版本");
|
||||
String otaMeta = availableRelease == null
|
||||
? "当前版本 " + ota.optString("currentVersion", "-")
|
||||
: availableRelease.optString("summary", "暂无摘要")
|
||||
+ " · 文件 " + availableRelease.optString("packageFileName", "-");
|
||||
appendContent(BossUi.buildListRow(
|
||||
this,
|
||||
"OTA 状态",
|
||||
otaBody,
|
||||
"当前版本 " + ota.optString("currentVersion", "-")
|
||||
otaSubtitle,
|
||||
otaMeta,
|
||||
availableRelease == null ? null : "NEW",
|
||||
null
|
||||
));
|
||||
|
||||
LinearLayout actionCard = BossUi.buildCard(this, "OTA 操作", "可在原生页直接检查更新、登记 OTA 并下载 APK。", "当前接口:/api/v1/user/ota");
|
||||
Button check = BossUi.buildPrimaryButton(this, "检查更新");
|
||||
check.setOnClickListener(v -> performOtaAction("check"));
|
||||
actionCard.addView(check);
|
||||
Button apply = BossUi.buildSecondaryButton(this, "登记应用 OTA");
|
||||
apply.setOnClickListener(v -> performOtaAction("apply"));
|
||||
actionCard.addView(apply);
|
||||
Button download = BossUi.buildSecondaryButton(this, "应用内下载 APK");
|
||||
download.setOnClickListener(v -> downloadLatestApk());
|
||||
actionCard.addView(download);
|
||||
appendContent(actionCard);
|
||||
appendContent(BossUi.buildMenuRow(this, "检查更新", "拉取最新 OTA 状态", null, v -> performOtaAction("check")));
|
||||
appendContent(BossUi.buildMenuRow(this, "登记应用 OTA", "把当前已应用版本写回服务端", null, v -> performOtaAction("apply")));
|
||||
appendContent(BossUi.buildMenuRow(this, "应用内下载 APK", "下载最新安装包并拉起系统安装器", null, v -> downloadLatestApk()));
|
||||
appendContent(BossUi.buildMenuRow(
|
||||
this,
|
||||
WechatSurfaceMapper.advancedEntryTitle(),
|
||||
"进入运维对话、审计与修复入口",
|
||||
null,
|
||||
v -> startActivity(new Intent(this, OpsCenterActivity.class))
|
||||
));
|
||||
|
||||
JSONArray logs = ota.optJSONArray("logs");
|
||||
if (logs != null) {
|
||||
for (int i = 0; i < logs.length(); i++) {
|
||||
JSONObject log = logs.optJSONObject(i);
|
||||
if (log == null) continue;
|
||||
appendContent(BossUi.buildCard(
|
||||
appendContent(BossUi.buildListRow(
|
||||
this,
|
||||
log.optString("version", "OTA"),
|
||||
log.optString("summary", ""),
|
||||
log.optString("status", "-") + " · " + log.optString("createdAt", "-")
|
||||
log.optString("status", "-") + " · " + log.optString("createdAt", "-"),
|
||||
null,
|
||||
null
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.hyzq.boss;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
@@ -20,14 +19,12 @@ public class AiAccountsActivity extends BossScreenActivity {
|
||||
private static final String[] PROVIDER_VALUES = {"master_codex_node", "openai_api"};
|
||||
private static final String[] PROVIDER_LABELS = {"Master Codex Node", "OpenAI API"};
|
||||
|
||||
private LinearLayout accountList;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
configureScreen("AI 账号", "主 GPT / 备用 GPT / API 容灾");
|
||||
setHeaderAction("新增", v -> openAccountEditor(null, null));
|
||||
replaceContent(buildIntroCard(), buildAccountListShell());
|
||||
replaceContent();
|
||||
reload();
|
||||
}
|
||||
|
||||
@@ -48,56 +45,46 @@ public class AiAccountsActivity extends BossScreenActivity {
|
||||
});
|
||||
}
|
||||
|
||||
private LinearLayout buildIntroCard() {
|
||||
return BossUi.buildCard(
|
||||
this,
|
||||
"账号说明",
|
||||
"当前页面管理 Boss 的主控 AI 账号。主链路优先使用已绑定电脑上的 Master Codex Node,API 容灾在同页可补充配置。",
|
||||
"支持新增、编辑、激活、校验和删除"
|
||||
);
|
||||
}
|
||||
|
||||
private LinearLayout buildAccountListShell() {
|
||||
LinearLayout wrapper = new LinearLayout(this);
|
||||
wrapper.setOrientation(LinearLayout.VERTICAL);
|
||||
accountList = new LinearLayout(this);
|
||||
accountList.setOrientation(LinearLayout.VERTICAL);
|
||||
wrapper.addView(accountList);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
private void renderAccounts(JSONObject payload) {
|
||||
JSONArray accounts = payload.optJSONArray("accounts");
|
||||
JSONObject activeIdentity = payload.optJSONObject("activeIdentity");
|
||||
JSONArray switchHistory = payload.optJSONArray("switchHistory");
|
||||
|
||||
accountList.removeAllViews();
|
||||
replaceContent(buildIntroCard(), buildActiveIdentityCard(activeIdentity), buildAccountsSection(accounts), buildSwitchHistoryCard(switchHistory));
|
||||
replaceContent();
|
||||
appendContent(BossUi.buildListRow(
|
||||
this,
|
||||
"账号管理",
|
||||
"管理主 GPT、备用 GPT 与 API 容灾。",
|
||||
"支持新增、编辑、激活、校验和删除。",
|
||||
null,
|
||||
null
|
||||
));
|
||||
appendContent(buildActiveIdentityCard(activeIdentity));
|
||||
appendContent(buildAccountsSection(accounts));
|
||||
setRefreshing(false);
|
||||
}
|
||||
|
||||
private LinearLayout buildActiveIdentityCard(@Nullable JSONObject activeIdentity) {
|
||||
String body = activeIdentity == null
|
||||
? "当前没有可用的主控身份。"
|
||||
: activeIdentity.optString("label", "AI 账号")
|
||||
+ "\n" + activeIdentity.optString("displayName", "-")
|
||||
+ "\n" + activeIdentity.optString("providerLabel", "-")
|
||||
+ (activeIdentity.optString("nodeLabel").isEmpty() ? "" : "\n节点:" + activeIdentity.optString("nodeLabel"));
|
||||
String meta = activeIdentity == null
|
||||
? "请先配置一个可用账号"
|
||||
: activeIdentity.optString("roleLabel", "-") + " · " + activeIdentity.optString("statusLabel", "-");
|
||||
return BossUi.buildCard(this, "当前主控身份", body, meta);
|
||||
if (activeIdentity == null) {
|
||||
return BossUi.buildListRow(this, "当前主控身份", "当前没有可用账号。", "请先新增或启用一个账号。", null, null);
|
||||
}
|
||||
String subtitle = activeIdentity.optString("label", "AI 账号")
|
||||
+ " · " + activeIdentity.optString("displayName", "-");
|
||||
String meta = activeIdentity.optString("roleLabel", "-")
|
||||
+ " · " + activeIdentity.optString("providerLabel", "-")
|
||||
+ " · " + activeIdentity.optString("statusLabel", "-");
|
||||
return BossUi.buildListRow(this, "当前主控身份", subtitle, meta, "当前", null);
|
||||
}
|
||||
|
||||
private LinearLayout buildAccountsSection(@Nullable JSONArray accounts) {
|
||||
LinearLayout section = new LinearLayout(this);
|
||||
section.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
section.addView(BossUi.buildCard(
|
||||
section.addView(BossUi.buildListRow(
|
||||
this,
|
||||
"账号列表",
|
||||
accounts == null || accounts.length() == 0 ? "当前还没有 AI 账号。" : "点击卡片可编辑,按钮可激活 / 校验 / 删除。",
|
||||
"当前 API:/api/v1/accounts"
|
||||
accounts == null || accounts.length() == 0 ? "当前还没有 AI 账号。" : "点开可编辑,按钮可激活、校验或删除。",
|
||||
"当前 API:/api/v1/accounts",
|
||||
null,
|
||||
null
|
||||
));
|
||||
|
||||
if (accounts == null || accounts.length() == 0) {
|
||||
@@ -118,20 +105,25 @@ public class AiAccountsActivity extends BossScreenActivity {
|
||||
String meta = account.optString("roleLabel", "-")
|
||||
+ " · " + account.optString("providerLabel", "-")
|
||||
+ " · " + statusLabel
|
||||
+ (account.optBoolean("isActive") ? " · 当前主控" : "")
|
||||
+ (account.optBoolean("apiKeyConfigured") ? " · 已配置 Key" : "");
|
||||
String body = account.optString("displayName", "-")
|
||||
+ "\n账号:" + account.optString("accountIdentifier", "-")
|
||||
+ (account.optString("nodeLabel").isEmpty() ? "" : "\n节点:" + account.optString("nodeLabel"))
|
||||
+ (account.optString("loginStatusNote").isEmpty() ? "" : "\n" + account.optString("loginStatusNote"));
|
||||
StringBuilder subtitle = new StringBuilder(account.optString("displayName", "-"));
|
||||
if (!account.optString("accountIdentifier").isEmpty()) {
|
||||
subtitle.append(" · ").append(account.optString("accountIdentifier", "-"));
|
||||
}
|
||||
if (!account.optString("nodeLabel").isEmpty()) {
|
||||
subtitle.append(" · ").append(account.optString("nodeLabel", "-"));
|
||||
}
|
||||
|
||||
LinearLayout card = BossUi.buildCard(
|
||||
LinearLayout card = new LinearLayout(this);
|
||||
card.setOrientation(LinearLayout.VERTICAL);
|
||||
card.addView(BossUi.buildListRow(
|
||||
this,
|
||||
account.optString("label", "未命名账号"),
|
||||
body,
|
||||
subtitle.toString(),
|
||||
meta,
|
||||
account.optBoolean("isActive") ? "当前" : null,
|
||||
v -> openAccountEditor(account, null)
|
||||
);
|
||||
));
|
||||
|
||||
Button activate = BossUi.buildPrimaryButton(this, account.optBoolean("isActive") ? "已激活" : "设为当前主控");
|
||||
activate.setEnabled(!account.optBoolean("isActive"));
|
||||
@@ -153,33 +145,6 @@ public class AiAccountsActivity extends BossScreenActivity {
|
||||
return card;
|
||||
}
|
||||
|
||||
private LinearLayout buildSwitchHistoryCard(@Nullable JSONArray switchHistory) {
|
||||
LinearLayout section = new LinearLayout(this);
|
||||
section.setOrientation(LinearLayout.VERTICAL);
|
||||
section.addView(BossUi.buildCard(
|
||||
this,
|
||||
"切换历史",
|
||||
switchHistory == null || switchHistory.length() == 0 ? "当前没有切换记录。" : "最近切换记录会保留 40 条。",
|
||||
"用于追踪主控身份变化"
|
||||
));
|
||||
|
||||
if (switchHistory == null || switchHistory.length() == 0) {
|
||||
section.addView(BossUi.buildEmptyCard(this, "当前没有 AI 账号切换历史。"));
|
||||
return section;
|
||||
}
|
||||
|
||||
for (int i = 0; i < switchHistory.length(); i++) {
|
||||
JSONObject record = switchHistory.optJSONObject(i);
|
||||
if (record == null) continue;
|
||||
String body = "从 " + record.optString("fromLabel", "无")
|
||||
+ "\n到 " + record.optString("toLabel", "-")
|
||||
+ "\n原因:" + record.optString("reason", "-");
|
||||
String meta = record.optString("role", "-") + " · " + record.optString("switchedAt", "-");
|
||||
section.addView(BossUi.buildCard(this, "切换记录", body, meta));
|
||||
}
|
||||
return section;
|
||||
}
|
||||
|
||||
private void openAccountEditor(@Nullable JSONObject existing, @Nullable String apiKeyHint) {
|
||||
final android.widget.EditText labelInput = BossUi.buildInput(this, "标签,例如 主 GPT", false);
|
||||
final android.widget.EditText displayNameInput = BossUi.buildInput(this, "显示名称", false);
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.hyzq.boss;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -24,7 +23,7 @@ public class DeviceDetailActivity extends BossScreenActivity {
|
||||
deviceId = getIntent().getStringExtra(EXTRA_DEVICE_ID);
|
||||
deviceName = getIntent().getStringExtra(EXTRA_DEVICE_NAME);
|
||||
configureScreen(deviceName == null ? "设备详情" : deviceName, "原生设备详情");
|
||||
setHeaderAction("编辑", v -> openEditDialog());
|
||||
hideHeaderAction();
|
||||
reload();
|
||||
}
|
||||
|
||||
@@ -48,8 +47,6 @@ public class DeviceDetailActivity extends BossScreenActivity {
|
||||
private void renderDevice(JSONObject payload) {
|
||||
JSONObject workspace = payload.optJSONObject("workspace");
|
||||
JSONObject device = workspace == null ? null : workspace.optJSONObject("selectedDevice");
|
||||
JSONArray relatedThreads = workspace == null ? null : workspace.optJSONArray("relatedThreads");
|
||||
JSONObject enrollment = workspace == null ? null : workspace.optJSONObject("activeEnrollment");
|
||||
|
||||
replaceContent();
|
||||
if (device == null) {
|
||||
@@ -60,53 +57,38 @@ public class DeviceDetailActivity extends BossScreenActivity {
|
||||
|
||||
deviceName = device.optString("name", deviceId);
|
||||
configureScreen(deviceName, device.optString("endpoint", "设备详情"));
|
||||
appendContent(BossUi.buildCard(
|
||||
appendContent(BossUi.buildListRow(
|
||||
this,
|
||||
device.optString("name", "设备"),
|
||||
device.optString("note", "暂无备注"),
|
||||
"状态 " + device.optString("status", "unknown")
|
||||
+ " · 账号 " + device.optString("account", "-")
|
||||
+ " · 5h " + device.optInt("quota5h", 0)
|
||||
+ " · 7d " + device.optInt("quota7d", 0)
|
||||
buildDeviceSubtitle(device),
|
||||
buildDeviceMeta(device),
|
||||
null,
|
||||
null
|
||||
));
|
||||
|
||||
Button skillsButton = BossUi.buildPrimaryButton(this, "查看技能");
|
||||
skillsButton.setOnClickListener(v -> openSkills());
|
||||
appendContent(skillsButton);
|
||||
|
||||
if (relatedThreads != null && relatedThreads.length() > 0) {
|
||||
for (int i = 0; i < relatedThreads.length(); i++) {
|
||||
JSONObject thread = relatedThreads.optJSONObject(i);
|
||||
if (thread == null) continue;
|
||||
appendContent(BossUi.buildCard(
|
||||
this,
|
||||
thread.optString("title", "线程"),
|
||||
thread.optString("summary", ""),
|
||||
thread.optString("workerId", "-")
|
||||
+ " · " + thread.optInt("contextBudgetRemainingPct", 0) + "%"
|
||||
+ " · " + thread.optString("contextBudgetLevel", "safe"),
|
||||
v -> openThread(thread.optString("threadId"))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (enrollment != null) {
|
||||
appendContent(BossUi.buildCard(
|
||||
this,
|
||||
"当前绑定草稿",
|
||||
"pairingCode " + enrollment.optString("pairingCode", "-")
|
||||
+ "\ntoken " + enrollment.optString("token", "-"),
|
||||
enrollment.optString("status", "ready")
|
||||
+ " · 到期 " + enrollment.optString("expiresAt", "-")
|
||||
));
|
||||
}
|
||||
appendContent(BossUi.buildMenuRow(this, "查看技能", "查看当前设备同步的 Skill 清单", null, v -> openSkills()));
|
||||
appendContent(BossUi.buildMenuRow(this, "编辑", "修改设备名称、备注和项目列表", null, v -> openEditDialog()));
|
||||
setRefreshing(false);
|
||||
}
|
||||
|
||||
private void openThread(String threadId) {
|
||||
Intent intent = new Intent(this, ThreadDetailActivity.class);
|
||||
intent.putExtra(ThreadDetailActivity.EXTRA_THREAD_ID, threadId);
|
||||
startActivity(intent);
|
||||
private String buildDeviceSubtitle(JSONObject device) {
|
||||
String note = device.optString("note", "");
|
||||
if (!note.isEmpty()) {
|
||||
return note;
|
||||
}
|
||||
return "状态 " + device.optString("status", "unknown") + " · 账号 " + device.optString("account", "-");
|
||||
}
|
||||
|
||||
private @Nullable String buildDeviceMeta(JSONObject device) {
|
||||
String endpoint = device.optString("endpoint", "");
|
||||
if (!endpoint.isEmpty()) {
|
||||
return endpoint;
|
||||
}
|
||||
JSONArray projects = device.optJSONArray("projects");
|
||||
if (projects == null || projects.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
return "项目 " + joinArray(projects);
|
||||
}
|
||||
|
||||
private void openSkills() {
|
||||
|
||||
@@ -344,12 +344,11 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
private void renderDevicesRoot() {
|
||||
screenContent.removeAllViews();
|
||||
screenContent.addView(BossUi.buildListRow(
|
||||
screenContent.addView(BossUi.buildMenuRow(
|
||||
this,
|
||||
"添加设备",
|
||||
"通过配对码接入新的生产设备",
|
||||
null,
|
||||
null,
|
||||
v -> startActivity(new Intent(this, DeviceEnrollmentActivity.class))
|
||||
));
|
||||
|
||||
@@ -363,8 +362,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
if (item == null) continue;
|
||||
String deviceId = item.optString("id", "");
|
||||
WechatSurfaceMapper.DeviceRow row = WechatSurfaceMapper.toDeviceRow(item);
|
||||
String meta = "5h " + item.optInt("quota5h", 0) + " · 7d " + item.optInt("quota7d", 0);
|
||||
screenContent.addView(BossUi.buildListRow(this, row.title, row.subtitle, meta, null, v -> {
|
||||
screenContent.addView(BossUi.buildListRow(this, row.title, row.subtitle, null, null, v -> {
|
||||
if (deviceId.isEmpty()) {
|
||||
showMessage("缺少 deviceId");
|
||||
return;
|
||||
@@ -382,12 +380,11 @@ public class MainActivity extends AppCompatActivity {
|
||||
String account = sessionData == null
|
||||
? apiClient.getAccountLabel()
|
||||
: sessionData.optString("account", apiClient.getAccountLabel());
|
||||
String expiresAt = sessionData == null ? "-" : sessionData.optString("expiresAt", "-");
|
||||
screenContent.addView(BossUi.buildListRow(
|
||||
this,
|
||||
displayName,
|
||||
"账号 " + account,
|
||||
"会话到期 " + expiresAt,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
));
|
||||
@@ -402,16 +399,6 @@ public class MainActivity extends AppCompatActivity {
|
||||
));
|
||||
}
|
||||
|
||||
if (otaData != null) {
|
||||
JSONObject availableRelease = otaData.optJSONObject("availableRelease");
|
||||
String body = "当前版本 " + otaData.optString("currentVersion", "-");
|
||||
String meta = availableRelease == null
|
||||
? "当前没有待安装版本"
|
||||
: "可用版本 " + availableRelease.optString("version", "-")
|
||||
+ " · 文件 " + availableRelease.optString("packageFileName", "-");
|
||||
screenContent.addView(BossUi.buildCard(this, "OTA 状态", body, meta));
|
||||
}
|
||||
|
||||
Button logoutButton = BossUi.buildSecondaryButton(this, "退出登录");
|
||||
logoutButton.setOnClickListener(v -> logout());
|
||||
screenContent.addView(logoutButton);
|
||||
@@ -488,15 +475,15 @@ public class MainActivity extends AppCompatActivity {
|
||||
private String meDescriptionFor(String title) {
|
||||
switch (title) {
|
||||
case "账号与安全":
|
||||
return "查看当前会话、登录模式和退出登录";
|
||||
return "查看当前会话与登录安全";
|
||||
case "AI 账号":
|
||||
return "管理主 GPT、备用 GPT 与 API 容灾";
|
||||
case "设置":
|
||||
return "调整默认首页和刷新偏好";
|
||||
return "调整默认首页和提醒偏好";
|
||||
case "技能":
|
||||
return "按绑定设备查看 Skill 清单";
|
||||
return "按设备查看 Skill 清单";
|
||||
case "关于":
|
||||
return "查看版本、OTA 状态和当前绑定节点";
|
||||
return "查看版本、更新与高级入口";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -33,33 +33,34 @@ public class SecurityActivity extends BossScreenActivity {
|
||||
}
|
||||
|
||||
private void renderSecurity(@Nullable JSONObject session) {
|
||||
replaceContent(
|
||||
BossUi.buildCard(
|
||||
this,
|
||||
"当前登录模式",
|
||||
"当前登录页已临时切到免验证模式,点击登录会直接创建最高管理员会话。",
|
||||
"后续如收口认证,再切回账号密码 / 验证码登录。"
|
||||
)
|
||||
);
|
||||
replaceContent();
|
||||
appendContent(BossUi.buildListRow(
|
||||
this,
|
||||
"当前登录模式",
|
||||
"当前客户端仍使用快速进入模式。",
|
||||
"需要更严格认证时,再切回账号密码或验证码登录。",
|
||||
null,
|
||||
null
|
||||
));
|
||||
if (session != null) {
|
||||
appendContent(BossUi.buildCard(
|
||||
appendContent(BossUi.buildListRow(
|
||||
this,
|
||||
"当前会话",
|
||||
"账号 " + session.optString("account", "-")
|
||||
+ "\n角色 " + session.optString("role", "-")
|
||||
+ "\n登录方式 " + session.optString("loginMethod", "-"),
|
||||
"到期 " + session.optString("expiresAt", "-")
|
||||
+ " · " + session.optString("role", "-"),
|
||||
"登录方式 " + session.optString("loginMethod", "-")
|
||||
+ " · 到期 " + session.optString("expiresAt", "-"),
|
||||
null,
|
||||
null
|
||||
));
|
||||
}
|
||||
|
||||
android.widget.Button devicesButton = BossUi.buildPrimaryButton(this, "打开设备页");
|
||||
devicesButton.setOnClickListener(v -> {
|
||||
appendContent(BossUi.buildMenuRow(this, "打开设备页", "查看已绑定设备与状态", null, v -> {
|
||||
Intent intent = new Intent(this, MainActivity.class);
|
||||
intent.putExtra(MainActivity.EXTRA_INITIAL_TAB, "devices");
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
startActivity(intent);
|
||||
});
|
||||
appendContent(devicesButton);
|
||||
}));
|
||||
|
||||
android.widget.Button logoutButton = BossUi.buildSecondaryButton(this, "退出登录");
|
||||
logoutButton.setOnClickListener(v -> logout());
|
||||
|
||||
@@ -43,14 +43,14 @@ public class SettingsActivity extends BossScreenActivity {
|
||||
}
|
||||
|
||||
private void buildForm() {
|
||||
replaceContent(
|
||||
BossUi.buildCard(
|
||||
this,
|
||||
"设置说明",
|
||||
"当前设置会持久化到 data/boss-state.json,下一线程接手不会丢失。",
|
||||
"原生设置页直接走 /api/v1/settings"
|
||||
)
|
||||
);
|
||||
replaceContent(BossUi.buildListRow(
|
||||
this,
|
||||
"偏好设置",
|
||||
"调整默认首页和提醒行为。",
|
||||
"保存后会直接写入 /api/v1/settings。",
|
||||
null,
|
||||
null
|
||||
));
|
||||
|
||||
liveUpdatesSwitch = new SwitchCompat(this);
|
||||
liveUpdatesSwitch.setText("启用实时刷新");
|
||||
@@ -69,12 +69,12 @@ public class SettingsActivity extends BossScreenActivity {
|
||||
);
|
||||
preferredEntrySpinner.setAdapter(adapter);
|
||||
|
||||
LinearLayout card = BossUi.buildCard(this, "交互偏好", "可切换默认首页与提醒行为。", "保存后立即生效");
|
||||
card.addView(liveUpdatesSwitch);
|
||||
card.addView(riskBadgesSwitch);
|
||||
card.addView(confirmActionsSwitch);
|
||||
card.addView(preferredEntrySpinner);
|
||||
appendContent(card);
|
||||
LinearLayout form = BossUi.buildCard(this, "交互偏好", "切换默认首页与提醒开关。", "保存后立即生效");
|
||||
form.addView(liveUpdatesSwitch);
|
||||
form.addView(riskBadgesSwitch);
|
||||
form.addView(confirmActionsSwitch);
|
||||
form.addView(preferredEntrySpinner);
|
||||
appendContent(form);
|
||||
}
|
||||
|
||||
private void populate(@Nullable JSONObject settings) {
|
||||
|
||||
@@ -65,11 +65,13 @@ public class SkillInventoryActivity extends BossScreenActivity {
|
||||
if (device != null) {
|
||||
deviceName = device.optString("name", deviceId);
|
||||
configureScreen("技能", deviceName);
|
||||
appendContent(BossUi.buildCard(
|
||||
appendContent(BossUi.buildListRow(
|
||||
this,
|
||||
deviceName,
|
||||
"当前页按设备查看 Skill 清单。",
|
||||
"Skill 由 local-agent 从本机 ~/.codex/skills 扫描并同步。"
|
||||
"Skill 由 local-agent 从本机 ~/.codex/skills 扫描并同步。",
|
||||
null,
|
||||
null
|
||||
));
|
||||
}
|
||||
|
||||
@@ -81,13 +83,17 @@ public class SkillInventoryActivity extends BossScreenActivity {
|
||||
for (int i = 0; i < skills.length(); i++) {
|
||||
JSONObject skill = skills.optJSONObject(i);
|
||||
if (skill == null) continue;
|
||||
LinearLayout card = BossUi.buildCard(
|
||||
LinearLayout card = new LinearLayout(this);
|
||||
card.setOrientation(LinearLayout.VERTICAL);
|
||||
card.addView(BossUi.buildListRow(
|
||||
this,
|
||||
skill.optString("name", "未命名 Skill"),
|
||||
skill.optString("description", "未提供说明"),
|
||||
skill.optString("category", "-")
|
||||
+ " · " + skill.optString("updatedAt", "-")
|
||||
);
|
||||
+ " · " + skill.optString("updatedAt", "-"),
|
||||
null,
|
||||
null
|
||||
));
|
||||
Button copyInvocation = BossUi.buildPrimaryButton(this, "复制调用语句");
|
||||
copyInvocation.setOnClickListener(v -> BossUi.copyText(this, "Skill 调用", skill.optString("invocation", "")));
|
||||
card.addView(copyInvocation);
|
||||
|
||||
@@ -60,6 +60,10 @@ public final class WechatSurfaceMapper {
|
||||
return ROOT_ME_MENU_TITLES.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public static String advancedEntryTitle() {
|
||||
return "高级与调试";
|
||||
}
|
||||
|
||||
public static String[] projectQuickActions() {
|
||||
return PROJECT_QUICK_ACTIONS.toArray(new String[0]);
|
||||
}
|
||||
|
||||
@@ -77,6 +77,11 @@ public class WechatSurfaceMapperTest {
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void advancedEntryTitle_movesOpsOutOfMainMePage() throws Exception {
|
||||
assertEquals("高级与调试", WechatSurfaceMapper.advancedEntryTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void projectQuickActions_keepOnlyGoalsAndVersions() throws Exception {
|
||||
assertArrayEquals(
|
||||
|
||||
Reference in New Issue
Block a user