style: align group creation list with conversations

This commit is contained in:
kris
2026-03-29 19:20:37 +08:00
parent e94e91a0f7
commit fe186ad8d5
2 changed files with 55 additions and 32 deletions

View File

@@ -114,11 +114,7 @@ public class GroupCreateActivity extends BossScreenActivity {
for (JSONObject item : selectableConversations) { for (JSONObject item : selectableConversations) {
CandidateConversation candidate = new CandidateConversation( CandidateConversation candidate = new CandidateConversation(
item.optString("projectId", ""), item.optString("projectId", ""),
item.optString("projectTitle", item.optString("threadTitle", "未命名会话")), item
item.optString("folderLabel", ""),
item.optString("lastMessagePreview", item.optString("preview", "")),
item.optString("latestReplyLabel", ""),
false
); );
nextCandidates.add(candidate); nextCandidates.add(candidate);
nextCandidateProjectIds.add(candidate.projectId); nextCandidateProjectIds.add(candidate.projectId);
@@ -191,20 +187,26 @@ public class GroupCreateActivity extends BossScreenActivity {
return result; return result;
} }
static WechatSurfaceMapper.ConversationRow toCandidateConversationRow(JSONObject item, boolean selected) {
return new WechatSurfaceMapper.ConversationRow(
item.optString("projectTitle", item.optString("threadTitle", "未命名会话")),
item.optString("folderLabel", ""),
item.optString("lastMessagePreview", item.optString("preview", "")),
item.optString("latestReplyLabel", ""),
0,
selected ? "已选" : "",
0,
false,
"",
"",
new WechatSurfaceMapper.GroupAvatarMember[0]
);
}
private LinearLayout buildCandidateRow(CandidateConversation candidate) { private LinearLayout buildCandidateRow(CandidateConversation candidate) {
boolean selected = selectedProjectIds.contains(candidate.projectId); return BossUi.buildConversationRow(
String badge = selected ? "已选" : "未选";
String subtitle = candidate.folderLabel.isEmpty() ? candidate.latestReplyLabel : candidate.folderLabel;
String meta = candidate.preview;
if (!candidate.latestReplyLabel.isEmpty() && !candidate.latestReplyLabel.equals(candidate.preview)) {
meta = candidate.latestReplyLabel + (meta.isEmpty() ? "" : " · " + meta);
}
return BossUi.buildListRow(
this, this,
candidate.title, toCandidateConversationRow(candidate.sourceItem, selectedProjectIds.contains(candidate.projectId)),
subtitle,
meta,
badge,
v -> toggleSelection(candidate.projectId) v -> toggleSelection(candidate.projectId)
); );
} }
@@ -369,26 +371,14 @@ public class GroupCreateActivity extends BossScreenActivity {
private static final class CandidateConversation { private static final class CandidateConversation {
private final String projectId; private final String projectId;
private final String title; private final JSONObject sourceItem;
private final String folderLabel;
private final String preview;
private final String latestReplyLabel;
private final boolean isGroup;
private CandidateConversation( private CandidateConversation(
String projectId, String projectId,
String title, JSONObject sourceItem
String folderLabel,
String preview,
String latestReplyLabel,
boolean isGroup
) { ) {
this.projectId = projectId; this.projectId = projectId;
this.title = title; this.sourceItem = sourceItem;
this.folderLabel = folderLabel;
this.preview = preview;
this.latestReplyLabel = latestReplyLabel;
this.isGroup = isGroup;
} }
} }
} }

View File

@@ -93,6 +93,28 @@ public class GroupCreateActivityTest {
assertTrue(GroupCreateActivity.canCreateGroupChat(false, false, linkedSet("thread-1", "thread-2"), false)); assertTrue(GroupCreateActivity.canCreateGroupChat(false, false, linkedSet("thread-1", "thread-2"), false));
} }
@Test
public void toCandidateConversationRow_usesConversationCardChromeAndSelectedBadge() {
JSONObject item = new StubJSONObject()
.withString("projectId", "thread-1")
.withString("projectTitle", "北区试产线回归")
.withString("folderLabel", "Mac Studio")
.withString("lastMessagePreview", "认证链路交接线程")
.withString("latestReplyLabel", "09:26")
.withInt("unreadCount", 3)
.withInt("activityIconCount", 2);
WechatSurfaceMapper.ConversationRow row = GroupCreateActivity.toCandidateConversationRow(item, true);
assertEquals("北区试产线回归", row.threadTitle);
assertEquals("Mac Studio", row.folderLabel);
assertEquals("认证链路交接线程", row.lastMessagePreview);
assertEquals("09:26", row.timeLabel);
assertEquals("已选", row.topPinnedLabel);
assertEquals(0, row.unreadCount);
assertEquals(0, row.activityIconCount);
}
private static Set<String> linkedSet(String... values) { private static Set<String> linkedSet(String... values) {
Set<String> result = new LinkedHashSet<>(); Set<String> result = new LinkedHashSet<>();
for (String value : values) { for (String value : values) {
@@ -114,6 +136,11 @@ public class GroupCreateActivityTest {
return this; return this;
} }
StubJSONObject withInt(String key, int value) {
values.put(key, value);
return this;
}
StubJSONObject withObjectArray(String key, JSONObject... entries) { StubJSONObject withObjectArray(String key, JSONObject... entries) {
values.put(key, new StubJSONArray(entries)); values.put(key, new StubJSONArray(entries));
return this; return this;
@@ -131,6 +158,12 @@ public class GroupCreateActivityTest {
return value instanceof Boolean ? (Boolean) value : defaultValue; return value instanceof Boolean ? (Boolean) value : defaultValue;
} }
@Override
public int optInt(String key, int defaultValue) {
Object value = values.get(key);
return value instanceof Integer ? (Integer) value : defaultValue;
}
@Override @Override
public JSONArray optJSONArray(String key) { public JSONArray optJSONArray(String key) {
Object value = values.get(key); Object value = values.get(key);