Add unified per-speaker font support and remote transcription service

Font changes:
- Consolidate font settings into single Display Settings section
- Support Web-Safe, Google Fonts, and Custom File uploads for both displays
- Fix Google Fonts URL encoding (use + instead of %2B for spaces)
- Fix per-speaker font inline style quote escaping in Node.js display
- Add font debug logging to help diagnose font issues
- Update web server to sync all font settings on settings change
- Remove deprecated PHP server documentation files

New features:
- Add remote transcription service for GPU offloading
- Add instance lock to prevent multiple app instances
- Add version tracking

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-11 18:56:12 -08:00
parent f035bdb927
commit ff067b3368
23 changed files with 2486 additions and 1160 deletions

View File

@@ -19,6 +19,10 @@ class Config:
self.app_dir = Path.home() / ".local-transcription"
self.app_dir.mkdir(parents=True, exist_ok=True)
# Fonts directory for custom font files
self.fonts_dir = self.app_dir / "fonts"
self.fonts_dir.mkdir(parents=True, exist_ok=True)
if config_path is None:
self.config_path = self.app_dir / "config.yaml"
else:
@@ -34,7 +38,7 @@ class Config:
self.config = yaml.safe_load(f) or {}
else:
# Load default configuration
default_config_path = Path(__file__).parent.parent / "config" / "default_config.yaml"
default_config_path = Path(__file__).resolve().parent.parent / "config" / "default_config.yaml"
if default_config_path.exists():
with open(default_config_path, 'r') as f:
self.config = yaml.safe_load(f) or {}
@@ -137,5 +141,24 @@ class Config:
self.config = self._get_default_config()
self.save()
def get_custom_fonts(self) -> list:
"""
Get list of custom font files in the fonts directory.
Returns:
List of (font_name, font_path) tuples
"""
fonts = []
font_extensions = {'.ttf', '.otf', '.woff', '.woff2'}
if self.fonts_dir.exists():
for font_file in self.fonts_dir.iterdir():
if font_file.suffix.lower() in font_extensions:
# Use filename without extension as font name
font_name = font_file.stem
fonts.append((font_name, font_file))
return sorted(fonts, key=lambda x: x[0].lower())
def __repr__(self) -> str:
return f"Config(path={self.config_path})"