Edit emotions: list every clip, and let the line follow the clip
The audio boxes are a native datalist, which lists only files whose names contain the box's text, so a filled box showed one or two clips. Pressing a box now empties it to list all of them (the file shows as the placeholder) and puts the file back when nothing is picked; Backspace or Delete really clears it. Picking another clip kept the old clip's line next to it. The line box now follows: the line it had for the first clip, the line the node already reads for a clip in use, or blank, which makes the node read the clip's own .txt / .lab / list line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
bd9afedb68
commit
a3ee55dfd2
@@ -24,6 +24,9 @@
|
||||
- The settings page is split into tabs: **Look, Models, Workflows, Prompts, Backup, Help**. "Change where downloads go" opens Models directly.
|
||||
- **Where downloads (and now imports) go is a choice**: by base model (the new default), in Downloads then by base model, all in a Downloads folder, straight in the type's folder, or your own folder typed by hand; an example path shows the result. Without a saved setting, downloads now go by base model instead of into a Downloads folder.
|
||||
|
||||
### Fixes
|
||||
- **Edit emotions: every clip in the list, and the line follows the clip (编辑情绪:下拉列出全部音频,换音频台词跟着换)**: a box that already held a file listed only the files whose names contain it (the browser filters by the box's text), so a character's other clips seemed missing. Pressing the box now lists all of them, with the current file shown greyed; leaving without a pick keeps it. Picking another clip no longer keeps the old clip's line beside it: the line the node already reads for that clip is filled in, otherwise the box is left blank and the node reads the clip's own line (its .txt / .lab or the annotation list) when it speaks; going back to the first clip brings its line back.
|
||||
|
||||
## v1.59.0 Beta (Model Downloads, Backup, Share Codes, Node Combos, MCP, Light Theme) — unreleased
|
||||
|
||||
### ⬇️ Download missing models from Model Check (模型检查一键下载缺失模型)
|
||||
|
||||
@@ -39,6 +39,24 @@ function audioInput(listId, value) {
|
||||
input.setAttribute('list', listId);
|
||||
input.placeholder = t('ttsEditorAudioPlaceholder');
|
||||
input.value = value || '';
|
||||
// The browser lists only the files matching the box's text, so a filled box offered one or
|
||||
// two. Pressing it empties the box to list them all (the file shows greyed meanwhile);
|
||||
// leaving without a pick puts the file back, unless it was deleted with a key.
|
||||
let kept = '';
|
||||
input.addEventListener('mousedown', () => {
|
||||
if (!input.value) return;
|
||||
kept = input.value;
|
||||
input.placeholder = kept;
|
||||
input.value = '';
|
||||
});
|
||||
input.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Backspace' || e.key === 'Delete') kept = '';
|
||||
});
|
||||
input.addEventListener('blur', () => {
|
||||
if (!input.value) input.value = kept;
|
||||
kept = '';
|
||||
input.placeholder = t('ttsEditorAudioPlaceholder');
|
||||
});
|
||||
return input;
|
||||
}
|
||||
|
||||
@@ -82,6 +100,19 @@ export function openGptSovitsEditor(group, { onSaved } = {}) {
|
||||
close();
|
||||
}, true);
|
||||
|
||||
// A picked file gets its own line: the one it had in this dialog, the line the node read for it
|
||||
// when it is in use already, or blank, which the node fills from the file's .txt / .lab / list.
|
||||
const knownText = new Map([raw.reference, ...Object.values(raw.emotions || {})]
|
||||
.filter(ref => ref?.audio && ref.text).map(ref => [ref.audio, ref.text]));
|
||||
const linkText = (audio, text) => {
|
||||
const start = { audio: audio.value.trim(), text: text.value };
|
||||
audio.addEventListener('input', () => {
|
||||
const path = audio.value.trim();
|
||||
if (!audioList.includes(path)) return;
|
||||
text.value = path === start.audio ? start.text : knownText.get(path) || '';
|
||||
});
|
||||
};
|
||||
|
||||
const play = (input) => {
|
||||
player?.pause();
|
||||
const path = input.value.trim();
|
||||
@@ -107,6 +138,7 @@ export function openGptSovitsEditor(group, { onSaved } = {}) {
|
||||
const mainRow = el('div', 'anomalous-tts-row is-main');
|
||||
const mainAudio = audioInput(listId, settings.reference?.audio);
|
||||
const mainText = textInput(settings.reference?.text);
|
||||
linkText(mainAudio, mainText);
|
||||
mainRow.append(
|
||||
el('span', 'anomalous-tts-row-name', '{main}'),
|
||||
mainAudio,
|
||||
@@ -127,6 +159,7 @@ export function openGptSovitsEditor(group, { onSaved } = {}) {
|
||||
nameInput.value = row.name || '';
|
||||
const audio = audioInput(listId, row.audio);
|
||||
const text = textInput(row.text);
|
||||
linkText(audio, text);
|
||||
line.append(
|
||||
nameInput,
|
||||
audio,
|
||||
|
||||
Reference in New Issue
Block a user