feat: restore wechat-style root shell
This commit is contained in:
@@ -4,6 +4,8 @@ import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
@@ -16,6 +18,94 @@ import androidx.annotation.Nullable;
|
||||
public final class BossUi {
|
||||
private BossUi() {}
|
||||
|
||||
public static LinearLayout buildListRow(
|
||||
Context context,
|
||||
String title,
|
||||
@Nullable String subtitle,
|
||||
@Nullable String meta,
|
||||
@Nullable String badge,
|
||||
@Nullable View.OnClickListener listener
|
||||
) {
|
||||
LinearLayout row = new LinearLayout(context);
|
||||
row.setOrientation(LinearLayout.HORIZONTAL);
|
||||
row.setGravity(Gravity.CENTER_VERTICAL);
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
params.bottomMargin = dp(context, 1);
|
||||
row.setLayoutParams(params);
|
||||
row.setPadding(dp(context, 16), dp(context, 14), dp(context, 16), dp(context, 14));
|
||||
row.setBackgroundResource(R.drawable.bg_list_row);
|
||||
if (listener != null) {
|
||||
row.setClickable(true);
|
||||
row.setFocusable(true);
|
||||
row.setOnClickListener(listener);
|
||||
}
|
||||
|
||||
LinearLayout textWrap = new LinearLayout(context);
|
||||
textWrap.setOrientation(LinearLayout.VERTICAL);
|
||||
LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams(
|
||||
0,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
1f
|
||||
);
|
||||
textWrap.setLayoutParams(textParams);
|
||||
|
||||
TextView titleView = new TextView(context);
|
||||
titleView.setText(title);
|
||||
titleView.setTextSize(17);
|
||||
titleView.setTypeface(Typeface.DEFAULT_BOLD);
|
||||
titleView.setTextColor(context.getColor(R.color.boss_text_primary));
|
||||
textWrap.addView(titleView);
|
||||
|
||||
if (!TextUtils.isEmpty(subtitle)) {
|
||||
TextView subtitleView = new TextView(context);
|
||||
subtitleView.setText(subtitle);
|
||||
subtitleView.setTextSize(14);
|
||||
subtitleView.setTextColor(context.getColor(R.color.boss_text_muted));
|
||||
subtitleView.setPadding(0, dp(context, 4), 0, 0);
|
||||
textWrap.addView(subtitleView);
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(meta)) {
|
||||
TextView metaView = new TextView(context);
|
||||
metaView.setText(meta);
|
||||
metaView.setTextSize(12);
|
||||
metaView.setTextColor(context.getColor(R.color.boss_text_soft));
|
||||
metaView.setPadding(0, dp(context, 6), 0, 0);
|
||||
textWrap.addView(metaView);
|
||||
}
|
||||
|
||||
row.addView(textWrap);
|
||||
|
||||
LinearLayout accessoryWrap = new LinearLayout(context);
|
||||
accessoryWrap.setOrientation(LinearLayout.VERTICAL);
|
||||
accessoryWrap.setGravity(Gravity.END | Gravity.CENTER_VERTICAL);
|
||||
|
||||
if (!TextUtils.isEmpty(badge)) {
|
||||
TextView badgeView = new TextView(context);
|
||||
badgeView.setText(badge);
|
||||
badgeView.setTextSize(12);
|
||||
badgeView.setTextColor(context.getColor(R.color.boss_green));
|
||||
badgeView.setBackgroundResource(R.drawable.bg_tab_active);
|
||||
badgeView.setPadding(dp(context, 8), dp(context, 2), dp(context, 8), dp(context, 2));
|
||||
accessoryWrap.addView(badgeView);
|
||||
}
|
||||
|
||||
if (listener != null) {
|
||||
TextView arrowView = new TextView(context);
|
||||
arrowView.setText("›");
|
||||
arrowView.setTextSize(18);
|
||||
arrowView.setTextColor(context.getColor(R.color.boss_text_soft));
|
||||
arrowView.setPadding(dp(context, 10), dp(context, 4), 0, 0);
|
||||
accessoryWrap.addView(arrowView);
|
||||
}
|
||||
|
||||
row.addView(accessoryWrap);
|
||||
return row;
|
||||
}
|
||||
|
||||
public static LinearLayout buildCard(Context context, String title, String body, String meta) {
|
||||
return buildCard(context, title, body, meta, null);
|
||||
}
|
||||
@@ -74,42 +164,7 @@ public final class BossUi {
|
||||
@Nullable String badge,
|
||||
View.OnClickListener listener
|
||||
) {
|
||||
LinearLayout row = buildCard(context, title, description, badge == null ? "点击进入" : badge, listener);
|
||||
row.setOrientation(LinearLayout.HORIZONTAL);
|
||||
row.removeAllViews();
|
||||
|
||||
LinearLayout textWrap = new LinearLayout(context);
|
||||
textWrap.setOrientation(LinearLayout.VERTICAL);
|
||||
LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams(
|
||||
0,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
1f
|
||||
);
|
||||
textWrap.setLayoutParams(textParams);
|
||||
|
||||
TextView titleView = new TextView(context);
|
||||
titleView.setText(title);
|
||||
titleView.setTextSize(17);
|
||||
titleView.setTypeface(Typeface.DEFAULT_BOLD);
|
||||
titleView.setTextColor(context.getColor(R.color.boss_text_primary));
|
||||
|
||||
TextView descView = new TextView(context);
|
||||
descView.setText(description);
|
||||
descView.setTextSize(13);
|
||||
descView.setTextColor(context.getColor(R.color.boss_text_muted));
|
||||
descView.setPadding(0, dp(context, 6), 0, 0);
|
||||
|
||||
textWrap.addView(titleView);
|
||||
textWrap.addView(descView);
|
||||
|
||||
TextView accessory = new TextView(context);
|
||||
accessory.setText(badge == null ? "›" : badge + " ›");
|
||||
accessory.setTextSize(13);
|
||||
accessory.setTextColor(context.getColor(R.color.boss_green));
|
||||
|
||||
row.addView(textWrap);
|
||||
row.addView(accessory);
|
||||
return row;
|
||||
return buildListRow(context, title, description, null, badge, listener);
|
||||
}
|
||||
|
||||
public static LinearLayout buildEmptyCard(Context context, String text) {
|
||||
|
||||
@@ -108,6 +108,11 @@ public class MainActivity extends AppCompatActivity {
|
||||
tabMe = findViewById(R.id.tab_me);
|
||||
screenRefresh = findViewById(R.id.screen_refresh);
|
||||
screenContent = findViewById(R.id.screen_content);
|
||||
|
||||
String[] rootTabs = WechatSurfaceMapper.rootTabLabels();
|
||||
tabConversations.setText(rootTabs[0]);
|
||||
tabDevices.setText(rootTabs[1]);
|
||||
tabMe.setText(rootTabs[2]);
|
||||
}
|
||||
|
||||
private void bindActions() {
|
||||
@@ -277,16 +282,16 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
switch (activeTab) {
|
||||
case "devices":
|
||||
updateHeader("设备", "只展示当前正式接入生产链路的设备。");
|
||||
updateHeader("设备", "生产设备列表");
|
||||
renderDevicesRoot();
|
||||
break;
|
||||
case "me":
|
||||
updateHeader("我的", "账号、安全、技能、运维、OTA 都从这里进入。");
|
||||
updateHeader("我的", "账号与应用设置");
|
||||
renderMeRoot();
|
||||
break;
|
||||
case "conversations":
|
||||
default:
|
||||
updateHeader("会话", "原生会话列表直接消费 /api/v1/conversations。");
|
||||
updateHeader("会话", "最近消息");
|
||||
renderConversationsRoot();
|
||||
break;
|
||||
}
|
||||
@@ -304,19 +309,12 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void styleTab(Button button, boolean active) {
|
||||
button.setBackgroundResource(active ? R.drawable.bg_primary_button : R.drawable.bg_secondary_button);
|
||||
button.setTextColor(getColor(active ? R.color.boss_surface : R.color.boss_green));
|
||||
button.setBackgroundResource(active ? R.drawable.bg_tab_active : R.drawable.bg_tab_inactive);
|
||||
button.setTextColor(getColor(active ? R.color.boss_green : R.color.boss_text_muted));
|
||||
}
|
||||
|
||||
private void renderConversationsRoot() {
|
||||
screenContent.removeAllViews();
|
||||
screenContent.addView(BossUi.buildCard(
|
||||
this,
|
||||
"会话首页",
|
||||
"当前原生首页会直接进入项目详情、目标、版本、转发与线程预算详情。",
|
||||
conversationsData == null ? "正在等待数据" : "会话数 " + conversationsData.length()
|
||||
));
|
||||
|
||||
if (conversationsData == null || conversationsData.length() == 0) {
|
||||
screenContent.addView(BossUi.buildEmptyCard(this, "当前没有会话数据。"));
|
||||
return;
|
||||
@@ -326,41 +324,35 @@ public class MainActivity extends AppCompatActivity {
|
||||
JSONObject item = conversationsData.optJSONObject(i);
|
||||
if (item == null) continue;
|
||||
String projectId = item.optString("projectId", "");
|
||||
String title = item.optString("projectTitle", "未命名会话");
|
||||
StringBuilder body = new StringBuilder(item.optString("preview", "暂无预览"));
|
||||
if (item.optInt("activeDeviceCount", 0) > 0) {
|
||||
body.append("\n设备 ").append(item.optString("deviceNamesPreview", "未标注"));
|
||||
}
|
||||
JSONObject budget = item.optJSONObject("contextBudgetIndicator");
|
||||
String meta = "风险 " + item.optString("riskLevel", "unknown")
|
||||
+ " · 未读 " + item.optInt("unreadCount", 0)
|
||||
+ " · " + item.optString("latestReplyLabel", "-");
|
||||
if (budget != null && budget.optBoolean("visible", false)) {
|
||||
meta = meta + " · 预算 " + budget.optInt("percent", 0) + "%";
|
||||
}
|
||||
screenContent.addView(BossUi.buildCard(this, title, body.toString(), meta, v -> {
|
||||
WechatSurfaceMapper.ConversationRow row = WechatSurfaceMapper.toConversationRow(item);
|
||||
String badge = row.unreadCount > 0 ? String.valueOf(row.unreadCount) : null;
|
||||
screenContent.addView(BossUi.buildListRow(
|
||||
this,
|
||||
row.title.isEmpty() ? "未命名会话" : row.title,
|
||||
row.preview.isEmpty() ? "暂无预览" : row.preview,
|
||||
row.timeLabel.isEmpty() ? null : row.timeLabel,
|
||||
badge,
|
||||
v -> {
|
||||
if (projectId.isEmpty()) {
|
||||
showMessage("缺少 projectId");
|
||||
return;
|
||||
}
|
||||
openProject(projectId, title);
|
||||
openProject(projectId, row.title.isEmpty() ? "未命名会话" : row.title);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private void renderDevicesRoot() {
|
||||
screenContent.removeAllViews();
|
||||
screenContent.addView(BossUi.buildCard(
|
||||
screenContent.addView(BossUi.buildListRow(
|
||||
this,
|
||||
"设备首页",
|
||||
"设备详情、技能清单和配对草稿都改为原生页。",
|
||||
devicesData == null ? "正在等待数据" : "设备数 " + devicesData.length()
|
||||
"添加设备",
|
||||
"通过配对码接入新的生产设备",
|
||||
null,
|
||||
null,
|
||||
v -> startActivity(new Intent(this, DeviceEnrollmentActivity.class))
|
||||
));
|
||||
|
||||
Button addDeviceButton = BossUi.buildPrimaryButton(this, "添加设备");
|
||||
addDeviceButton.setOnClickListener(v -> startActivity(new Intent(this, DeviceEnrollmentActivity.class)));
|
||||
screenContent.addView(addDeviceButton);
|
||||
|
||||
if (devicesData == null || devicesData.length() == 0) {
|
||||
screenContent.addView(BossUi.buildEmptyCard(this, "当前没有接入设备。"));
|
||||
return;
|
||||
@@ -370,18 +362,14 @@ public class MainActivity extends AppCompatActivity {
|
||||
JSONObject item = devicesData.optJSONObject(i);
|
||||
if (item == null) continue;
|
||||
String deviceId = item.optString("id", "");
|
||||
String title = item.optString("name", "未命名设备");
|
||||
String body = item.optString("note", item.optString("endpoint", "暂无设备说明"));
|
||||
String meta = "状态 " + item.optString("status", "unknown")
|
||||
+ " · 账号 " + item.optString("account", "-")
|
||||
+ " · 5h " + item.optInt("quota5h", 0)
|
||||
+ " · 7d " + item.optInt("quota7d", 0);
|
||||
screenContent.addView(BossUi.buildCard(this, title, body, meta, v -> {
|
||||
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 -> {
|
||||
if (deviceId.isEmpty()) {
|
||||
showMessage("缺少 deviceId");
|
||||
return;
|
||||
}
|
||||
openDevice(deviceId, title);
|
||||
openDevice(deviceId, row.title);
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -395,55 +383,24 @@ public class MainActivity extends AppCompatActivity {
|
||||
? apiClient.getAccountLabel()
|
||||
: sessionData.optString("account", apiClient.getAccountLabel());
|
||||
String expiresAt = sessionData == null ? "-" : sessionData.optString("expiresAt", "-");
|
||||
screenContent.addView(BossUi.buildCard(
|
||||
screenContent.addView(BossUi.buildListRow(
|
||||
this,
|
||||
displayName,
|
||||
"账号 " + account + "\n当前原生客户端已覆盖会话 / 设备 / 我的一级导航。",
|
||||
"会话到期 " + expiresAt
|
||||
"账号 " + account,
|
||||
"会话到期 " + expiresAt,
|
||||
null,
|
||||
null
|
||||
));
|
||||
|
||||
screenContent.addView(BossUi.buildMenuRow(
|
||||
this,
|
||||
"账号与安全",
|
||||
"查看当前会话、登录模式和退出登录。",
|
||||
null,
|
||||
v -> startActivity(new Intent(this, SecurityActivity.class))
|
||||
));
|
||||
screenContent.addView(BossUi.buildMenuRow(
|
||||
this,
|
||||
"设置",
|
||||
"实时刷新、风险徽标和默认首页。",
|
||||
null,
|
||||
v -> startActivity(new Intent(this, SettingsActivity.class))
|
||||
));
|
||||
screenContent.addView(BossUi.buildMenuRow(
|
||||
this,
|
||||
"运维与修复",
|
||||
"查看故障、repair ticket、审计请求和能力注册表。",
|
||||
null,
|
||||
v -> startActivity(new Intent(this, OpsCenterActivity.class))
|
||||
));
|
||||
screenContent.addView(BossUi.buildMenuRow(
|
||||
this,
|
||||
"AI 账号",
|
||||
"管理主 GPT、备用 GPT、Master Codex Node 与 API 容灾。",
|
||||
null,
|
||||
v -> startActivity(new Intent(this, AiAccountsActivity.class))
|
||||
));
|
||||
screenContent.addView(BossUi.buildMenuRow(
|
||||
this,
|
||||
"技能",
|
||||
"按绑定设备查看 Skill,并一键复制调用语句。",
|
||||
null,
|
||||
v -> startActivity(new Intent(this, SkillInventoryActivity.class))
|
||||
));
|
||||
screenContent.addView(BossUi.buildMenuRow(
|
||||
this,
|
||||
"关于",
|
||||
"查看版本、OTA 状态和当前绑定节点。",
|
||||
otaData == null ? null : otaData.optBoolean("hasOta", false) ? "OTA" : null,
|
||||
v -> startActivity(new Intent(this, AboutActivity.class))
|
||||
));
|
||||
for (String title : WechatSurfaceMapper.rootMeMenuTitles()) {
|
||||
screenContent.addView(BossUi.buildMenuRow(
|
||||
this,
|
||||
title,
|
||||
meDescriptionFor(title),
|
||||
meBadgeFor(title),
|
||||
v -> openMeEntry(title)
|
||||
));
|
||||
}
|
||||
|
||||
if (otaData != null) {
|
||||
JSONObject availableRelease = otaData.optJSONObject("availableRelease");
|
||||
@@ -502,4 +459,53 @@ public class MainActivity extends AppCompatActivity {
|
||||
private void showMessage(String text) {
|
||||
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
private void openMeEntry(String title) {
|
||||
Intent intent;
|
||||
switch (title) {
|
||||
case "账号与安全":
|
||||
intent = new Intent(this, SecurityActivity.class);
|
||||
break;
|
||||
case "AI 账号":
|
||||
intent = new Intent(this, AiAccountsActivity.class);
|
||||
break;
|
||||
case "设置":
|
||||
intent = new Intent(this, SettingsActivity.class);
|
||||
break;
|
||||
case "技能":
|
||||
intent = new Intent(this, SkillInventoryActivity.class);
|
||||
break;
|
||||
case "关于":
|
||||
intent = new Intent(this, AboutActivity.class);
|
||||
break;
|
||||
default:
|
||||
showMessage("暂未接入:" + title);
|
||||
return;
|
||||
}
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
private String meDescriptionFor(String title) {
|
||||
switch (title) {
|
||||
case "账号与安全":
|
||||
return "查看当前会话、登录模式和退出登录";
|
||||
case "AI 账号":
|
||||
return "管理主 GPT、备用 GPT 与 API 容灾";
|
||||
case "设置":
|
||||
return "调整默认首页和刷新偏好";
|
||||
case "技能":
|
||||
return "按绑定设备查看 Skill 清单";
|
||||
case "关于":
|
||||
return "查看版本、OTA 状态和当前绑定节点";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable String meBadgeFor(String title) {
|
||||
if ("关于".equals(title) && otaData != null && otaData.optBoolean("hasOta", false)) {
|
||||
return "OTA";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,12 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public final class WechatSurfaceMapper {
|
||||
private static final List<String> ROOT_TAB_LABELS = Arrays.asList(
|
||||
"会话",
|
||||
"设备",
|
||||
"我的"
|
||||
);
|
||||
|
||||
private static final List<String> ROOT_ME_MENU_TITLES = Arrays.asList(
|
||||
"账号与安全",
|
||||
"AI 账号",
|
||||
@@ -40,6 +46,10 @@ public final class WechatSurfaceMapper {
|
||||
);
|
||||
}
|
||||
|
||||
public static String[] rootTabLabels() {
|
||||
return ROOT_TAB_LABELS.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public static String[] rootMeMenuTitles() {
|
||||
return ROOT_ME_MENU_TITLES.toArray(new String[0]);
|
||||
}
|
||||
|
||||
16
android/app/src/main/res/drawable/bg_list_row.xml
Normal file
16
android/app/src/main/res/drawable/bg_list_row.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_pressed="true">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/boss_bg_app" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/boss_surface" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="@color/boss_divider" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
||||
6
android/app/src/main/res/drawable/bg_tab_active.xml
Normal file
6
android/app/src/main/res/drawable/bg_tab_active.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#1407C160" />
|
||||
<corners android:radius="18dp" />
|
||||
</shape>
|
||||
6
android/app/src/main/res/drawable/bg_tab_inactive.xml
Normal file
6
android/app/src/main/res/drawable/bg_tab_inactive.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/boss_surface" />
|
||||
<corners android:radius="18dp" />
|
||||
</shape>
|
||||
@@ -2,7 +2,7 @@
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_app_gradient">
|
||||
android:background="@color/boss_bg_app">
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/login_panel"
|
||||
@@ -16,18 +16,18 @@
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingTop="72dp"
|
||||
android:paddingTop="96dp"
|
||||
android:paddingRight="24dp"
|
||||
android:paddingBottom="32dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:background="@drawable/bg_primary_button"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:background="@drawable/bg_tab_active"
|
||||
android:gravity="center"
|
||||
android:text="B"
|
||||
android:textColor="@color/boss_surface"
|
||||
android:textSize="30sp"
|
||||
android:textColor="@color/boss_green"
|
||||
android:textSize="32sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
@@ -54,7 +54,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="28dp"
|
||||
android:background="@drawable/bg_card"
|
||||
android:background="@drawable/bg_list_row"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp">
|
||||
|
||||
@@ -109,12 +109,13 @@
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/boss_surface"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="20dp"
|
||||
android:paddingTop="18dp"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingRight="20dp"
|
||||
android:paddingBottom="16dp">
|
||||
android:paddingBottom="14dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/back_button"
|
||||
@@ -144,7 +145,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="会话"
|
||||
android:textColor="@color/boss_text_primary"
|
||||
android:textSize="24sp"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
@@ -163,9 +164,9 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_secondary_button"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingTop="9dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:paddingBottom="9dp"
|
||||
android:text="刷新"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="@color/boss_green"
|
||||
@@ -192,10 +193,9 @@
|
||||
android:id="@+id/screen_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/boss_panel"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="20dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingRight="20dp"
|
||||
android:paddingBottom="88dp" />
|
||||
</ScrollView>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
@@ -203,11 +203,13 @@
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="76dp"
|
||||
android:layout_height="72dp"
|
||||
android:background="@color/boss_surface"
|
||||
android:elevation="10dp"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingRight="12dp">
|
||||
|
||||
@@ -217,10 +219,10 @@
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginRight="6dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/bg_primary_button"
|
||||
android:background="@drawable/bg_tab_active"
|
||||
android:text="会话"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="@color/boss_surface"
|
||||
android:textColor="@color/boss_green"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<Button
|
||||
@@ -230,10 +232,10 @@
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_marginRight="6dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/bg_secondary_button"
|
||||
android:background="@drawable/bg_tab_inactive"
|
||||
android:text="设备"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="@color/boss_green"
|
||||
android:textColor="@color/boss_text_muted"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<Button
|
||||
@@ -242,10 +244,10 @@
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/bg_secondary_button"
|
||||
android:background="@drawable/bg_tab_inactive"
|
||||
android:text="我的"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="@color/boss_green"
|
||||
android:textColor="@color/boss_text_muted"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_app_gradient"
|
||||
android:background="@color/boss_bg_app"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/boss_surface"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="16dp"
|
||||
@@ -74,13 +75,13 @@
|
||||
android:id="@+id/screen_refresh_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:background="@drawable/bg_primary_button"
|
||||
android:background="@drawable/bg_secondary_button"
|
||||
android:minWidth="0dp"
|
||||
android:paddingLeft="14dp"
|
||||
android:paddingRight="14dp"
|
||||
android:text="刷新"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="@color/boss_surface"
|
||||
android:textColor="@color/boss_green"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
@@ -99,10 +100,9 @@
|
||||
android:id="@+id/screen_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/boss_panel"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="18dp"
|
||||
android:paddingTop="6dp"
|
||||
android:paddingRight="18dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="24dp" />
|
||||
</ScrollView>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
@@ -3,11 +3,15 @@
|
||||
<color name="boss_green">#07C160</color>
|
||||
<color name="boss_green_dark">#04984B</color>
|
||||
<color name="boss_surface">#FFFFFFFF</color>
|
||||
<color name="boss_bg_start">#FFF1F6EE</color>
|
||||
<color name="boss_bg_end">#FFE3F0E3</color>
|
||||
<color name="boss_card_stroke">#1A0F1B12</color>
|
||||
<color name="boss_bg_start">#FFF7F7F7</color>
|
||||
<color name="boss_bg_end">#FFF7F7F7</color>
|
||||
<color name="boss_bg_app">#FFF7F7F7</color>
|
||||
<color name="boss_panel">#FFFFFFFF</color>
|
||||
<color name="boss_card_stroke">#14000000</color>
|
||||
<color name="boss_divider">#FFEAEAEA</color>
|
||||
<color name="boss_text_primary">#FF111111</color>
|
||||
<color name="boss_text_muted">#FF5F6B63</color>
|
||||
<color name="boss_text_soft">#FF8E8E93</color>
|
||||
<color name="colorPrimary">@color/boss_green</color>
|
||||
<color name="colorPrimaryDark">@color/boss_green_dark</color>
|
||||
<color name="colorAccent">@color/boss_green</color>
|
||||
|
||||
@@ -6,17 +6,17 @@
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="android:windowBackground">@drawable/bg_app_gradient</item>
|
||||
<item name="android:windowBackground">@color/boss_bg_app</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="android:windowBackground">@drawable/bg_app_gradient</item>
|
||||
<item name="android:windowBackground">@color/boss_bg_app</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="AppTheme.NoActionBarLaunch" parent="AppTheme.NoActionBar">
|
||||
<item name="android:windowBackground">@drawable/bg_app_gradient</item>
|
||||
<item name="android:windowBackground">@color/boss_bg_app</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -48,6 +48,22 @@ public class WechatSurfaceMapperTest {
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rootTabOrder_isWechatStyle() throws Exception {
|
||||
assertArrayEquals(
|
||||
new String[]{"会话", "设备", "我的"},
|
||||
WechatSurfaceMapper.rootTabLabels()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mainPage_doesNotExposeOpsEntry() throws Exception {
|
||||
assertArrayEquals(
|
||||
new String[]{"账号与安全", "AI 账号", "设置", "技能", "关于"},
|
||||
WechatSurfaceMapper.rootMeMenuTitles()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void projectQuickActions_keepOnlyGoalsAndVersions() throws Exception {
|
||||
assertArrayEquals(
|
||||
|
||||
Reference in New Issue
Block a user