fix: support archived thread search on android homepage

This commit is contained in:
kris
2026-04-05 13:58:08 +08:00
parent 7206be05b6
commit 0fcbf2d0a0
4 changed files with 100 additions and 19 deletions

View File

@@ -1086,12 +1086,12 @@ public class MainActivity extends AppCompatActivity {
return;
}
if ("folder_archive".equals(conversationType)
|| (conversationSearchMode && isArchivedProjectThread(item))) {
|| (conversationSearchMode && !item.optString("searchMatchLabel", "").isEmpty())) {
if (folderKey.isEmpty()) {
showMessage("缺少 folderKey");
return;
}
openConversationFolder(folderKey, resolveConversationFolderName(item, finalDisplayRow));
openConversationFolder(folderKey, resolveConversationFolderName(item, row));
return;
}
if (projectId.isEmpty()) {
@@ -1105,22 +1105,14 @@ public class MainActivity extends AppCompatActivity {
}
}
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;
if ("folder_archive".equals(item.optString("conversationType", ""))) {
String matchedThreadTitle = item.optString("searchMatchLabel", "").trim();
if (!matchedThreadTitle.isEmpty()) {
return row.threadTitle + " / " + matchedThreadTitle;
}
}
return row.threadTitle;
@@ -1321,7 +1313,17 @@ public class MainActivity extends AppCompatActivity {
continue;
}
if (matchesConversationQuery(item, query)) {
filtered.put(item);
JSONObject filteredItem = item;
try {
filteredItem = new JSONObject(item.toString());
String matchLabel = resolveConversationSearchMatchLabel(item, query);
if (!matchLabel.isEmpty()) {
filteredItem.put("searchMatchLabel", matchLabel);
}
} catch (Exception ignored) {
// Keep the original item if JSON cloning fails.
}
filtered.put(filteredItem);
}
}
return filtered;
@@ -1426,6 +1428,9 @@ public class MainActivity extends AppCompatActivity {
if (query.isEmpty()) {
return true;
}
if (!resolveConversationSearchMatchLabel(item, query).isEmpty()) {
return true;
}
String[] fields = new String[] {
item.optString("projectTitle", ""),
item.optString("threadTitle", ""),
@@ -1441,6 +1446,26 @@ public class MainActivity extends AppCompatActivity {
return false;
}
private static String resolveConversationSearchMatchLabel(JSONObject item, String query) {
if (item == null || query == null || query.isEmpty()) {
return "";
}
if (!"folder_archive".equals(item.optString("conversationType", ""))) {
return "";
}
JSONArray searchAliases = item.optJSONArray("searchAliases");
if (searchAliases == null) {
return "";
}
for (int i = 0; i < searchAliases.length(); i++) {
String alias = searchAliases.optString(i, "").trim();
if (!alias.isEmpty() && alias.toLowerCase().contains(query)) {
return alias;
}
}
return "";
}
private void renderDevicesRoot() {
if (screenList == null) {
return;

View File

@@ -49,6 +49,27 @@ public class MainActivityConversationSearchTest {
assertEquals("p2", filteredByFolder.optJSONObject(0).optString("projectId", ""));
}
@Test
public void filterConversationItemsMatchesFolderArchiveSearchAliases() throws Exception {
JSONArray source = new JSONArray()
.put(new JSONObject()
.put("projectId", "folder-boss")
.put("conversationType", "folder_archive")
.put("folderKey", "mac-studio:boss")
.put("projectTitle", "Boss")
.put("threadTitle", "Boss")
.put("folderLabel", "2 个线程 · 最近:发布回滚")
.put("searchAliases", new JSONArray().put("发布回滚").put("Android UI 收尾"))
.put("lastMessagePreview", "最近:发布回滚")
.put("latestReplyLabel", "11:00"));
JSONArray filtered = MainActivity.filterConversationItems(source, "发布回滚");
assertEquals(1, filtered.length());
assertEquals("folder-boss", filtered.optJSONObject(0).optString("projectId", ""));
assertEquals("发布回滚", filtered.optJSONObject(0).optString("searchMatchLabel", ""));
}
@Test
public void conversationsHeader_usesSearchIconAndPlusButton() throws Exception {
MainActivity activity = Robolectric.buildActivity(MainActivity.class).setup().get();
@@ -103,15 +124,15 @@ public class MainActivityConversationSearchTest {
MainActivity activity = Robolectric.buildActivity(MainActivity.class).setup().get();
ReflectionHelpers.setField(activity, "conversationsData", new JSONArray()
.put(new JSONObject()
.put("projectId", "boss-thread-1")
.put("conversationType", "single_device")
.put("projectId", "folder-boss")
.put("conversationType", "folder_archive")
.put("folderKey", "mac-studio:boss")
.put("folderLabel", "Boss")
.put("projectTitle", "Boss")
.put("threadTitle", "发布回滚")
.put("threadTitle", "Boss")
.put("lastMessagePreview", "最近:发布回滚")
.put("latestReplyLabel", "11:00")
.put("threadCount", 2)));
.put("searchAliases", new JSONArray().put("发布回滚").put("Android UI 收尾"))));
ReflectionHelpers.callInstanceMethod(activity, "showContent");
Shadows.shadowOf(activity.getMainLooper()).idle();