perf: live mode entry
This commit is contained in:
@@ -1,19 +1,16 @@
|
||||
<template>
|
||||
<div class="input-area fade-in"
|
||||
@dragover.prevent="handleDragOver"
|
||||
@dragleave.prevent="handleDragLeave"
|
||||
<div class="input-area fade-in" @dragover.prevent="handleDragOver" @dragleave.prevent="handleDragLeave"
|
||||
@drop.prevent="handleDrop">
|
||||
<div class="input-container"
|
||||
:style="{
|
||||
width: '85%',
|
||||
maxWidth: '900px',
|
||||
margin: '0 auto',
|
||||
border: isDark ? 'none' : '1px solid #e0e0e0',
|
||||
borderRadius: '24px',
|
||||
boxShadow: isDark ? 'none' : '0px 2px 2px rgba(0, 0, 0, 0.1)',
|
||||
backgroundColor: isDark ? '#2d2d2d' : 'transparent',
|
||||
position: 'relative'
|
||||
}">
|
||||
<div class="input-container" :style="{
|
||||
width: '85%',
|
||||
maxWidth: '900px',
|
||||
margin: '0 auto',
|
||||
border: isDark ? 'none' : '1px solid #e0e0e0',
|
||||
borderRadius: '24px',
|
||||
boxShadow: isDark ? 'none' : '0px 2px 2px rgba(0, 0, 0, 0.1)',
|
||||
backgroundColor: isDark ? '#2d2d2d' : 'transparent',
|
||||
position: 'relative'
|
||||
}">
|
||||
<!-- 拖拽上传遮罩 -->
|
||||
<transition name="fade">
|
||||
<div v-if="isDragging" class="drop-overlay">
|
||||
@@ -30,35 +27,24 @@
|
||||
<v-icon size="small" class="reply-icon">mdi-reply</v-icon>
|
||||
"<span class="reply-text">{{ props.replyTo.selectedText }}</span>"
|
||||
</div>
|
||||
<v-btn @click="handleClearReply" class="remove-reply-btn" icon="mdi-close" size="x-small" color="grey" variant="text" />
|
||||
<v-btn @click="handleClearReply" class="remove-reply-btn" icon="mdi-close" size="x-small"
|
||||
color="grey" variant="text" />
|
||||
</div>
|
||||
</transition>
|
||||
<textarea
|
||||
ref="inputField"
|
||||
v-model="localPrompt"
|
||||
@keydown="handleKeyDown"
|
||||
:disabled="disabled"
|
||||
<textarea ref="inputField" v-model="localPrompt" @keydown="handleKeyDown" :disabled="disabled"
|
||||
placeholder="Ask AstrBot..."
|
||||
style="width: 100%; resize: none; outline: none; border: 1px solid var(--v-theme-border); border-radius: 12px; padding: 12px 16px; min-height: 40px; font-family: inherit; font-size: 16px; background-color: var(--v-theme-surface);"></textarea>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; padding: 6px 14px;">
|
||||
<div style="display: flex; justify-content: flex-start; margin-top: 4px; align-items: center; gap: 8px;">
|
||||
<div
|
||||
style="display: flex; justify-content: flex-start; margin-top: 4px; align-items: center; gap: 8px;">
|
||||
<!-- Settings Menu -->
|
||||
<StyledMenu offset="8" location="top start" :close-on-content-click="false">
|
||||
<template v-slot:activator="{ props: activatorProps }">
|
||||
<v-btn
|
||||
v-bind="activatorProps"
|
||||
icon="mdi-plus"
|
||||
variant="text"
|
||||
color="deep-purple"
|
||||
/>
|
||||
<v-btn v-bind="activatorProps" icon="mdi-plus" variant="text" color="deep-purple" />
|
||||
</template>
|
||||
|
||||
|
||||
<!-- Upload Files -->
|
||||
<v-list-item
|
||||
class="styled-menu-item"
|
||||
rounded="md"
|
||||
@click="triggerImageInput"
|
||||
>
|
||||
<v-list-item class="styled-menu-item" rounded="md" @click="triggerImageInput">
|
||||
<template v-slot:prepend>
|
||||
<v-icon icon="mdi-file-upload-outline" size="small"></v-icon>
|
||||
</template>
|
||||
@@ -66,22 +52,14 @@
|
||||
{{ tm('input.upload') }}
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
|
||||
|
||||
<!-- Config Selector in Menu -->
|
||||
<ConfigSelector
|
||||
:session-id="sessionId || null"
|
||||
:platform-id="sessionPlatformId"
|
||||
:is-group="sessionIsGroup"
|
||||
:initial-config-id="props.configId"
|
||||
@config-changed="handleConfigChange"
|
||||
/>
|
||||
|
||||
<ConfigSelector :session-id="sessionId || null" :platform-id="sessionPlatformId"
|
||||
:is-group="sessionIsGroup" :initial-config-id="props.configId"
|
||||
@config-changed="handleConfigChange" />
|
||||
|
||||
<!-- Streaming Toggle in Menu -->
|
||||
<v-list-item
|
||||
class="styled-menu-item"
|
||||
rounded="md"
|
||||
@click="$emit('toggleStreaming')"
|
||||
>
|
||||
<v-list-item class="styled-menu-item" rounded="md" @click="$emit('toggleStreaming')">
|
||||
<template v-slot:prepend>
|
||||
<v-icon :icon="enableStreaming ? 'mdi-flash' : 'mdi-flash-off'" size="small"></v-icon>
|
||||
</template>
|
||||
@@ -90,15 +68,14 @@
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
</StyledMenu>
|
||||
|
||||
|
||||
<!-- Provider/Model Selector Menu -->
|
||||
<ProviderModelMenu v-if="showProviderSelector" ref="providerModelMenuRef" />
|
||||
</div>
|
||||
<div style="display: flex; justify-content: flex-end; margin-top: 8px; align-items: center;">
|
||||
<input type="file" ref="imageInputRef" @change="handleFileSelect"
|
||||
style="display: none" multiple />
|
||||
<input type="file" ref="imageInputRef" @change="handleFileSelect" style="display: none" multiple />
|
||||
<v-progress-circular v-if="disabled" indeterminate size="16" class="mr-1" width="1.5" />
|
||||
<v-btn @click="$emit('openLiveMode')"
|
||||
<!-- <v-btn @click="$emit('openLiveMode')"
|
||||
icon
|
||||
variant="text"
|
||||
color="purple"
|
||||
@@ -108,15 +85,11 @@
|
||||
<v-tooltip activator="parent" location="top">
|
||||
{{ tm('voice.liveMode') }}
|
||||
</v-tooltip>
|
||||
</v-btn>
|
||||
<v-btn @click="handleRecordClick"
|
||||
icon
|
||||
variant="text"
|
||||
:color="isRecording ? 'error' : 'deep-purple'"
|
||||
class="record-btn"
|
||||
size="small"
|
||||
>
|
||||
<v-icon :icon="isRecording ? 'mdi-stop-circle' : 'mdi-microphone'" variant="text" plain></v-icon>
|
||||
</v-btn> -->
|
||||
<v-btn @click="handleRecordClick" icon variant="text" :color="isRecording ? 'error' : 'deep-purple'"
|
||||
class="record-btn" size="small">
|
||||
<v-icon :icon="isRecording ? 'mdi-stop-circle' : 'mdi-microphone'" variant="text"
|
||||
plain></v-icon>
|
||||
<v-tooltip activator="parent" location="top">
|
||||
{{ isRecording ? tm('voice.speaking') : tm('voice.startRecording') }}
|
||||
</v-tooltip>
|
||||
@@ -128,11 +101,12 @@
|
||||
</div>
|
||||
|
||||
<!-- 附件预览区 -->
|
||||
<div class="attachments-preview" v-if="stagedImagesUrl.length > 0 || stagedAudioUrl || (stagedFiles && stagedFiles.length > 0)">
|
||||
<div class="attachments-preview"
|
||||
v-if="stagedImagesUrl.length > 0 || stagedAudioUrl || (stagedFiles && stagedFiles.length > 0)">
|
||||
<div v-for="(img, index) in stagedImagesUrl" :key="'img-' + index" class="image-preview">
|
||||
<img :src="img" class="preview-image" />
|
||||
<v-btn @click="$emit('removeImage', index)" class="remove-attachment-btn" icon="mdi-close"
|
||||
size="small" color="error" variant="text" />
|
||||
<v-btn @click="$emit('removeImage', index)" class="remove-attachment-btn" icon="mdi-close" size="small"
|
||||
color="error" variant="text" />
|
||||
</div>
|
||||
|
||||
<div v-if="stagedAudioUrl" class="audio-preview">
|
||||
@@ -255,9 +229,17 @@ function handleReplyAfterLeave() {
|
||||
}
|
||||
|
||||
function handleKeyDown(e: KeyboardEvent) {
|
||||
// Enter 发送消息
|
||||
// Enter 发送消息或触发命令
|
||||
if (e.keyCode === 13 && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
|
||||
// 检查是否是 /astr_live_dev 命令
|
||||
if (localPrompt.value.trim() === '/astr_live_dev') {
|
||||
emit('openLiveMode');
|
||||
localPrompt.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
if (canSend.value) {
|
||||
emit('send');
|
||||
}
|
||||
@@ -458,6 +440,7 @@ defineExpose({
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
max-height: 500px;
|
||||
opacity: 1;
|
||||
@@ -475,6 +458,7 @@ defineExpose({
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
to {
|
||||
max-height: 0;
|
||||
opacity: 0;
|
||||
@@ -571,6 +555,7 @@ defineExpose({
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
@@ -581,7 +566,7 @@ defineExpose({
|
||||
.input-area {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
|
||||
.input-container {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
@click="toggleNervousMode" flat variant="text" :color="isNervousMode ? 'primary' : ''" />
|
||||
</div>
|
||||
|
||||
<span style="color: gray; padding-left: 16px;">We're developing Astr Live Mode on ChatUI & Desktop right now. Stay tuned!</span>
|
||||
|
||||
<div class="live-mode-content">
|
||||
<div class="center-circle-container" @click="handleCircleClick">
|
||||
<!-- 爆炸效果层 -->
|
||||
|
||||
Reference in New Issue
Block a user