fix(composer): 断连时禁止发送并消除输入扩展迟滞
This commit is contained in:
parent
d036ef5ccd
commit
91739840ee
@ -132,6 +132,14 @@ export const messageMethods = {
|
|||||||
if (this.streamingUi) {
|
if (this.streamingUi) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!this.isConnected) {
|
||||||
|
this.uiPushToast({
|
||||||
|
title: '连接已断开',
|
||||||
|
message: '当前无法发送消息,请等待连接恢复后重试',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (this.mediaUploading) {
|
if (this.mediaUploading) {
|
||||||
this.uiPushToast({
|
this.uiPushToast({
|
||||||
title: '上传中',
|
title: '上传中',
|
||||||
|
|||||||
@ -60,11 +60,15 @@
|
|||||||
+
|
+
|
||||||
</button>
|
</button>
|
||||||
<textarea
|
<textarea
|
||||||
|
:key="composerInputKey"
|
||||||
ref="stadiumInput"
|
ref="stadiumInput"
|
||||||
class="stadium-input"
|
class="stadium-input"
|
||||||
rows="1"
|
rows="1"
|
||||||
:value="inputMessage"
|
:value="inputMessage"
|
||||||
:disabled="!isConnected || streamingMessage || inputLocked"
|
:disabled="!isConnected || streamingMessage || inputLocked"
|
||||||
|
autocomplete="off"
|
||||||
|
autocorrect="off"
|
||||||
|
autocapitalize="off"
|
||||||
placeholder="输入消息... (Ctrl+Enter 发送)"
|
placeholder="输入消息... (Ctrl+Enter 发送)"
|
||||||
@input="onInput"
|
@input="onInput"
|
||||||
@focus="$emit('input-focus')"
|
@focus="$emit('input-focus')"
|
||||||
@ -306,12 +310,15 @@ const applyLineMetrics = (lines: number, multiline: boolean) => {
|
|||||||
inputStore.setInputMultiline(multiline);
|
inputStore.setInputMultiline(multiline);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const composerInputKey = computed(
|
||||||
|
() => `${props.currentConversationId || 'new'}:${props.isConnected ? 'online' : 'offline'}`
|
||||||
|
);
|
||||||
|
|
||||||
const adjustTextareaSize = () => {
|
const adjustTextareaSize = () => {
|
||||||
const textarea = stadiumInput.value;
|
const textarea = stadiumInput.value;
|
||||||
if (!textarea) {
|
if (!textarea) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const previousHeight = textarea.offsetHeight;
|
|
||||||
textarea.style.height = 'auto';
|
textarea.style.height = 'auto';
|
||||||
const computedStyle = window.getComputedStyle(textarea);
|
const computedStyle = window.getComputedStyle(textarea);
|
||||||
const lineHeight = parseFloat(computedStyle.lineHeight || '20') || 20;
|
const lineHeight = parseFloat(computedStyle.lineHeight || '20') || 20;
|
||||||
@ -320,20 +327,15 @@ const adjustTextareaSize = () => {
|
|||||||
const lines = Math.max(1, Math.round(targetHeight / lineHeight));
|
const lines = Math.max(1, Math.round(targetHeight / lineHeight));
|
||||||
const multiline = targetHeight > lineHeight * 1.4;
|
const multiline = targetHeight > lineHeight * 1.4;
|
||||||
applyLineMetrics(lines, multiline);
|
applyLineMetrics(lines, multiline);
|
||||||
|
textarea.style.height = `${targetHeight}px`;
|
||||||
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`;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onInput = (event: Event) => {
|
const onInput = (event: Event) => {
|
||||||
const target = event.target as HTMLTextAreaElement;
|
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('update:input-message', target.value);
|
||||||
emit('input-change');
|
emit('input-change');
|
||||||
adjustTextareaSize();
|
adjustTextareaSize();
|
||||||
@ -435,6 +437,17 @@ watch(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.isConnected,
|
||||||
|
async (connected) => {
|
||||||
|
if (!connected && stadiumInput.value) {
|
||||||
|
stadiumInput.value.blur();
|
||||||
|
}
|
||||||
|
await nextTick();
|
||||||
|
adjustTextareaSize();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
adjustTextareaSize();
|
adjustTextareaSize();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -232,8 +232,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
transition:
|
transition:
|
||||||
padding 0.2s ease,
|
|
||||||
min-height 0.2s ease,
|
|
||||||
box-shadow 0.45s cubic-bezier(0.4, 0, 0.2, 1),
|
box-shadow 0.45s cubic-bezier(0.4, 0, 0.2, 1),
|
||||||
border-color 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;
|
outline: none;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
scrollbar-width: none;
|
scrollbar-width: none;
|
||||||
transition: height 0.28s cubic-bezier(0.4, 0, 0.2, 1);
|
transition: none;
|
||||||
will-change: height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.stadium-input:disabled {
|
.stadium-input:disabled {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user