mirror of
https://github.com/vegu-ai/talemate.git
synced 2026-09-01 19:48:52 +02:00
Refactor message toolbar integration across components for improved action handling
This commit is contained in:
@@ -56,55 +56,29 @@
|
||||
</div>
|
||||
</div>
|
||||
<v-sheet v-if="hovered" rounded="sm" color="transparent">
|
||||
<v-chip size="x-small" color="indigo-lighten-4" v-if="editing">
|
||||
<v-icon class="mr-1">mdi-pencil</v-icon>
|
||||
Editing - Press `enter` to submit. Click anywhere to cancel.</v-chip>
|
||||
<v-chip size="x-small" color="grey-lighten-1" v-else-if="!editing && hovered" variant="text" class="mr-1">
|
||||
<v-icon>mdi-pencil</v-icon>
|
||||
Double-click to edit.</v-chip>
|
||||
|
||||
<!-- create pin -->
|
||||
<v-chip size="x-small" label color="success" v-if="!editing && hovered" variant="outlined" @click="createPin(message_id)" :disabled="uxLocked">
|
||||
<v-icon class="mr-1">mdi-pin</v-icon>
|
||||
Create Pin
|
||||
</v-chip>
|
||||
|
||||
<!-- revision -->
|
||||
<v-chip size="x-small" class="ml-2" label color="dirty" v-if="!editing && hovered && editorRevisionsEnabled && isLastMessage" variant="outlined" @click="reviseMessage(message_id)" :disabled="uxLocked">
|
||||
<v-icon class="mr-1">mdi-typewriter</v-icon>
|
||||
Editor Revision
|
||||
</v-chip>
|
||||
|
||||
<!-- fork scene -->
|
||||
<v-chip size="x-small" class="ml-2" label :color="rev > 0 ? 'highlight1' : 'muted'" v-if="!editing && hovered && forkable" variant="outlined" @click="forkSceneInitiate(message_id)" :disabled="uxLocked">
|
||||
<v-icon class="mr-1">mdi-source-fork</v-icon>
|
||||
Fork
|
||||
</v-chip>
|
||||
|
||||
<!-- generate continuation -->
|
||||
<v-chip size="x-small" class="ml-2" label color="primary" v-if="!editing && hovered && !continuing && isLastMessage" variant="outlined" @click="continueConversation" :disabled="uxLocked">
|
||||
<v-icon class="mr-1">mdi-fast-forward</v-icon>
|
||||
Continue
|
||||
</v-chip>
|
||||
<v-chip size="x-small" class="ml-2" label color="primary" v-if="!editing && hovered && continuing && isLastMessage" variant="outlined" disabled>
|
||||
<v-progress-circular class="mr-1" size="14" indeterminate="disable-shrink" color="primary"></v-progress-circular>
|
||||
Continuing...
|
||||
</v-chip>
|
||||
|
||||
<!-- generate tts -->
|
||||
<v-chip size="x-small" class="ml-2" label color="secondary" v-if="!editing && hovered && ttsAvailable" variant="outlined" @click="generateTTS(message_id)" :disabled="uxLocked || ttsBusy">
|
||||
<v-icon class="mr-1">mdi-account-voice</v-icon>
|
||||
TTS
|
||||
<v-progress-circular v-if="ttsBusy" class="ml-2" size="14" indeterminate="disable-shrink"
|
||||
color="secondary"></v-progress-circular>
|
||||
</v-chip>
|
||||
|
||||
<!-- insert time passage -->
|
||||
<v-chip size="x-small" class="ml-2" label color="time" v-if="!editing && hovered" variant="outlined" @click="insertTimePassage(message_id)" :disabled="uxLocked">
|
||||
<v-icon class="mr-1">mdi-clock-plus-outline</v-icon>
|
||||
Time Passage
|
||||
</v-chip>
|
||||
|
||||
<MessageToolbar
|
||||
:message-id="message_id"
|
||||
:editing="editing"
|
||||
:ux-locked="uxLocked"
|
||||
:is-last-message="isLastMessage"
|
||||
:editor-revisions-enabled="editorRevisionsEnabled"
|
||||
:tts-available="ttsAvailable"
|
||||
:tts-busy="ttsBusy"
|
||||
:rev="rev"
|
||||
:scene-rev="sceneRev"
|
||||
>
|
||||
<template #extra-actions>
|
||||
<!-- generate continuation -->
|
||||
<v-chip size="x-small" class="ml-2" label color="primary" v-if="!continuing && isLastMessage" variant="outlined" @click="continueConversation" :disabled="uxLocked">
|
||||
<v-icon class="mr-1">mdi-fast-forward</v-icon>
|
||||
Continue
|
||||
</v-chip>
|
||||
<v-chip size="x-small" class="ml-2" label color="primary" v-if="continuing && isLastMessage" variant="outlined" disabled>
|
||||
<v-progress-circular class="mr-1" size="14" indeterminate="disable-shrink" color="primary"></v-progress-circular>
|
||||
Continuing...
|
||||
</v-chip>
|
||||
</template>
|
||||
</MessageToolbar>
|
||||
</v-sheet>
|
||||
<div v-else style="height:24px">
|
||||
|
||||
@@ -119,13 +93,14 @@ import { isPrimaryModifier } from '@/utils/keyboardModifiers';
|
||||
import MessageAssetImage from './MessageAssetImage.vue';
|
||||
import MessageAssetMixin from './MessageAssetMixin.js';
|
||||
import RevisionNav from './RevisionNav.vue';
|
||||
import MessageToolbar from './MessageToolbar.vue';
|
||||
export default {
|
||||
components: {
|
||||
MessageAssetImage,
|
||||
RevisionNav,
|
||||
MessageToolbar,
|
||||
},
|
||||
mixins: [MessageAssetMixin],
|
||||
//props: ['character', 'text', 'color', 'message_id', 'uxLocked', 'isLastMessage'],
|
||||
props: {
|
||||
character: {
|
||||
type: String,
|
||||
@@ -211,15 +186,10 @@ export default {
|
||||
emits: ['navigate-revision'],
|
||||
inject: [
|
||||
'requestDeleteMessage',
|
||||
'getWebsocket',
|
||||
'createPin',
|
||||
'forkSceneInitiate',
|
||||
'autocompleteRequest',
|
||||
'autocompleteInfoMessage',
|
||||
'getMessageStyle',
|
||||
'reviseMessage',
|
||||
'generateTTS',
|
||||
'insertTimePassage',
|
||||
'getWebsocket',
|
||||
'autocompleteRequest',
|
||||
'autocompleteInfoMessage',
|
||||
'getMessageStyle',
|
||||
],
|
||||
computed: {
|
||||
parser() {
|
||||
@@ -244,9 +214,6 @@ export default {
|
||||
renderedText() {
|
||||
return this.parser.parse(this.text);
|
||||
},
|
||||
forkable() {
|
||||
return this.rev <= this.sceneRev;
|
||||
},
|
||||
characterData() {
|
||||
if (!this.scene || !this.scene.data || !this.scene.data.characters) {
|
||||
return null;
|
||||
|
||||
@@ -49,20 +49,17 @@
|
||||
</div>
|
||||
|
||||
<v-sheet v-if="hovered" rounded="sm" color="transparent">
|
||||
<v-chip size="x-small" color="indigo-lighten-4" v-if="editing">
|
||||
<v-icon class="mr-1">mdi-pencil</v-icon>
|
||||
Editing - Press `enter` to submit. Click anywhere to cancel.</v-chip>
|
||||
<v-chip size="x-small" color="grey-lighten-1" v-else-if="!editing && hovered" variant="text" class="mr-1">
|
||||
<v-icon>mdi-pencil</v-icon>
|
||||
Double-click to edit.</v-chip>
|
||||
|
||||
<!-- generate tts -->
|
||||
<v-chip size="x-small" class="ml-2" label color="secondary" v-if="!editing && hovered && ttsAvailable" variant="outlined" @click="generateTTS(message.id)" :disabled="uxLocked || ttsBusy">
|
||||
<v-icon class="mr-1">mdi-account-voice</v-icon>
|
||||
TTS
|
||||
<v-progress-circular v-if="ttsBusy" class="ml-2" size="14" indeterminate="disable-shrink"
|
||||
color="secondary"></v-progress-circular>
|
||||
</v-chip>
|
||||
<MessageToolbar
|
||||
:message-id="message.id"
|
||||
:editing="editing"
|
||||
:ux-locked="uxLocked"
|
||||
:tts-available="ttsAvailable"
|
||||
:tts-busy="ttsBusy"
|
||||
:show-pin="false"
|
||||
:show-revision="false"
|
||||
:show-fork="false"
|
||||
:show-time-passage="false"
|
||||
/>
|
||||
</v-sheet>
|
||||
<div v-else style="height:24px">
|
||||
|
||||
@@ -77,12 +74,14 @@ import { isPrimaryModifier } from '@/utils/keyboardModifiers';
|
||||
import MessageAssetImage from './MessageAssetImage.vue';
|
||||
import MessageAssetMixin from './MessageAssetMixin.js';
|
||||
import RevisionNav from './RevisionNav.vue';
|
||||
import MessageToolbar from './MessageToolbar.vue';
|
||||
|
||||
export default {
|
||||
name: 'ContextInvestigationMessage',
|
||||
components: {
|
||||
MessageAssetImage,
|
||||
RevisionNav,
|
||||
MessageToolbar,
|
||||
},
|
||||
mixins: [MessageAssetMixin],
|
||||
data() {
|
||||
@@ -188,7 +187,7 @@ export default {
|
||||
},
|
||||
},
|
||||
emits: ['navigate-revision'],
|
||||
inject: ['requestDeleteMessage', 'getWebsocket', 'createPin', 'autocompleteRequest', 'autocompleteInfoMessage', 'getMessageStyle', 'getMessageColor', 'generateTTS'],
|
||||
inject: ['requestDeleteMessage', 'getWebsocket', 'autocompleteRequest', 'autocompleteInfoMessage', 'getMessageStyle', 'getMessageColor'],
|
||||
methods: {
|
||||
toggle() {
|
||||
if (!this.editing) {
|
||||
|
||||
134
talemate_frontend/src/components/MessageToolbar.vue
Normal file
134
talemate_frontend/src/components/MessageToolbar.vue
Normal file
@@ -0,0 +1,134 @@
|
||||
<template>
|
||||
<!-- editing indicator -->
|
||||
<v-chip size="x-small" color="indigo-lighten-4" v-if="editing">
|
||||
<v-icon class="mr-1">mdi-pencil</v-icon>
|
||||
Editing - Press `enter` to submit. Click anywhere to cancel.
|
||||
</v-chip>
|
||||
|
||||
<template v-else>
|
||||
<!-- edit hint -->
|
||||
<v-chip size="x-small" color="grey-lighten-1" variant="text" class="mr-1">
|
||||
<v-icon>mdi-pencil</v-icon>
|
||||
Double-click to edit.
|
||||
</v-chip>
|
||||
|
||||
<!-- create pin -->
|
||||
<v-chip v-if="showPin" size="x-small" class="ml-2" label color="success" variant="outlined" @click="createPin(messageId)" :disabled="uxLocked">
|
||||
<v-icon class="mr-1">mdi-pin</v-icon>
|
||||
Create Pin
|
||||
</v-chip>
|
||||
|
||||
<!-- revision -->
|
||||
<v-chip v-if="showRevision && editorRevisionsEnabled && isLastMessage" size="x-small" class="ml-2" label color="dirty" variant="outlined" @click="reviseMessage(messageId)" :disabled="uxLocked">
|
||||
<v-icon class="mr-1">mdi-typewriter</v-icon>
|
||||
Editor Revision
|
||||
</v-chip>
|
||||
|
||||
<!-- fork scene -->
|
||||
<v-chip v-if="showFork && forkable" size="x-small" class="ml-2" label :color="rev > 0 ? 'highlight1' : 'muted'" variant="outlined" @click="forkSceneInitiate(messageId)" :disabled="uxLocked">
|
||||
<v-icon class="mr-1">mdi-source-fork</v-icon>
|
||||
Fork
|
||||
</v-chip>
|
||||
|
||||
<!-- type-specific actions (e.g. Continue) -->
|
||||
<slot name="extra-actions" />
|
||||
|
||||
<!-- generate tts -->
|
||||
<v-chip v-if="showTts && ttsAvailable" size="x-small" class="ml-2" label color="secondary" variant="outlined" @click="generateTTS(messageId)" :disabled="uxLocked || ttsBusy">
|
||||
<v-icon class="mr-1">mdi-account-voice</v-icon>
|
||||
TTS
|
||||
<v-progress-circular v-if="ttsBusy" class="ml-2" size="14" indeterminate="disable-shrink" color="secondary"></v-progress-circular>
|
||||
</v-chip>
|
||||
|
||||
<!-- insert time passage -->
|
||||
<v-chip v-if="showTimePassage" size="x-small" class="ml-2" label color="time" variant="outlined" @click="insertTimePassage(messageId)" :disabled="uxLocked">
|
||||
<v-icon class="mr-1">mdi-clock-plus-outline</v-icon>
|
||||
Time Passage
|
||||
</v-chip>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Shared hover toolbar for scene message components (CharacterMessage,
|
||||
// NarratorMessage, ContextInvestigationMessage, ...). Action handlers are
|
||||
// pulled from the provide/inject tree exposed by SceneMessages.vue, so the
|
||||
// only wiring a consumer needs is state props + which actions to show.
|
||||
export default {
|
||||
name: 'MessageToolbar',
|
||||
// Renders a fragment (multiple sibling chips) — consumers must wrap it
|
||||
// (e.g. in a <v-sheet>); inheritAttrs is off so stray attrs don't warn.
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
// id passed to the action handlers
|
||||
messageId: {
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
},
|
||||
editing: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
uxLocked: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isLastMessage: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
editorRevisionsEnabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
ttsAvailable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
ttsBusy: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
rev: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
sceneRev: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
// action toggles
|
||||
showPin: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showRevision: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showFork: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showTts: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showTimePassage: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
inject: [
|
||||
'createPin',
|
||||
'reviseMessage',
|
||||
'forkSceneInitiate',
|
||||
'generateTTS',
|
||||
'insertTimePassage',
|
||||
],
|
||||
computed: {
|
||||
forkable() {
|
||||
return this.rev <= this.sceneRev;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -49,45 +49,17 @@
|
||||
</div>
|
||||
<v-sheet v-if="hovered" rounded="sm" color="transparent">
|
||||
<div v-if="message_id">
|
||||
<v-chip size="x-small" color="indigo-lighten-4" v-if="editing">
|
||||
<v-icon class="mr-1">mdi-pencil</v-icon>
|
||||
Editing - Press `enter` to submit. Click anywhere to cancel.</v-chip>
|
||||
<v-chip size="x-small" color="grey-lighten-1" v-else-if="!editing && hovered" variant="text" class="mr-1">
|
||||
<v-icon>mdi-pencil</v-icon>
|
||||
Double-click to edit.</v-chip>
|
||||
<v-chip size="x-small" label color="success" v-if="!editing && hovered" variant="outlined"
|
||||
@click="createPin(message_id)">
|
||||
<v-icon class="mr-1">mdi-pin</v-icon>
|
||||
Create Pin
|
||||
</v-chip>
|
||||
|
||||
<!-- revision -->
|
||||
<v-chip size="x-small" class="ml-2" label color="dirty" v-if="!editing && hovered && editorRevisionsEnabled && isLastMessage" variant="outlined" @click="reviseMessage(message_id)" :disabled="uxLocked">
|
||||
<v-icon class="mr-1">mdi-typewriter</v-icon>
|
||||
Editor Revision
|
||||
</v-chip>
|
||||
|
||||
<!-- fork scene -->
|
||||
<v-chip size="x-small" class="ml-2" label :color="rev > 0 ? 'highlight1' : 'muted'" v-if="!editing && hovered && forkable" variant="outlined"
|
||||
@click="forkSceneInitiate(message_id)" :disabled="uxLocked">
|
||||
<v-icon class="mr-1">mdi-source-fork</v-icon>
|
||||
Fork
|
||||
</v-chip>
|
||||
|
||||
<!-- generate tts -->
|
||||
<v-chip size="x-small" class="ml-2" label color="secondary" v-if="!editing && hovered && ttsAvailable" variant="outlined" @click="generateTTS(message_id)" :disabled="uxLocked || ttsBusy">
|
||||
<v-icon class="mr-1">mdi-account-voice</v-icon>
|
||||
TTS
|
||||
<v-progress-circular v-if="ttsBusy" class="ml-2" size="14" indeterminate="disable-shrink"
|
||||
color="secondary"></v-progress-circular>
|
||||
</v-chip>
|
||||
|
||||
<!-- insert time passage -->
|
||||
<v-chip size="x-small" class="ml-2" label color="time" v-if="!editing && hovered" variant="outlined" @click="insertTimePassage(message_id)" :disabled="uxLocked">
|
||||
<v-icon class="mr-1">mdi-clock-plus-outline</v-icon>
|
||||
Time Passage
|
||||
</v-chip>
|
||||
|
||||
<MessageToolbar
|
||||
:message-id="message_id"
|
||||
:editing="editing"
|
||||
:ux-locked="uxLocked"
|
||||
:is-last-message="isLastMessage"
|
||||
:editor-revisions-enabled="editorRevisionsEnabled"
|
||||
:tts-available="ttsAvailable"
|
||||
:tts-busy="ttsBusy"
|
||||
:rev="rev"
|
||||
:scene-rev="sceneRev"
|
||||
/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<span class="text-muted text-caption">To edit the intro message open the <v-btn size="x-small" variant="text" color="primary" @click="openWorldStateManager('scene')"><v-icon>mdi-script</v-icon>Scene Editor</v-btn></span>
|
||||
@@ -113,13 +85,14 @@ import { isPrimaryModifier } from '@/utils/keyboardModifiers';
|
||||
import MessageAssetImage from './MessageAssetImage.vue';
|
||||
import MessageAssetMixin from './MessageAssetMixin.js';
|
||||
import RevisionNav from './RevisionNav.vue';
|
||||
import MessageToolbar from './MessageToolbar.vue';
|
||||
export default {
|
||||
components: {
|
||||
MessageAssetImage,
|
||||
RevisionNav,
|
||||
MessageToolbar,
|
||||
},
|
||||
mixins: [MessageAssetMixin],
|
||||
// props: ['text', 'message_id', 'uxLocked', 'isLastMessage'],
|
||||
|
||||
props: {
|
||||
text: {
|
||||
@@ -188,17 +161,13 @@ export default {
|
||||
},
|
||||
emits: ['navigate-revision'],
|
||||
inject: [
|
||||
'requestDeleteMessage',
|
||||
'getWebsocket',
|
||||
'createPin',
|
||||
'forkSceneInitiate',
|
||||
'autocompleteRequest',
|
||||
'autocompleteInfoMessage',
|
||||
'getMessageStyle',
|
||||
'requestDeleteMessage',
|
||||
'getWebsocket',
|
||||
'autocompleteRequest',
|
||||
'autocompleteInfoMessage',
|
||||
'getMessageStyle',
|
||||
'openWorldStateManager',
|
||||
'reviseMessage',
|
||||
'generateTTS',
|
||||
'insertTimePassage',
|
||||
],
|
||||
computed: {
|
||||
parser() {
|
||||
@@ -217,9 +186,6 @@ export default {
|
||||
renderedText() {
|
||||
return this.parser.parse(this.text);
|
||||
},
|
||||
forkable() {
|
||||
return this.rev <= this.sceneRev;
|
||||
},
|
||||
// Asset mixin expects these
|
||||
assetId() {
|
||||
return this.asset_id;
|
||||
|
||||
Reference in New Issue
Block a user