feat: ScriptView 复用 MessageCard 组件
- story-card 使用 MessageCard - result-chat-list 中的 assistant 消息按内容长度自动切换短消息/完整卡片模式 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -169,87 +169,47 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="story-card" :class="{ collapsed: storyCollapsed, dialogMode: resultHasScriptReplies }">
|
||||
<view class="story-head">
|
||||
<view class="story-title-wrap">
|
||||
<text class="story-title">{{ currentResult?.title || '我的人生剧本' }}</text>
|
||||
<view class="tag-row">
|
||||
<text v-for="tag in resultTags" :key="tag" class="tag">{{ tag }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="story-head-actions">
|
||||
<button class="collapse-icon" @click="toggleStoryCollapse">
|
||||
<text class="collapse-icon-text">{{ storyCollapsed ? '展开' : '收起' }}</text>
|
||||
<view class="collapse-chevron" :class="{ down: storyCollapsed }">
|
||||
<view></view>
|
||||
<view></view>
|
||||
</view>
|
||||
</button>
|
||||
<button class="copy-card-btn" @click="copyResultContent">复制</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<scroll-view
|
||||
v-if="storyCollapsed"
|
||||
class="story-body-scroll"
|
||||
scroll-y
|
||||
:enhanced="true"
|
||||
:show-scrollbar="true"
|
||||
>
|
||||
<text class="story-body" :selectable="true" :user-select="true">{{ displayedResultContent }}</text>
|
||||
</scroll-view>
|
||||
<text v-else class="story-body" :selectable="true" :user-select="true">{{ displayedResultContent }}</text>
|
||||
<view class="collapse-row" @click="toggleStoryCollapse">
|
||||
<text class="collapse-row-text">{{ storyCollapsed ? '展开全文' : '收起全文' }}</text>
|
||||
<view class="collapse-chevron" :class="{ down: storyCollapsed }">
|
||||
<view></view>
|
||||
<view></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="result-actions">
|
||||
<button class="action-btn" @click="changeDirection">换个方向</button>
|
||||
<button class="action-btn" @click="notLikeMe">不像我</button>
|
||||
<button class="action-btn" @click="continueInChat">继续生成</button>
|
||||
<button class="action-btn primary" @click="trackTtsClick">
|
||||
<text class="action-icon">{{ ttsActionIcon }}</text>
|
||||
<text>{{ ttsActionText }}</text>
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<MessageCard
|
||||
:content="displayedResultContent"
|
||||
:title="currentResult?.title"
|
||||
:tags="resultTags"
|
||||
:collapsed="storyCollapsed"
|
||||
:content-length="displayedResultContent.length"
|
||||
:is-short-message="false"
|
||||
:tts-icon="ttsActionIcon"
|
||||
:tts-text="ttsActionText"
|
||||
@toggle-collapse="toggleStoryCollapse"
|
||||
@copy="copyResultContent"
|
||||
@change-direction="changeDirection"
|
||||
@not-like-me="notLikeMe"
|
||||
@continue="continueInChat"
|
||||
@play-tts="trackTtsClick"
|
||||
/>
|
||||
|
||||
<view v-if="resultMessages.length" class="result-chat-list">
|
||||
<view
|
||||
v-for="message in resultMessages"
|
||||
:key="message.id"
|
||||
class="chat-bubble"
|
||||
:class="{ user: message.role === 'user', system: message.role === 'assistant', pending: message.pending }"
|
||||
>
|
||||
<text selectable user-select>{{ getMessageDisplayContent(message) }}</text>
|
||||
<view v-if="message.pending" class="thinking-dots">
|
||||
<view></view>
|
||||
<view></view>
|
||||
<view></view>
|
||||
</view>
|
||||
<view
|
||||
<MessageCard
|
||||
v-if="isAssistantMessage(message)"
|
||||
class="message-toggle"
|
||||
@click.stop="toggleMessageCollapse(message)"
|
||||
>
|
||||
<text>{{ isMessageCollapsed(message) ? '展开' : '收起' }}</text>
|
||||
<text class="message-toggle-icon" :class="{ open: !isMessageCollapsed(message) }">⌃</text>
|
||||
:content="message.content"
|
||||
:collapsed="isMessageCollapsed(message)"
|
||||
:content-length="message.content.length"
|
||||
:is-short-message="message.content.length < 100"
|
||||
:tts-icon="ttsPlayer.playing.value ? 'Ⅱ' : '▶'"
|
||||
:tts-text="ttsPlayer.playing.value ? '暂停' : '播放'"
|
||||
@toggle-collapse="toggleMessageCollapse(message)"
|
||||
@copy="copyMessageContent(message)"
|
||||
@change-direction="changeDirection"
|
||||
@not-like-me="notLikeMe"
|
||||
@continue="continueInChat"
|
||||
@play-tts="playMessageTts(message)"
|
||||
/>
|
||||
<view v-else class="chat-bubble user">
|
||||
<text>{{ message.content }}</text>
|
||||
<text class="bubble-time">{{ message.time }}</text>
|
||||
</view>
|
||||
<view v-if="isAssistantMessage(message)" class="message-actions">
|
||||
<button class="action-btn" @click="copyMessageContent(message)">复制</button>
|
||||
<button class="action-btn" @click="changeDirection">换个方向</button>
|
||||
<button class="action-btn" @click="notLikeMe">不像我</button>
|
||||
<button class="action-btn" @click="continueInChat">继续生成</button>
|
||||
<button class="action-btn primary" @click="playMessageTts(message)">
|
||||
<text class="action-icon">{{ ttsPlayer.playing.value ? 'Ⅱ' : '▶' }}</text>
|
||||
<text>{{ ttsPlayer.playing.value ? '暂停' : '播放' }}</text>
|
||||
</button>
|
||||
</view>
|
||||
<text class="bubble-time">{{ message.time }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -312,6 +272,7 @@ import { useTtsPlayer } from '../../composables/useTtsPlayer.js'
|
||||
import { useTypewriterStream } from '../../composables/useTypewriterStream.js'
|
||||
import { transcribeAudio } from '../../services/asr.js'
|
||||
import { streamAiScene } from '../../services/aiRuntime.js'
|
||||
import MessageCard from '../../components/MessageCard.vue'
|
||||
|
||||
const store = useAppStore()
|
||||
const pagePath = '/pages/main/ScriptView'
|
||||
|
||||
Reference in New Issue
Block a user