From 1b5dc18124ad6b3ee2cdb35f04157a0bde958990 Mon Sep 17 00:00:00 2001 From: TechTide AI Date: Thu, 21 May 2026 18:42:21 -0400 Subject: [PATCH] refactor: extract hardcoded config from AppShell template Move TTS provider definitions, accepted upload file types, and canvas iframe sandbox permissions into a dedicated constants module (src/core/constants.js). AppShell now interpolates these values at runtime instead of embedding them in the HTML string. Adding a new TTS provider now requires editing only one file instead of searching through the template markup. Addresses #234. --- src/core/constants.js | 49 +++++++++++++++++++++++++++++++++++++++++++ src/ui/AppShell.js | 23 +++++++++++++------- 2 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 src/core/constants.js diff --git a/src/core/constants.js b/src/core/constants.js new file mode 100644 index 0000000..58b58d3 --- /dev/null +++ b/src/core/constants.js @@ -0,0 +1,49 @@ +/** + * constants — Centralized configuration constants + * + * Extracted from AppShell.js to avoid hardcoding provider lists + * and accepted file types directly in HTML templates. + * + * Add new TTS providers here — the settings UI will reflect them + * automatically without touching the shell template. + */ + +/** + * TTS provider options shown in the settings dropdown. + * @type {Array<{id: string, label: string}>} + */ +export const TTS_PROVIDERS = [ + { id: 'supertonic', label: 'Supertonic (Free)' }, + { id: 'groq', label: 'Groq Orpheus' }, + { id: 'hume', label: 'Hume EVI' }, +]; + +/** + * Accepted file types for the transcript panel upload input. + * Includes documents, images, code, and 3D model formats. + * @type {string} + */ +export const TRANSCRIPT_UPLOAD_ACCEPT = [ + 'image/*', + '.pdf', '.docx', '.xlsx', '.pptx', + '.txt', '.md', '.json', '.csv', + '.html', '.js', '.py', '.ts', '.css', + '.glb', '.gltf', '.obj', '.fbx', '.stl', + '.3ds', '.dae', '.ply', '.usdz', '.blend', + '.mtl', '.hdr', '.exr', +].join(','); + +/** + * Sandbox permissions for the canvas iframe. + * @type {string} + */ +export const CANVAS_SANDBOX_PERMISSIONS = [ + 'allow-same-origin', + 'allow-scripts', + 'allow-popups', + 'allow-popups-to-escape-sandbox', + 'allow-forms', + 'allow-top-navigation-by-user-activation', + 'allow-downloads', + 'allow-pointer-lock', +].join(' '); diff --git a/src/ui/AppShell.js b/src/ui/AppShell.js index 01f67a5..034edaf 100644 --- a/src/ui/AppShell.js +++ b/src/ui/AppShell.js @@ -8,15 +8,25 @@ * import { inject } from './ui/AppShell.js'; * inject(); // must be first, before DOM queries */ +import { TTS_PROVIDERS, TRANSCRIPT_UPLOAD_ACCEPT, CANVAS_SANDBOX_PERMISSIONS } from '../core/constants.js'; + export function inject() { - document.body.insertAdjacentHTML('afterbegin', SHELL_HTML); + document.body.insertAdjacentHTML('afterbegin', buildShellHTML()); // Activity chip style — light grey on dark grey, no backdrop-filter const chipStyle = document.createElement('style'); chipStyle.textContent = `.agent-activity-chip{background:var(--bg-elevated)!important;border:1px solid rgba(180,190,210,0.3)!important;color:var(--text-primary)!important;backdrop-filter:none!important;box-shadow:0 2px 12px rgba(0,0,0,0.6),inset 0 1px 0 rgba(255,255,255,0.07)!important;overflow:hidden!important;}`; document.head.appendChild(chipStyle); } -const SHELL_HTML = ` +/** Build TTS provider ` + ).join('\n '); +} + +function buildShellHTML() { +return ` @@ -63,7 +73,7 @@ const SHELL_HTML = ` id="canvas-iframe" src="about:blank" data-canvas-src="" - sandbox="allow-same-origin allow-scripts allow-popups allow-popups-to-escape-sandbox allow-forms allow-top-navigation-by-user-activation allow-downloads allow-pointer-lock" + sandbox="${CANVAS_SANDBOX_PERMISSIONS}" style="width: 100vw; height: 100vh; border: none; display: block; touch-action: manipulation;" allow="autoplay; fullscreen; microphone; camera; pointer-lock"> @@ -108,7 +118,7 @@ const SHELL_HTML = ` `; +}