Files
boss/docs/superpowers/plans/2026-03-29-wechat-conversations-me-ui-polish.md
2026-03-29 23:47:59 +08:00

12 KiB
Raw Permalink Blame History

微信式会话页与我的页 UI 收口 Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 把原生 Android 的 会话 根页和 我的 根页统一收口到同一套微信式产品语言,同时保持现有会话、返回、群聊、附件和登录链路不回退。

Architecture: 这次只重写原生 UI helper 和 MainActivity 的两处根页渲染绑定,不改数据模型或 API。实现顺序按 TDD 走:先补 helper 和根页渲染测试,再做最小实现,再跑 Android 单测、release 构建和 OPPO 真机回归。

Tech Stack: Java, Android AppCompat, Robolectric/JUnit, Gradle, ADB, Next.js verification scripts


Task 1: 为会话页和我的页补 UI 基线测试

Files:

  • Modify: android/app/src/test/java/com/hyzq/boss/BossUiConversationRowTest.java

  • Create: android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java

  • Test: android/app/src/test/java/com/hyzq/boss/BossUiConversationRowTest.java

  • Test: android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java

  • Step 1: 扩展会话列表项测试,明确“非卡片流”的结构约束

@Test
public void buildConversationRow_usesWechatListSpacingInsteadOfCardChrome() {
    Context context = ApplicationProvider.getApplicationContext();
    WechatSurfaceMapper.ConversationRow row = new WechatSurfaceMapper.ConversationRow(
            "北区试产线回归",
            "归档确认",
            "现场摄像头关键帧",
            "09:26",
            2,
            "置顶",
            2,
            false,
            "M",
            "W",
            new WechatSurfaceMapper.GroupAvatarMember[0]
    );

    LinearLayout view = BossUi.buildConversationRow(context, row, null);

    assertEquals(Color.WHITE, ((ColorDrawable) view.getBackground()).getColor());
    assertEquals(BossUi.dp(context, 16), view.getPaddingLeft());
    assertEquals(BossUi.dp(context, 12), view.getPaddingTop());
}
  • Step 2: 运行单测,确认它先失败

Run:

cd /Users/kris/code/boss/android
./gradlew testDebugUnitTest --tests com.hyzq.boss.BossUiConversationRowTest --no-daemon

Expected: FAIL原因是当前 buildConversationRow 仍保留卡片样式或 padding 不符合新约束。

  • Step 3: 新增根页测试,锁定“我的”页头部和菜单列表结构
@Test
public void renderMeRoot_usesWechatProfileHeaderAndFlatMenuRows() {
    MainActivity activity = Robolectric.buildActivity(MainActivity.class).create().start().resume().get();

    activity.runOnUiThread(() -> {
        activity.sessionData = new StubJSONObject()
                .withString("displayName", "Kris")
                .withString("account", "17600003315")
                .withString("role", "最高管理员");
        activity.setActiveTab("me", false);
    });
    Shadows.shadowOf(Looper.getMainLooper()).idle();

    LinearLayout content = activity.findViewById(R.id.screen_content);

    assertTrue(findText(content, "Kris"));
    assertTrue(findText(content, "17600003315"));
    assertTrue(findText(content, "账号与安全"));
    assertTrue(findText(content, "AI 账号"));
}
  • Step 4: 运行新的根页测试,确认它先失败

Run:

cd /Users/kris/code/boss/android
./gradlew testDebugUnitTest --tests com.hyzq.boss.BossUiRootSurfaceTest --no-daemon

Expected: FAIL原因是当前 renderMeRoot / buildSimpleProfileHeader 仍不满足新的微信式结构断言。

  • Step 5: 提交测试基线
cd /Users/kris/code/boss
git add android/app/src/test/java/com/hyzq/boss/BossUiConversationRowTest.java android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java
git commit -m "test: lock wechat root surface expectations"

Task 2: 重写 BossUi 的会话行、资料区和菜单行 helper

