feat: align android conversation folders with drawer design

This commit is contained in:
kris
2026-04-05 13:49:16 +08:00
parent c8156d5f40
commit 7206be05b6
4 changed files with 171 additions and 12 deletions

View File

@@ -1028,16 +1028,40 @@ public class MainActivity extends AppCompatActivity {
String conversationType = item.optString("conversationType", "");
String folderKey = item.optString("folderKey", "");
WechatSurfaceMapper.ConversationRow row = WechatSurfaceMapper.toConversationRow(item);
String displayTitle = conversationSearchMode ? buildConversationSearchLabel(item, row) : row.threadTitle;
WechatSurfaceMapper.ConversationRow displayRow = row;
if (!displayTitle.equals(row.threadTitle)) {
displayRow = new WechatSurfaceMapper.ConversationRow(
displayTitle,
row.folderLabel,
row.lastMessagePreview,
row.timeLabel,
row.unreadCount,
row.topPinnedLabel,
row.activityIconCount,
row.isGroup,
row.avatarPrimary,
row.avatarSecondary,
row.groupAvatarMembers,
row.pinnedConversation,
row.contextStatusLabel,
row.contextStatusLevel,
row.contextUsagePercent,
row.contextIndicatorVisible,
row.contextMustFinish
);
}
final WechatSurfaceMapper.ConversationRow finalDisplayRow = displayRow;
boolean selected = selectedConversationProjectIds.contains(projectId);
String stableKey = !"".equals(projectId)
? "conversation-project:" + projectId
: "conversation-folder:" + folderKey;
String signature = row.threadTitle + "|"
+ row.lastMessagePreview + "|"
+ row.timeLabel + "|"
+ row.unreadCount + "|"
+ row.contextStatusLabel + "|"
+ row.activityIconCount + "|"
String signature = finalDisplayRow.threadTitle + "|"
+ finalDisplayRow.lastMessagePreview + "|"
+ finalDisplayRow.timeLabel + "|"
+ finalDisplayRow.unreadCount + "|"
+ finalDisplayRow.contextStatusLabel + "|"
+ finalDisplayRow.activityIconCount + "|"
+ selected + "|"
+ conversationSelectionMode;
rootItems.add(rootListItem(
@@ -1045,7 +1069,7 @@ public class MainActivity extends AppCompatActivity {
signature,
() -> BossUi.buildConversationRow(
this,
row,
finalDisplayRow,
conversationSelectionMode,
selected,
v -> {
@@ -1061,25 +1085,58 @@ public class MainActivity extends AppCompatActivity {
toggleConversationSelection(projectId);
return;
}
if ("folder_archive".equals(conversationType)) {
if ("folder_archive".equals(conversationType)
|| (conversationSearchMode && isArchivedProjectThread(item))) {
if (folderKey.isEmpty()) {
showMessage("缺少 folderKey");
return;
}
openConversationFolder(folderKey, row.threadTitle);
openConversationFolder(folderKey, resolveConversationFolderName(item, finalDisplayRow));
return;
}
if (projectId.isEmpty()) {
showMessage("缺少 projectId");
return;
}
String projectName = row.threadTitle.isEmpty() ? "未命名会话" : row.threadTitle;
String projectName = finalDisplayRow.threadTitle.isEmpty() ? "未命名会话" : finalDisplayRow.threadTitle;
openProject(projectId, projectName);
})
));
}
}
private static boolean isArchivedProjectThread(JSONObject item) {
String folderKey = item.optString("folderKey", "").trim();
if (folderKey.isEmpty()) {
return false;
}
return item.optInt("threadCount", 0) > 1;
}
private static String buildConversationSearchLabel(JSONObject item, WechatSurfaceMapper.ConversationRow row) {
if (row == null) {
return "";
}
if (isArchivedProjectThread(item)) {
String folderLabel = row.folderLabel == null ? "" : row.folderLabel.trim();
if (!folderLabel.isEmpty()) {
return folderLabel + " / " + row.threadTitle;
}
}
return row.threadTitle;
}
private static String resolveConversationFolderName(JSONObject item, WechatSurfaceMapper.ConversationRow row) {
if ("folder_archive".equals(item.optString("conversationType", ""))) {
return row.threadTitle;
}
String folderLabel = row.folderLabel == null ? "" : row.folderLabel.trim();
if (!folderLabel.isEmpty()) {
return folderLabel;
}
return row.threadTitle;
}
private void appendConversationSelectionControls(List<RootListItem> items) {
items.add(rootListItem(
"conversation-selection-summary",

View File

@@ -54,9 +54,17 @@ public final class WechatSurfaceMapper {
}
JSONObject avatar = source.optJSONObject("avatar");
boolean isGroup = source.optBoolean("isGroup", groupAvatarMembers.size() > 1);
String conversationType = source.optString("conversationType", "");
String threadTitle = source.optString("threadTitle", source.optString("title", source.optString("projectTitle", "")));
if ("folder_archive".equals(conversationType)) {
threadTitle = source.optString(
"projectTitle",
source.optString("threadTitle", source.optString("title", source.optString("folderLabel", "")))
);
}
String pinnedLabel = source.optString("topPinnedLabel", "");
return new ConversationRow(
source.optString("threadTitle", source.optString("title", source.optString("projectTitle", ""))),
threadTitle,
source.optString("folderLabel", ""),
source.optString("lastMessagePreview", source.optString("preview", "")),
source.optString("timeLabel", source.optString("latestReplyLabel", "")),