Patch conversation home from realtime events
This commit is contained in:
@@ -581,9 +581,43 @@ public class MainActivity extends AppCompatActivity {
|
||||
if (isDuplicateRealtimeEvent(eventFingerprint, now)) {
|
||||
return;
|
||||
}
|
||||
if ("conversations".equals(activeTab) && tryApplyConversationRealtimePatch(event)) {
|
||||
return;
|
||||
}
|
||||
runOnUiThread(this::scheduleRealtimeRefresh);
|
||||
}
|
||||
|
||||
private boolean tryApplyConversationRealtimePatch(BossRealtimeEvent event) {
|
||||
if (event == null || conversationsData == null) {
|
||||
return false;
|
||||
}
|
||||
if (!"conversation.updated".equals(event.eventName)
|
||||
&& !"project.messages.updated".equals(event.eventName)) {
|
||||
return false;
|
||||
}
|
||||
String affectedProjectId = event.payload.optString("projectId", "").trim();
|
||||
if (affectedProjectId.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
JSONObject conversationItem = event.payload.optJSONObject("conversationItem");
|
||||
if (conversationItem == null) {
|
||||
return false;
|
||||
}
|
||||
runOnUiThread(() -> {
|
||||
if (conversationsData == null) {
|
||||
scheduleRealtimeRefresh();
|
||||
return;
|
||||
}
|
||||
conversationsData = WechatSurfaceMapper.mergeConversationHomeItem(
|
||||
conversationsData,
|
||||
conversationItem,
|
||||
affectedProjectId
|
||||
);
|
||||
renderCurrentTab();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
private void scheduleRealtimeRefresh() {
|
||||
if (realtimeRefreshScheduled) {
|
||||
return;
|
||||
|
||||
@@ -383,6 +383,35 @@ public final class WechatSurfaceMapper {
|
||||
return sortConversationItems(passthrough);
|
||||
}
|
||||
|
||||
public static JSONArray mergeConversationHomeItem(JSONArray source, JSONObject item, String affectedProjectId) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
JSONArray merged = new JSONArray();
|
||||
String normalizedAffectedProjectId = affectedProjectId == null ? "" : affectedProjectId.trim();
|
||||
String replacementConversationId = item == null ? "" : item.optString("conversationId", "").trim();
|
||||
String replacementFolderKey = item == null ? "" : item.optString("folderKey", "").trim();
|
||||
for (int index = 0; index < source.length(); index += 1) {
|
||||
JSONObject existing = source.optJSONObject(index);
|
||||
if (existing == null) {
|
||||
continue;
|
||||
}
|
||||
if (shouldReplaceConversationItem(
|
||||
existing,
|
||||
normalizedAffectedProjectId,
|
||||
replacementConversationId,
|
||||
replacementFolderKey
|
||||
)) {
|
||||
continue;
|
||||
}
|
||||
merged.put(copyJson(existing));
|
||||
}
|
||||
if (item != null) {
|
||||
merged.put(copyJson(item));
|
||||
}
|
||||
return sortConversationItems(merged);
|
||||
}
|
||||
|
||||
private static JSONObject buildFolderArchiveItem(String folderKey, List<JSONObject> items) {
|
||||
List<JSONObject> sortedByLatest = new ArrayList<>(items);
|
||||
sortedByLatest.sort((left, right) -> compareConversationFreshness(right, left));
|
||||
@@ -488,6 +517,42 @@ public final class WechatSurfaceMapper {
|
||||
return sorted;
|
||||
}
|
||||
|
||||
private static boolean shouldReplaceConversationItem(
|
||||
JSONObject existing,
|
||||
String affectedProjectId,
|
||||
String replacementConversationId,
|
||||
String replacementFolderKey
|
||||
) {
|
||||
if (!replacementConversationId.isEmpty()
|
||||
&& replacementConversationId.equals(existing.optString("conversationId", "").trim())) {
|
||||
return true;
|
||||
}
|
||||
if (!replacementFolderKey.isEmpty()
|
||||
&& replacementFolderKey.equals(existing.optString("folderKey", "").trim())) {
|
||||
return true;
|
||||
}
|
||||
if (affectedProjectId.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (affectedProjectId.equals(existing.optString("projectId", "").trim())) {
|
||||
return true;
|
||||
}
|
||||
return arrayContainsString(existing.optJSONArray("searchTargetProjectIds"), affectedProjectId);
|
||||
}
|
||||
|
||||
private static boolean arrayContainsString(JSONArray source, String target) {
|
||||
if (source == null || target == null || target.trim().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
String normalizedTarget = target.trim();
|
||||
for (int index = 0; index < source.length(); index += 1) {
|
||||
if (normalizedTarget.equals(source.optString(index, "").trim())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int compareConversationFreshness(JSONObject left, JSONObject right) {
|
||||
String leftAt = left.optString("latestReplyAt", "");
|
||||
String rightAt = right.optString("latestReplyAt", "");
|
||||
|
||||
Reference in New Issue
Block a user