fix(composer): 断连时禁止发送并消除输入扩展迟滞

This commit is contained in:
JOJO 2026-05-06 19:19:08 +08:00
parent d036ef5ccd
commit 91739840ee
3 changed files with 33 additions and 15 deletions

View File

@ -132,6 +132,14 @@ export const messageMethods = {
if (this.streamingUi) {
return;
}
if (!this.isConnected) {
this.uiPushToast({
title: '连接已断开',
message: '当前无法发送消息,请等待连接恢复后重试',
type: 'warning'
});
return;
}
if (this.mediaUploading) {
this.uiPushToast({
title: '上传中',

View File

@ -60,11 +60,15 @@
+
</button>
<textarea
:key="composerInputKey"
ref="stadiumInput"
class="stadium-input"
rows="1"
:value="inputMessage"
:disabled="!isConnected || streamingMessage || inputLocked"
autocomplete="off"
autocorrect="off"
autocapitalize="off"
placeholder="输入消息... (Ctrl+Enter 发送)"
@input="onInput"
@focus="$emit('input-focus')"
@ -306,12 +310,15 @@ const applyLineMetrics = (lines: number, multiline: boolean) => {
inputStore.setInputMultiline(multiline);
};
const composerInputKey = computed(
() => `${props.currentConversationId || 'new'}:${props.isConnected ? 'online' : 'offline'}`
);
const adjustTextareaSize = () => {
const textarea = stadiumInput.value;
if (!textarea) {
return;
}
const previousHeight = textarea.offsetHeight;
textarea.style.height = 'auto';
const computedStyle = window.getComputedStyle(textarea);
const lineHeight = parseFloat(computedStyle.lineHeight || '20') || 20;
@ -320,20 +327,15 @@ const adjustTextareaSize = () => {
const lines = Math.max(1, Math.round(targetHeight / lineHeight));
const multiline = targetHeight > lineHeight * 1.4;
applyLineMetrics(lines, multiline);
if (Math.abs(targetHeight - previousHeight) <= 0.5) {
textarea.style.height = `${targetHeight}px`;
return;
}
textarea.style.height = `${previousHeight}px`;
void textarea.offsetHeight;
requestAnimationFrame(() => {
textarea.style.height = `${targetHeight}px`;
});
textarea.style.height = `${targetHeight}px`;
};
const onInput = (event: Event) => {
const target = event.target as HTMLTextAreaElement;
if (!props.isConnected || props.streamingMessage || props.inputLocked) {
target.value = props.inputMessage || '';
return;
}
emit('update:input-message', target.value);
emit('input-change');
adjustTextareaSize();
@ -435,6 +437,17 @@ watch(
}
);
watch(
() => props.isConnected,
async (connected) => {
if (!connected && stadiumInput.value) {
stadiumInput.value.blur();
}
await nextTick();
adjustTextareaSize();
}
);
onMounted(() => {
adjustTextareaSize();
});

View File

@ -232,8 +232,6 @@
display: flex;
gap: 12px;
transition:
padding 0.2s ease,
min-height 0.2s ease,
box-shadow 0.45s cubic-bezier(0.4, 0, 0.2, 1),
border-color 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}
@ -327,8 +325,7 @@
outline: none;
overflow-y: auto;
scrollbar-width: none;
transition: height 0.28s cubic-bezier(0.4, 0, 0.2, 1);
will-change: height;
transition: none;
}
.stadium-input:disabled {