Files:

  • Modify: android/app/src/main/java/com/hyzq/boss/BossUi.java

  • Modify: android/app/src/test/java/com/hyzq/boss/BossUiConversationRowTest.java

  • Modify: android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java

  • Test: android/app/src/test/java/com/hyzq/boss/BossUiConversationRowTest.java

  • Test: android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java

  • Step 1: 实现新的会话列表行和我的页基础 helper

public static LinearLayout buildWechatMenuRow(
        Context context,
        String title,
        @Nullable String subtitle,
        @Nullable String meta,
        @Nullable String badge,
        @Nullable View.OnClickListener listener
) {
    LinearLayout row = buildListRow(context, title, subtitle, meta, badge, listener);
    row.setBackgroundColor(Color.WHITE);
    row.setPadding(dp(context, 18), dp(context, 15), dp(context, 18), dp(context, 15));
    row.setElevation(0f);
    return row;
}

public static LinearLayout buildSimpleProfileHeader(
        Context context,
        String name,
        String subtitle,
        @Nullable String detail
) {
    LinearLayout header = new LinearLayout(context);
    header.setOrientation(LinearLayout.HORIZONTAL);
    header.setBackgroundColor(Color.WHITE);
    header.setPadding(dp(context, 20), dp(context, 18), dp(context, 20), dp(context, 18));
    return header;
}
  • Step 2: 把 buildConversationRow 从卡片改成白底列表项
public static LinearLayout buildConversationRow(
        Context context,
        WechatSurfaceMapper.ConversationRow row,
        @Nullable View.OnClickListener listener
) {
    LinearLayout container = new LinearLayout(context);
    container.setOrientation(LinearLayout.HORIZONTAL);
    container.setBackgroundColor(Color.WHITE);
    container.setPadding(dp(context, 16), dp(context, 12), dp(context, 16), dp(context, 12));
    if (listener != null) {
        container.setClickable(true);
        container.setFocusable(true);
        container.setOnClickListener(listener);
    }
    return container;
}
  • Step 3: 运行 helper 相关单测,确认现在全部通过

Run:

cd /Users/kris/code/boss/android
./gradlew testDebugUnitTest --tests com.hyzq.boss.BossUiConversationRowTest --tests com.hyzq.boss.BossUiRootSurfaceTest --no-daemon

Expected: PASSBossUiConversationRowTestBossUiRootSurfaceTest 全绿。

  • Step 4: 自查复用面
cd /Users/kris/code/boss
rg -n "buildSimpleProfileHeader|buildWechatMenuRow|buildConversationRow" android/app/src/main/java/com/hyzq/boss -S

Expected: 输出覆盖 MainActivity / ConversationInfoActivity / GroupInfoActivity / GroupCreateActivity / AboutActivity 等现有入口,确认 helper 改动会统一带到深层页。

  • Step 5: 提交 helper 重写
cd /Users/kris/code/boss
git add android/app/src/main/java/com/hyzq/boss/BossUi.java android/app/src/test/java/com/hyzq/boss/BossUiConversationRowTest.java android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java
git commit -m "style: align conversations and me root surfaces"

Task 3: 收口 MainActivity 根页渲染和点击区

Files:

  • Modify: android/app/src/main/java/com/hyzq/boss/MainActivity.java

  • Modify: android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java

  • Test: android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java

  • Step 1: 调整会话页和我的页根渲染,让新 helper 真正落到主界面

private void renderConversationsRoot() {
    topTitle.setText("会话");
    topSubtitle.setVisibility(View.GONE);
    screenContent.removeAllViews();
    for (int i = 0; i < conversationsData.length(); i++) {
        JSONObject item = conversationsData.optJSONObject(i);
        if (item == null) continue;
        WechatSurfaceMapper.ConversationRow row = WechatSurfaceMapper.toConversationRow(item);
        screenContent.addView(BossUi.buildConversationRow(this, row, v -> openConversation(item)));
    }
}

