diff options
Diffstat (limited to 'ui')
| -rw-r--r-- | ui/config-schema.js | 49 | ||||
| -rw-r--r-- | ui/index.html | 52 | ||||
| -rw-r--r-- | ui/index.js | 49 | ||||
| -rw-r--r-- | ui/renderer.js | 31 |
4 files changed, 125 insertions, 56 deletions
diff --git a/ui/config-schema.js b/ui/config-schema.js new file mode 100644 index 0000000..b1108ff --- /dev/null +++ b/ui/config-schema.js @@ -0,0 +1,49 @@ +// Shared configuration schema with types and defaults +const CONFIG_SCHEMA = { + // String fields + compute_type: { type: 'select', default: 'float16' }, + language: { type: 'select', default: 'english' }, + model: { type: 'select', default: 'turbo' }, + microphone: { type: 'number', default: 0 }, + user_prompt: { type: 'text', default: 'Use proper punctuation and grammar. Prefer spelled out numbers like one, eleven, twenty, etc. Mm.' }, + + // Number fields + gpu_idx: { type: 'number', default: 0 }, + max_speech_duration_s: { type: 'number', default: 10 }, + min_silence_duration_ms: { type: 'number', default: 250 }, + reset_after_silence_s: { type: 'number', default: 15 }, + transcription_loop_delay_ms: { type: 'number', default: 100 }, + block_width: { type: 'number', default: 2 }, + num_blocks: { type: 'number', default: 40 }, + rows: { type: 'number', default: 10 }, + cols: { type: 'number', default: 24 }, + beam_size: { type: 'number', default: 5 }, + best_of: { type: 'number', default: 5 }, + + // Boolean fields (stored as 1/0) + enable_debug_mode: { type: 'boolean', default: 0 }, + enable_previews: { type: 'boolean', default: 1 }, + save_audio: { type: 'boolean', default: 0 }, + use_cpu: { type: 'boolean', default: 0 }, + enable_lowercase_filter: { type: 'boolean', default: 0 }, + enable_uppercase_filter: { type: 'boolean', default: 0 }, + enable_profanity_filter: { type: 'boolean', default: 0 }, + remove_trailing_period: { type: 'boolean', default: 0 } +}; + +// Helper to extract just the default values +function getDefaultConfig() { + const defaults = {}; + for (const [key, schema] of Object.entries(CONFIG_SCHEMA)) { + defaults[key] = schema.default; + } + return defaults; +} + +// Export for both CommonJS (main process) and ES modules (renderer) +if (typeof module !== 'undefined' && module.exports) { + module.exports = { CONFIG_SCHEMA, getDefaultConfig }; +} else { + window.CONFIG_SCHEMA = CONFIG_SCHEMA; + window.getDefaultConfig = getDefaultConfig; +}
\ No newline at end of file diff --git a/ui/index.html b/ui/index.html index 90f78c1..97da3d2 100644 --- a/ui/index.html +++ b/ui/index.html @@ -10,9 +10,9 @@ <div class="container-fluid px-6 py-6 h-screen flex flex-col"> <div class="flex flex-1 gap-6 overflow-hidden"> <!-- Left Panel: Configuration Form --> - <div class="max-w-96 relative flex flex-col"> + <div class="max-w-96 relative flex flex-col overflow-hidden rounded-lg"> <!-- Loading Overlay --> - <div id="loading-overlay" class="absolute inset-0 bg-white bg-opacity-75 backdrop-blur-sm z-50 hidden flex items-center justify-center rounded-lg"> + <div id="loading-overlay" class="absolute inset-0 bg-white bg-opacity-75 backdrop-blur-sm z-50 hidden flex items-center justify-center"> <div class="text-center p-6"> <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"></div> <p class="text-gray-700 font-medium"></p> @@ -126,7 +126,7 @@ <h2 class="section-title">Transcription Settings</h2> <div> <label for="user_prompt" class="form-label"> - Custom Prompt + Prompt <span class="text-gray-500 text-xs block mt-1" title="Whisper is given this prompt before transcribing. It helps guide the transcription style. For example, you could improve the spelling of your friends' names with: 'My friends' names are Saoirse, Azariah, and Caoimhe.'"> (Hover for details) @@ -136,6 +136,28 @@ class="form-input h-20 resize-none" placeholder="My friends' names are Saoirse, Azariah, and Caoimhe."></textarea> </div> + <div class="grid grid-cols-2 gap-4 mt-4"> + <div> + <label for="beam_size" class="form-label"> + Beam size + <span class="text-gray-500 text-xs block mt-1" + title="Number of beams for beam search. Higher values may improve accuracy but increase compute time."> + (Search width) + </span> + </label> + <input type="number" id="beam_size" min="1" max="20" value="5" class="form-input"> + </div> + <div> + <label for="best_of" class="form-label"> + Best of + <span class="text-gray-500 text-xs block mt-1" + title="Number of candidates to generate when sampling. The best one will be selected."> + (Sampling candidates) + </span> + </label> + <input type="number" id="best_of" min="1" max="20" value="5" class="form-input"> + </div> + </div> </section> <!-- Performance Settings --> @@ -166,6 +188,29 @@ </div> </section> + <!-- Text Filters --> + <section class="config-section"> + <h2 class="section-title">Text Filters</h2> + <div class="space-y-3"> + <label for="enable_lowercase_filter" class="checkbox-label"> + <input type="checkbox" id="enable_lowercase_filter" class="mr-2"> + <span class="checkbox-text">Convert to lowercase</span> + </label> + <label for="enable_uppercase_filter" class="checkbox-label"> + <input type="checkbox" id="enable_uppercase_filter" class="mr-2"> + <span class="checkbox-text">Convert to uppercase</span> + </label> + <label for="enable_profanity_filter" class="checkbox-label"> + <input type="checkbox" id="enable_profanity_filter" class="mr-2"> + <span class="checkbox-text">Filter profanity</span> + </label> + <label for="remove_trailing_period" class="checkbox-label"> + <input type="checkbox" id="remove_trailing_period" class="mr-2"> + <span class="checkbox-text">Remove trailing period</span> + </label> + </div> + </section> + <!-- Display Settings --> <section class="config-section"> <h2 class="section-title">Custom Chatbox Settings</h2> @@ -240,6 +285,7 @@ </div> </div> + <script src="config-schema.js"></script> <script src="renderer.js"></script> </body> </html> diff --git a/ui/index.js b/ui/index.js index 2420ece..7717c92 100644 --- a/ui/index.js +++ b/ui/index.js @@ -4,6 +4,7 @@ const fs = require('node:fs').promises; const yaml = require('js-yaml'); const { spawn } = require('child_process'); const https = require('https'); +const { CONFIG_SCHEMA, getDefaultConfig } = require('./config-schema.js'); const APP_ROOT = path.join(__dirname, '..'); const CONFIG_PATH = path.join(APP_ROOT, 'config.yaml'); @@ -82,6 +83,14 @@ function downloadFile(url, outputPath) { }); } +function shouldFilterMessage(message) { + // Filter out pydub ffmpeg/avconv warning. It does not actually matter. + if (message.includes("Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work")) { + return true; + } + return false; +} + // Helper function to setup process event handlers function setupProcessHandlers(process) { process.stdout.on('data', (data) => { @@ -91,7 +100,9 @@ function setupProcessHandlers(process) { process.stderr.on('data', (data) => { const text = data.toString(); - sendPythonOutput(text.trimEnd(), 'stderr'); + if (!shouldFilterMessage(text)) { + sendPythonOutput(text.trimEnd(), 'stderr'); + } }); process.on('error', (error) => { @@ -137,7 +148,10 @@ function executePythonCommand(args, options = {}) { pythonProcess.stderr.on('data', (data) => { const text = data.toString(); stderr += text; - sendPythonOutput(text.trimEnd(), 'stderr'); + // Filter out specific warning messages + if (!shouldFilterMessage(text)) { + sendPythonOutput(text.trimEnd(), 'stderr'); + } }); pythonProcess.on('error', (error) => { @@ -171,27 +185,8 @@ function createWindow () { mainWindow.loadFile('index.html'); } -// Default configuration based on user's current config.yaml -const DEFAULT_CONFIG = { - compute_type: 'float16', - enable_debug_mode: 0, - enable_previews: 1, - user_prompt: 'Use proper punctuation and grammar. Prefer spelled out numbers like one, eleven, twenty, etc.', - save_audio: 0, - language: 'english', - gpu_idx: 0, - max_speech_duration_s: 10, - min_silence_duration_ms: 250, - microphone: 0, - model: 'turbo', - reset_after_silence_s: 15, - transcription_loop_delay_ms: 100, - use_cpu: 0, - block_width: 2, - num_blocks: 40, - rows: 10, - cols: 24 -}; +// Replace the DEFAULT_CONFIG constant with: +const DEFAULT_CONFIG = getDefaultConfig(); // IPC handlers ipcMain.handle('load-config', async () => { @@ -521,12 +516,12 @@ ipcMain.handle('start-process', async () => { }); ipcMain.handle('stop-process', async () => { - if (!runningProcess) { - throw new Error('No process is running'); - } - return new Promise((resolve) => { let forcefullyKilled = false; + + if (!runningProcess) { + resolve({ success: true, forcefullyKilled }); + } // Set up a timeout to force kill after 10 seconds const killTimeout = setTimeout(() => { diff --git a/ui/renderer.js b/ui/renderer.js index 201eef6..133a79b 100644 --- a/ui/renderer.js +++ b/ui/renderer.js @@ -1,29 +1,5 @@ -// Configuration and form field mappings -const CONFIG_FIELDS = { - // String fields - compute_type: { type: 'select', default: 'float16' }, - language: { type: 'select', default: 'english' }, - model: { type: 'select', default: 'turbo' }, - microphone: { type: 'number', default: 0 }, - user_prompt: { type: 'text', default: '' }, - - // Number fields - gpu_idx: { type: 'number', default: 0 }, - max_speech_duration_s: { type: 'number', default: 10 }, - min_silence_duration_ms: { type: 'number', default: 250 }, - reset_after_silence_s: { type: 'number', default: 15 }, - transcription_loop_delay_ms: { type: 'number', default: 100 }, - block_width: { type: 'number', default: 2 }, - num_blocks: { type: 'number', default: 40 }, - rows: { type: 'number', default: 10 }, - cols: { type: 'number', default: 24 }, - - // Boolean fields (stored as 1/0) - enable_debug_mode: { type: 'boolean', default: 0 }, - enable_previews: { type: 'boolean', default: 1 }, - save_audio: { type: 'boolean', default: 0 }, - use_cpu: { type: 'boolean', default: 0 } -}; +// Import configuration schema +const CONFIG_FIELDS = window.CONFIG_SCHEMA; // Button management system class ButtonManager { @@ -35,6 +11,9 @@ class ButtonManager { resetVenv: document.getElementById('reset-venv'), refreshMicrophones: document.getElementById('refresh-microphones') }; + + // Initialize button states on construction + this.setProcessStopped(); } setState(buttonName, disabled) { |
