Files
DemonGatanjieu-Anomalous_Mo…/web/modules/ui_domain_switcher.js
T
DemonGatanjieuandClaude Opus 5.5 66979f698a fix(audio): align voices with ComfyUI-F5-TTS multi-voice layout and repair studio UI
ComfyUI-F5-TTS resolves {happy} to <sample stem>.happy.wav beside the selected
sample, so `Arona_happy.wav` + `{Arona_happy}` could never run. Voices now use
Character.wav (main, {main}) and Character.<emotion>.wav ({emotion}); the
catalog groups a main voice with its variants and marks tags that F5-TTS
cannot resolve (missing main, missing .txt, different format).

- script director: one character per script, untagged lines pinned to {main},
  pushes sample (main voice, node's own combo spelling) and speech together,
  confirms before overwriting and re-checks the node after the dialog
- pure rules (splitting, composing, planning, combo spelling) in audio_script.js
- one module instance per file: drop ?v= imports that duplicated
  ui_audio_gallery/ui_audio_studio state, so studio playback stops the gallery
- all user/file-derived text goes through textContent (no innerHTML)
- studio/sidebar/gallery renders ignore stale responses; errors are shown
- gallery: count badge no longer overwrites the title, paging via "load more",
  deletion errors surfaced, timeupdate instead of a 100ms timer
- sidebar: filter selection updates in place instead of refetching; the header
  tabs, sidebar and domain switch share browser.switchAudioTab
- uploader: createViewScope lifecycle (Esc/overlay/close release listeners and
  object URLs, Esc no longer reaches the parent), 409 -> confirm -> overwrite,
  sends the pre-romanization text as original_text, no hard-coded character
- workflow template: confirm before replacing the canvas, clear message when
  the template file is missing, align sample paths to the node's combo values
- static styles moved from inline JS into 11-audio-studio.css; strings localized

Verified: tests/audio_script_rules.mjs, tests/test_audio_catalog.py (15), a
jsdom walkthrough of studio/gallery/director/uploader with a stubbed app
(outside the repo), JS syntax and import/export link check. Not yet checked in
a live ComfyUI session.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W411Z69FC3em9CzpeqEub5
2026-09-23 08:02:33 +00:00

62 lines
2.7 KiB
JavaScript

import { t } from './interface_settings.js';
/**
* Domain Switcher component (Visual Studio <-> Audio & Voice Studio)
* Ultra-compact 26x26px icon button matching Anomalous Browser shell standards.
*/
const STORAGE_KEY = 'anomalous_active_domain';
const SVG_ICONS = {
// Elegant waveform / microphone for audio mode
AUDIO: `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="22"/></svg>`,
// Elegant palette / grid for visual mode
VISUAL: `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="13.5" cy="6.5" r=".5" fill="currentColor"/><circle cx="17.5" cy="10.5" r=".5" fill="currentColor"/><circle cx="8.5" cy="7.5" r=".5" fill="currentColor"/><circle cx="6.5" cy="12.5" r=".5" fill="currentColor"/><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688 0-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 0 1 1.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.012 17.461 2 12 2z"/></svg>`
};
export function getActiveDomain() {
try {
return localStorage.getItem(STORAGE_KEY) === 'audio' ? 'audio' : 'visual';
} catch (_) {
return 'visual';
}
}
export function setActiveDomain(domain) {
try {
localStorage.setItem(STORAGE_KEY, domain === 'audio' ? 'audio' : 'visual');
} catch (_) {
// Private windows may refuse storage; the switch still applies to this page.
}
}
export function createDomainSwitcher(browser) {
const container = document.createElement('div');
container.id = 'anomalous-domain-switcher';
const toggleBtn = document.createElement('button');
toggleBtn.className = 'anomalous-domain-toggle-btn';
toggleBtn.type = 'button';
function updateButtonState(domain) {
const isAudio = domain === 'audio';
toggleBtn.innerHTML = isAudio ? SVG_ICONS.AUDIO : SVG_ICONS.VISUAL;
toggleBtn.title = t(isAudio ? 'domainSwitchToVisual' : 'domainSwitchToAudio');
toggleBtn.setAttribute('aria-label', toggleBtn.title);
toggleBtn.classList.toggle('is-audio', isAudio);
}
updateButtonState(getActiveDomain());
toggleBtn.addEventListener('click', (e) => {
e.stopPropagation();
const nextDomain = getActiveDomain() === 'visual' ? 'audio' : 'visual';
setActiveDomain(nextDomain);
updateButtonState(nextDomain);
browser.handleDomainChange?.(nextDomain);
});
container.appendChild(toggleBtn);
return container;
}