diff --git a/talemate_frontend/src/components/WorldStateManagerWorldEntries.vue b/talemate_frontend/src/components/WorldStateManagerWorldEntries.vue index 067caebf..f5ca5955 100644 --- a/talemate_frontend/src/components/WorldStateManagerWorldEntries.vue +++ b/talemate_frontend/src/components/WorldStateManagerWorldEntries.vue @@ -1,6 +1,6 @@ @@ -85,12 +95,15 @@ import ContextualGenerate from './ContextualGenerate.vue'; import ConfirmActionInline from './ConfirmActionInline.vue'; +import AutocompleteRedoChip from './AutocompleteRedoChip.vue'; +import { createAutocompleteField } from '@/utils/autocompleteField'; export default { name: 'WorldStateManagerWorldEntries', components: { ContextualGenerate, ConfirmActionInline, + AutocompleteRedoChip, }, props: { pins: Object, @@ -113,6 +126,8 @@ export default { timeout: null, entry: null, dirty: false, + worldInfoBusy: false, + worldInfoAutocompleteField: null, formValid: false, rules: [ v => !!v || 'Entry ID is required', @@ -138,6 +153,8 @@ export default { 'loadContextDBEntry', 'registerMessageHandler', 'unregisterMessageHandler', + 'autocompleteInfoMessage', + 'autocompleteRequest', ], watch: { immutableEntries: { @@ -153,6 +170,27 @@ export default { }); } }, + 'entry.text'() { + this.worldInfoAutocompleteField?.onValueChange(); + }, + }, + created() { + this.worldInfoAutocompleteField = createAutocompleteField({ + autocompleteRequest: this.autocompleteRequest, + getValue: () => this.entry?.text || '', + setValue: (v) => { + if (!this.entry) return; + this.entry.text = v; + // Programmatic writes bypass @update:model-value; flag dirty so the completion persists. + this.dirty = true; + }, + buildParams: () => ({ + partial: this.entry.text, + context: `world context:${this.entry.id}`, + }), + onStart: () => { this.worldInfoBusy = true; }, + onEnd: () => { this.worldInfoBusy = false; }, + }); }, methods: { queueSave(delay = 1500) { @@ -245,12 +283,20 @@ export default { }); }, handleBlur() { + // Guard: blur during autocomplete would save the un-stripped {hint}. + if (this.worldInfoBusy) { + return; + } // Only auto-save on blur for existing entries, not new ones if (!this.isNewEntry) { this.save(true); } }, + sendWorldInfoAutocomplete() { + this.worldInfoAutocompleteField.request(this.$refs.textInput); + }, + handleMessage(message) { if (message.type !== 'world_state_manager') { return;