private void renderMeRoot() {
    topTitle.setText("我的");
    topSubtitle.setVisibility(View.GONE);
    screenContent.removeAllViews();
    screenContent.addView(BossUi.buildSimpleProfileHeader(this, displayName, account, roleLabel));
    for (WechatSurfaceMapper.MeMenuItem item : WechatSurfaceMapper.rootMeMenuItems()) {
        screenContent.addView(BossUi.buildWechatMenuRow(this, item.title, item.description, null, null, v -> openMeItem(item.key)));
    }
}
  • Step 2: 补充点击区测试,保证菜单行和会话行整行可点
@Test
public void renderConversationsRoot_keepsConversationRowsClickable() {
    MainActivity activity = buildConversationReadyActivity();
    LinearLayout content = activity.findViewById(R.id.screen_content);
    View firstRow = content.getChildAt(1);
    assertTrue(firstRow.isClickable());
}
  • Step 3: 跑根页测试,确认主界面结构和点击区正确

Run:

cd /Users/kris/code/boss/android
./gradlew testDebugUnitTest --tests com.hyzq.boss.BossUiRootSurfaceTest --no-daemon

Expected: PASS根页结构、菜单项和点击区断言全部通过。

  • Step 4: 提交 MainActivity 收口
cd /Users/kris/code/boss
git add android/app/src/main/java/com/hyzq/boss/MainActivity.java android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java
git commit -m "style: polish native conversations and me roots"

Task 4: 合并现有关于页版本号修复并完成全链验证

Files:

  • Modify: android/app/src/main/java/com/hyzq/boss/AboutActivity.java

  • Modify: android/app/src/test/java/com/hyzq/boss/WechatSurfaceMapperTest.java

  • Modify: README.md

  • Modify: docs/architecture/current_runtime_and_deploy_status_cn.md

  • Test: android/app/src/test/java/com/hyzq/boss/WechatSurfaceMapperTest.java

  • Step 1: 保留并整理当前“关于页显示已安装版本号”的修复

private static String resolveInstalledVersionLabel(
        @Nullable JSONObject user,
        JSONObject ota,
        @Nullable String packageVersionName
) {
    if (packageVersionName != null && !packageVersionName.isEmpty()) {
        return packageVersionName;
    }
    if (user != null) {
        String userVersion = user.optString("version", "");
        if (!userVersion.isEmpty()) {
            return userVersion;
        }
    }
    return ota.optString("currentVersion", "-");
}
  • Step 2: 跑关于页测试,确认已安装版本优先级正确

Run:

cd /Users/kris/code/boss/android
./gradlew testDebugUnitTest --tests com.hyzq.boss.WechatSurfaceMapperTest --no-daemon

Expected: PASSaboutActivity_prefersInstalledPackageVersionOverServerVersion 通过。

  • Step 3: 运行完整本地验证

Run:

cd /Users/kris/code/boss
npm run lint
npm run build
curl -sS http://127.0.0.1:3000/api/health
curl -sS http://127.0.0.1:4317/health
cd android && ./gradlew testDebugUnitTest --no-daemon
cd /Users/kris/code/boss/android && ./gradlew clean assembleRelease --no-daemon

Expected:

  • lint PASS

  • build PASS

  • 两个 health 接口返回 ok

  • Android 单测 PASS

  • release 构建成功输出 APK

  • Step 4: 用 OPPO PLB110 做真机回归

Run:

adb devices -l
adb -t 501 install -r /Users/kris/code/boss/android/app/build/outputs/apk/release/app-release.apk
adb -t 501 shell am start -W -n com.hyzq.boss/.MainActivity

Manual checks:

  • 会话首页视觉不再是厚卡片流

  • 点击任意会话能进入聊天并返回

  • 我的首页顶部是微信式资料区

  • 我的 > 关于 正确显示已安装版本号

  • 底部 会话 / 设备 / 我的 切换正常

  • Step 5: 同步文档并提交

cd /Users/kris/code/boss
git add android/app/src/main/java/com/hyzq/boss/AboutActivity.java android/app/src/test/java/com/hyzq/boss/WechatSurfaceMapperTest.java README.md docs/architecture/current_runtime_and_deploy_status_cn.md
git commit -m "docs: record native root ui polish validation"