fix: keep chat scroll usable while sending
This commit is contained in:
@@ -19,6 +19,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
@@ -61,7 +62,7 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
private LinearLayout quickActionsLayout;
|
||||
private LinearLayout composerRow;
|
||||
private LinearLayout multiSelectActionsLayout;
|
||||
private Button composerAttachmentButton;
|
||||
private ImageButton composerAttachmentButton;
|
||||
private EditText composerInput;
|
||||
private Button composerSendButton;
|
||||
private Button multiSelectForwardButton;
|
||||
@@ -105,6 +106,7 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
private boolean realtimeReloadRequiresFullSnapshot;
|
||||
private boolean reloadInFlight;
|
||||
private boolean pendingReload;
|
||||
private boolean pendingReloadMessagesOnly;
|
||||
private boolean pendingReloadForcedScrollToBottom;
|
||||
private volatile boolean activityDestroyed;
|
||||
private final Runnable conversationAutoRefreshRunnable = new Runnable() {
|
||||
@@ -114,7 +116,7 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
if (!shouldMaintainConversationAutoRefresh()) {
|
||||
return;
|
||||
}
|
||||
if (!reloadInFlight && !refreshLayout.isRefreshing() && shouldAutoRefreshConversation()) {
|
||||
if (!reloadInFlight && !isComposerBusy() && shouldAutoRefreshConversation()) {
|
||||
reload(false);
|
||||
}
|
||||
armConversationAutoRefresh();
|
||||
@@ -280,6 +282,7 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
|
||||
BossWindowInsets.applyKeyboardAvoidingInset(composerRow);
|
||||
BossWindowInsets.applyKeyboardAvoidingInset(multiSelectActionsLayout);
|
||||
bindChatRefreshScrollBridge();
|
||||
|
||||
updateProjectHeader(initialProjectName == null ? "项目详情" : initialProjectName, "正在同步项目详情...");
|
||||
if (composerAttachmentButton != null) {
|
||||
@@ -352,6 +355,18 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
reload(false);
|
||||
}
|
||||
|
||||
private void bindChatRefreshScrollBridge() {
|
||||
if (refreshLayout == null) {
|
||||
return;
|
||||
}
|
||||
refreshLayout.setOnChildScrollUpCallback((parent, child) -> {
|
||||
if (chatScrollView == null || chatScrollView.getVisibility() != View.VISIBLE) {
|
||||
return false;
|
||||
}
|
||||
return chatScrollView.canScrollVertically(-1) || chatScrollView.getScrollY() > 0;
|
||||
});
|
||||
}
|
||||
|
||||
void handleRealtimeEvent(BossRealtimeEvent event) {
|
||||
if (event == null || event.eventName.isEmpty() || projectId == null || projectId.isEmpty()) {
|
||||
return;
|
||||
@@ -371,7 +386,7 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
if (tryApplyRealtimeMessagesPatch(event)) {
|
||||
return;
|
||||
}
|
||||
runOnUiThread(() -> scheduleRealtimeReload(true));
|
||||
runOnUiThread(() -> scheduleRealtimeReload(!"project.messages.updated".equals(event.eventName)));
|
||||
}
|
||||
|
||||
private boolean tryApplyRealtimeMessagesPatch(BossRealtimeEvent event) {
|
||||
@@ -562,6 +577,10 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
return;
|
||||
}
|
||||
if (reloadInFlight) {
|
||||
pendingReloadMessagesOnly = pendingReload && pendingReloadMessagesOnly && messagesOnly;
|
||||
if (!pendingReload) {
|
||||
pendingReloadMessagesOnly = messagesOnly;
|
||||
}
|
||||
pendingReload = true;
|
||||
pendingReloadForcedScrollToBottom = pendingReloadForcedScrollToBottom || forcedScrollToBottom;
|
||||
return;
|
||||
@@ -641,20 +660,16 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
return;
|
||||
}
|
||||
boolean forcedScrollToBottom = pendingReloadForcedScrollToBottom;
|
||||
boolean messagesOnly = pendingReloadMessagesOnly;
|
||||
pendingReload = false;
|
||||
pendingReloadMessagesOnly = false;
|
||||
pendingReloadForcedScrollToBottom = false;
|
||||
reload(forcedScrollToBottom);
|
||||
reloadSnapshot(forcedScrollToBottom, messagesOnly);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setRefreshing(boolean refreshing) {
|
||||
super.setRefreshing(refreshing);
|
||||
if (composerAttachmentButton != null) {
|
||||
composerAttachmentButton.setEnabled(!refreshing && !composerSending);
|
||||
}
|
||||
if (composerInput != null) {
|
||||
composerInput.setEnabled(!refreshing);
|
||||
}
|
||||
updateComposerSendButtonState();
|
||||
updateSelectionUi();
|
||||
if (!refreshing) {
|
||||
@@ -788,7 +803,7 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
&& shouldMaintainConversationAutoRefresh()
|
||||
&& !reloadInFlight
|
||||
&& refreshLayout != null
|
||||
&& !refreshLayout.isRefreshing()) {
|
||||
&& !isComposerBusy()) {
|
||||
reload();
|
||||
}
|
||||
updateConversationAutoRefresh();
|
||||
@@ -1017,7 +1032,6 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
private void sendProjectMessage(String kind, String body) {
|
||||
composerSending = true;
|
||||
updateComposerSendButtonState();
|
||||
setRefreshing(true);
|
||||
appendPendingOutgoingBubble(body);
|
||||
scrollChatToBottom();
|
||||
executor.execute(() -> {
|
||||
@@ -1220,7 +1234,6 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
private void uploadAttachment(AttachmentComposerState.PendingAttachment attachment) {
|
||||
composerSending = true;
|
||||
updateComposerSendButtonState();
|
||||
setRefreshing(true);
|
||||
appendPendingOutgoingAttachment(attachment);
|
||||
scrollChatToBottom();
|
||||
executor.execute(() -> {
|
||||
@@ -2361,8 +2374,13 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
if (composerSendButton == null || composerInput == null) {
|
||||
return;
|
||||
}
|
||||
boolean composerBusy = isComposerBusy();
|
||||
if (composerAttachmentButton != null) {
|
||||
composerAttachmentButton.setEnabled(!composerBusy);
|
||||
}
|
||||
composerInput.setEnabled(!composerBusy);
|
||||
String body = composerInput.getText() == null ? "" : composerInput.getText().toString();
|
||||
composerSendButton.setEnabled(ProjectChatUiState.canSend(body, isComposerBusy()));
|
||||
composerSendButton.setEnabled(ProjectChatUiState.canSend(body, composerBusy));
|
||||
}
|
||||
|
||||
private boolean isComposerBusy() {
|
||||
@@ -2698,7 +2716,6 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
}
|
||||
composerSending = true;
|
||||
updateComposerSendButtonState();
|
||||
setRefreshing(true);
|
||||
showMessage(waitingMessage);
|
||||
enqueueReplyWaitPoll(waitSpec.baselineMessageId, includeDispatchPlans);
|
||||
}
|
||||
@@ -2781,7 +2798,6 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
if (!hasReply && !isMasterAgentConversation()) {
|
||||
composerSending = true;
|
||||
updateComposerSendButtonState();
|
||||
setRefreshing(true);
|
||||
}
|
||||
});
|
||||
renderedInitialSnapshot = true;
|
||||
|
||||
@@ -141,18 +141,17 @@
|
||||
android:paddingRight="12dp"
|
||||
android:paddingBottom="12dp">
|
||||
|
||||
<Button
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/project_chat_attach"
|
||||
android:layout_width="44dp"
|
||||
android:layout_height="44dp"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:background="@drawable/bg_secondary_button"
|
||||
android:minWidth="0dp"
|
||||
android:text="+"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="@color/boss_text_primary"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
android:contentDescription="发送附件"
|
||||
android:padding="12dp"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_boss_add"
|
||||
android:tint="@color/boss_text_primary" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/project_chat_input"
|
||||
|
||||
Reference in New Issue
Block a user