Skip duplicate chat payloads and batch layouts
This commit is contained in:
@@ -371,6 +371,9 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
if (projectMessagesPayload == null) {
|
||||
return false;
|
||||
}
|
||||
if (trySkipUnchangedRealtimeMessagesPatch(projectMessagesPayload)) {
|
||||
return true;
|
||||
}
|
||||
if (tryAppendRealtimeMessagesPatch(projectMessagesPayload)) {
|
||||
return true;
|
||||
}
|
||||
@@ -386,6 +389,33 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean trySkipUnchangedRealtimeMessagesPatch(JSONObject projectMessagesPayload) {
|
||||
if (currentRenderedProjectPayload == null || projectMessagesPayload == null) {
|
||||
return false;
|
||||
}
|
||||
JSONObject currentProject = currentRenderedProjectPayload.optJSONObject("project");
|
||||
JSONObject nextProject = projectMessagesPayload.optJSONObject("project");
|
||||
if (currentProject == null || nextProject == null) {
|
||||
return false;
|
||||
}
|
||||
if (!TextUtils.equals(
|
||||
currentProject.optString("id", "").trim(),
|
||||
nextProject.optString("id", "").trim()
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
JSONArray currentMessages = currentProject.optJSONArray("messages");
|
||||
JSONArray nextMessages = nextProject.optJSONArray("messages");
|
||||
if (currentMessages == null || nextMessages == null) {
|
||||
return false;
|
||||
}
|
||||
if (!TextUtils.equals(currentMessages.toString(), nextMessages.toString())) {
|
||||
return false;
|
||||
}
|
||||
currentRenderedProjectPayload = copyJson(projectMessagesPayload);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean tryAppendRealtimeMessagesPatch(JSONObject projectMessagesPayload) {
|
||||
if (currentRenderedProjectPayload == null
|
||||
|| contentLayout == null
|
||||
@@ -434,13 +464,15 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
|
||||
selectionState = ProjectChatUiState.reconcileSelection(selectionState, nextIds);
|
||||
renderNearBottom = isChatNearBottom();
|
||||
for (int i = currentIds.size(); i < nextMessages.length(); i++) {
|
||||
JSONObject message = nextMessages.optJSONObject(i);
|
||||
if (message == null) {
|
||||
continue;
|
||||
runWithSuppressedContentLayout(() -> {
|
||||
for (int i = currentIds.size(); i < nextMessages.length(); i++) {
|
||||
JSONObject message = nextMessages.optJSONObject(i);
|
||||
if (message == null) {
|
||||
continue;
|
||||
}
|
||||
appendContent(buildMessageView(message));
|
||||
}
|
||||
appendContent(buildMessageView(message));
|
||||
}
|
||||
});
|
||||
currentRenderedProjectPayload = copyJson(projectMessagesPayload);
|
||||
setRefreshing(false);
|
||||
updateSelectionUi();
|
||||
@@ -638,45 +670,47 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
updateProjectHeader(title, buildProjectSubtitle(projectFolderName, devices));
|
||||
|
||||
renderQuickActions();
|
||||
replaceContent();
|
||||
pendingOutgoingBubble = null;
|
||||
if (currentPendingDispatchPlan != null) {
|
||||
appendContent(buildPendingDispatchPlanView(currentPendingDispatchPlan));
|
||||
} else if (projectIsGroup && "rejected".equals(projectApprovalState) && currentRejectedDispatchPlan != null) {
|
||||
appendContent(buildRejectedDispatchPlanView(currentRejectedDispatchPlan));
|
||||
}
|
||||
if (projectIsGroup
|
||||
&& effectiveParticipantsPayload != null
|
||||
&& effectiveParticipantsPayload.optBoolean("repairRequired", false)) {
|
||||
appendContent(buildRepairGroupMembersView(effectiveParticipantsPayload));
|
||||
}
|
||||
|
||||
JSONArray messages = project == null ? null : project.optJSONArray("messages");
|
||||
selectionState = ProjectChatUiState.reconcileSelection(selectionState, collectMessageIds(messages));
|
||||
if (messages != null && messages.length() > 0) {
|
||||
for (int i = 0; i < messages.length(); i++) {
|
||||
JSONObject message = messages.optJSONObject(i);
|
||||
if (message == null) {
|
||||
continue;
|
||||
}
|
||||
appendContent(buildMessageView(message));
|
||||
runWithSuppressedContentLayout(() -> {
|
||||
replaceContent();
|
||||
pendingOutgoingBubble = null;
|
||||
if (currentPendingDispatchPlan != null) {
|
||||
appendContent(buildPendingDispatchPlanView(currentPendingDispatchPlan));
|
||||
} else if (projectIsGroup && "rejected".equals(projectApprovalState) && currentRejectedDispatchPlan != null) {
|
||||
appendContent(buildRejectedDispatchPlanView(currentRejectedDispatchPlan));
|
||||
}
|
||||
if (projectIsGroup
|
||||
&& effectiveParticipantsPayload != null
|
||||
&& effectiveParticipantsPayload.optBoolean("repairRequired", false)) {
|
||||
appendContent(buildRepairGroupMembersView(effectiveParticipantsPayload));
|
||||
}
|
||||
} else {
|
||||
appendContent(BossUi.buildMessagePlaceholder(this, "还没有项目消息,先发一条开始对话。"));
|
||||
}
|
||||
|
||||
boolean masterAgentHasReply = isMasterAgentConversation()
|
||||
&& ProjectChatUiState.hasReplyBeyondBaseline(project, masterAgentReplyBaselineMessageId);
|
||||
if (masterAgentHasReply) {
|
||||
clearMasterAgentReplyState();
|
||||
}
|
||||
if (isMasterAgentConversation()) {
|
||||
if (masterAgentReplyWaiting) {
|
||||
appendContent(buildMasterAgentReplyStateView(false));
|
||||
} else if (masterAgentReplyTimedOut) {
|
||||
appendContent(buildMasterAgentReplyStateView(true));
|
||||
if (messages != null && messages.length() > 0) {
|
||||
for (int i = 0; i < messages.length(); i++) {
|
||||
JSONObject message = messages.optJSONObject(i);
|
||||
if (message == null) {
|
||||
continue;
|
||||
}
|
||||
appendContent(buildMessageView(message));
|
||||
}
|
||||
} else {
|
||||
appendContent(BossUi.buildMessagePlaceholder(this, "还没有项目消息,先发一条开始对话。"));
|
||||
}
|
||||
}
|
||||
|
||||
boolean masterAgentHasReply = isMasterAgentConversation()
|
||||
&& ProjectChatUiState.hasReplyBeyondBaseline(project, masterAgentReplyBaselineMessageId);
|
||||
if (masterAgentHasReply) {
|
||||
clearMasterAgentReplyState();
|
||||
}
|
||||
if (isMasterAgentConversation()) {
|
||||
if (masterAgentReplyWaiting) {
|
||||
appendContent(buildMasterAgentReplyStateView(false));
|
||||
} else if (masterAgentReplyTimedOut) {
|
||||
appendContent(buildMasterAgentReplyStateView(true));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
currentRenderedProjectPayload = copyJson(payload);
|
||||
setRefreshing(false);
|
||||
@@ -686,6 +720,22 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void runWithSuppressedContentLayout(Runnable action) {
|
||||
if (action == null) {
|
||||
return;
|
||||
}
|
||||
if (contentLayout == null) {
|
||||
action.run();
|
||||
return;
|
||||
}
|
||||
contentLayout.suppressLayout(true);
|
||||
try {
|
||||
action.run();
|
||||
} finally {
|
||||
contentLayout.suppressLayout(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRealtimeSubscription() {
|
||||
if (apiClient != null && apiClient.hasSessionHints()) {
|
||||
realtimeClient.start();
|
||||
|
||||
Reference in New Issue
Block a user