FILE_STRUCTURE

Project Structure

A summary of how HTML templates, CSS, and JavaScript interact in this project.


Overview

This is a Flask application with a single-page frontend. The server renders one HTML page via Jinja2 templates, loads all CSS globally, and boots a single ES module entry point. All subsequent UI interaction is handled in JavaScript without page reloads. The application also serves several standalone pages (landing, account, presentation, etc.) with their own templates and stylesheets.


File Map

templates/                          Jinja2 HTML templates
├── index.html                      Root app page — loads CSS, loads main.js
├── sidebar.html                    Sidebar partial
├── workspace.html                  Workspace partial
├── start_page.html                 Empty-state page partial
├── landing.html                    Public landing/marketing page
├── account.html                    User account management page
├── admin.html                      Admin panel page
├── donate.html                     Donation page
├── downloads.html                  Downloads page
├── faq.html                        FAQ page
├── license.html                    License page
├── privacy.html                    Privacy policy page
├── terms.html                      Terms of service page
├── changelog.html                  Changelog detail page
├── changelog_index.html            Changelog index page
├── presentation.html               Public presentation view
├── presentation_folder.html        Public presentation folder view
├── components/
│   └── shortcut_legend.html        Keyboard shortcut reference
├── workspace_panels/
│   ├── waveform_panel.html         Audio player and waveform
│   ├── speakers_panel.html         Speaker list and management
│   └── transcript_panel.html       Transcript editor
├── partials/
│   ├── _app_icon_svg.html          App icon SVG include
│   ├── _title_svg.html             Title SVG include
│   ├── _landing_header.html        Landing page header
│   ├── _landing_footer.html        Landing page footer
│   ├── _landing_modals.html        Landing page modals
│   ├── _report_modal.html          Report/abuse modal
│   └── _signup_modal.html          Signup/registration modal
└── documentation/
    ├── index.html                  Documentation index
    └── guide/                      User guide pages (standalone)

static/css/
├── variables.css                   Global CSS custom properties (colors, dark + light theme)
├── main.css                        Base/global styles
├── sidebar.css                     Sidebar layout (includes folder breadcrumb styles)
├── start_page.css                  Empty-state page styles
├── icons.css                       Icon styles
├── landing.css                     Landing page styles
├── account.css                     Account page styles
├── admin.css                       Admin page styles
├── downloads.css                   Downloads page styles
├── faq.css                         FAQ page styles
├── changelog.css                   Changelog page styles
├── presentation.css                Presentation view styles
├── components/
│   ├── context_menu.css            Base context menu styles
│   ├── confirm_dialog.css
│   ├── donate_dialog.css
│   ├── download_modal.css
│   ├── embed_dialog.css
│   ├── export_panel.css
│   ├── hue_picker.css
│   ├── info_widget.css
│   ├── live_quotes_dialog.css
│   ├── login_dialog.css
│   ├── report_modal.css
│   ├── segment_context_menu.css
│   ├── share_dialog.css
│   ├── shortcut_legend.css
│   ├── signup_modal.css
│   ├── split_popup.css
│   ├── transcribe_dialog.css
│   └── tutorial_dialog.css
├── workspace/
│   ├── workspace.css
│   ├── waveform_panel.css
│   ├── speakers_panel.css
│   └── transcript_panel.css
└── documentation/
    └── guide.css

static/js/
├── main.js                         Entry point — App class, sidebar, project list, folder navigation
├── project.js                      Project, ProjectData, Transcript, Speaker classes
├── workspace.js                    Workspace — coordinates the three panels
├── server.js                       Server class — connection state, auth, and all server operations
├── start_page.js                   StartPage class
├── firebase.js                     Firebase auth integration (cloud mode)
├── account.js                      Account page logic
├── admin.js                        Admin page logic
├── donate.js                       Donation page logic
├── presentation.js                 Presentation view logic
├── presentation_folder.js          Presentation folder view logic
├── transcription_manager.js        Transcription state and progress management
├── workspace_panels/
│   ├── waveform_panel.js           WaveformPanel — audio playback, waveform, regions
│   ├── speakers_panel.js           SpeakersPanel — speaker list and editing
│   └── transcript_panel.js         TranscriptPanel — transcript display and editing
├── components/
│   ├── context_menu.js             Base ContextMenu class
│   ├── apply_effect_dialog.js      ApplyEffectDialog — audio effect application
│   ├── confirm_dialog.js           ConfirmDialog — modal confirmation
│   ├── effect_context_menu.js      EffectContextMenu — right-click menu on effects
│   ├── embed_dialog.js             EmbedDialog — quote embed creation
│   ├── export_panel.js             ExportPanel — export format selection and download
│   ├── hue_picker.js               HuePicker — speaker color selection
│   ├── hyperlink_dialog.js         HyperlinkDialog — hyperlink editing in transcript
│   ├── info_widget.js              InfoWidget — toast/notification display
│   ├── link_context_menu.js        LinkContextMenu — right-click menu on links
│   ├── live_quotes_dialog.js       LiveQuotesDialog — live quote embedding feature
│   ├── login_dialog.js             LoginDialog — Firebase login UI
│   ├── project_context_menu.js     ProjectContextMenu — right-click menu on projects
│   ├── section_context_menu.js     SectionContextMenu — right-click menu on sections
│   ├── segment_context_menu.js     SegmentContextMenu — right-click menu on segments
│   ├── selection_context_menu.js   SelectionContextMenu — right-click menu on text selections
│   ├── share_dialog.js             ShareDialog — project sharing
│   ├── speaker_context_menu.js     SpeakerContextMenu — right-click menu on speakers
│   ├── split_popup.js              SplitPopup — word-level segment splitting
│   ├── stale_context_menu.js       StaleContextMenu — stale content resolution
│   ├── tooltip.js                  Tooltip — hover tooltips
│   ├── transcribe_dialog.js        TranscribeDialog — transcription options and progress
│   ├── tutorial_dialog.js          TutorialDialog — onboarding tutorial
│   └── version_history_dialog.js   VersionHistoryDialog — project version history browser
├── utilities/
│   ├── tools.js                    General utility functions
│   ├── audio.js                    Audio loading helpers
│   ├── colors.js                   Color manipulation utilities
│   ├── constants.js                Shared constants (GAP_THRESHOLD, SPEAKER_COLORS, etc.)
│   ├── export.js                   Export formatting helpers (PDF, DOCX, TXT, CSV, MD)
│   ├── history_manager.js          Undo/redo history management
│   ├── theme.js                    Theme switching (dark/light/auto) helpers
│   ├── transcription_pricing.js    Cloud transcription cost estimation
│   ├── version_manager.js          Client-side version management helpers
│   └── server_access.js            Low-level fetch functions (raw API calls, no state)
└── utils/
    └── avatars.js                  User avatar generation

application/                        Flask server
├── __init__.py                     App factory
├── analytics.py                    Usage analytics tracking
├── auth.py                         Authentication helpers
├── config.py                       Server configuration
├── effect_chains.py                Audio effect chain logic
├── embed_generator.py              Quote embed HTML generation
├── embeds.py                       Embed CRUD and management
├── files.py                        Filesystem helpers
├── folders.py                      Folder hierarchy management
├── notify.py                       Notification delivery
├── permissions.py                  Permission checks (per-resource access control)
├── project_versions.py             Project version history management
├── projects.py                     Project CRUD logic
├── stats.py                        Usage statistics tracking
├── stripe_integration.py           Stripe payment integration helpers
├── subscriptions.py                Subscription plan logic
├── tools.py                        Server-side utility functions
├── usage_rollover.py               Scheduled usage counter rollover (cron job)
├── user_subscriptions.py           Per-user subscription state management
├── users.py                        User account management
├── db_access/
│   ├── db.py                       DB abstraction layer (interface)
│   ├── db_postgres.py              PostgreSQL implementation
│   └── db_sqlite.py                SQLite implementation
├── routing/
│   ├── admin.py                    Admin panel routes
│   ├── commands.py                 Flask CLI commands
│   ├── pages.py                    Page routes (landing, account, docs, etc.)
│   └── api/
│       ├── auth.py                 Auth API routes (/auth/*)
│       ├── dialog.py               Dialog/widget API routes
│       ├── embeds.py               Embeds API routes (/api/embeds/*)
│       ├── files.py                File management API routes (/api/projects/<id>/*)
│       ├── folder.py               Folder API routes (/api/folders/*)
│       ├── project.py              Project CRUD API routes (/api/projects/*)
│       ├── reporting.py            Reporting/abuse API routes
│       ├── signup.py               Signup/registration API routes
│       ├── stats.py                Stats API routes (/api/stats)
│       ├── stripe_routes.py        Stripe webhook and billing routes
│       ├── user.py                 User account API routes (/api/user/*)
│       └── versions.py             Version history API routes (/api/projects/<id>/versions/*)
├── storage/
│   ├── gcs.py                      Google Cloud Storage backend
│   └── local.py                    Local filesystem storage backend
└── transcription/
    ├── cuda_check.py               CUDA/GPU availability detection
    ├── local_transcribe.py         Local transcription (CPU/GPU, faster-whisper + pyannote)
    └── modal_transcribe.py         Cloud transcription (Modal AI, serverless GPU)

app.py                              Flask application entry point and blueprint registration
serve.py                            Production WSGI launcher (Gunicorn/Waitress)
local_launcher.py                   Desktop app launcher (local/offline mode)
runtime_hook_gpu.py                 PyInstaller runtime hook for GPU detection
run.sh / run.bat                    Convenience startup scripts
Caddyfile                           Caddy reverse-proxy configuration

How Templates, CSS, and JS Interact

1. Template Composition

index.html is the single root template rendered by Flask for the main app. It composes the page using Jinja2 {% include %} tags:

index.html
├── {% include "sidebar.html" %}
│   └── {% include "components/shortcut_legend.html" %}
└── {% include "workspace.html" %}
    ├── {% include "start_page.html" %}
    ├── {% include "workspace_panels/waveform_panel.html" %}
    ├── {% include "workspace_panels/speakers_panel.html" %}
    └── {% include "workspace_panels/transcript_panel.html" %}

Standalone pages (landing, account, presentation, etc.) each have their own top-level template and are served by routes in application/routing/pages.py.

Templates define static HTML structure and element IDs only. No data is injected into templates at render time (aside from static asset URLs via url_for). All dynamic content is written by JavaScript after the page loads.

2. CSS Loading

All stylesheets are declared as <link> tags in index.html, referenced via Flask's url_for('static', filename=...). There is no CSS bundler or preprocessor.

Load order matters:

  1. variables.css — defines CSS custom properties consumed by everything else
  2. main.css — base/reset styles
  3. Layout stylesheets (sidebar.css, start_page.css)
  4. Component stylesheets (components/*.css)
  5. Workspace panel stylesheets (workspace/*.css)

CSS files are scoped by directory: global styles live at the top level, component styles under components/, panel styles under workspace/. Standalone pages load only the stylesheets they need.

3. JavaScript as ES Modules

index.html loads a single script:

<script src="{{ url_for('static', filename='js/main.js') }}" type="module"></script>

main.js imports all other JS files using native ES module import syntax. There is no bundler (Webpack, Vite, etc.) — the browser resolves modules directly from the filesystem via Flask's static file serving.

4. JS ↔ Template Binding

JavaScript classes bind to the pre-rendered DOM by querying element IDs defined in the templates:

// Example from main.js / Workspace
this.sidebar     = document.querySelector("#sidebar");
this.sidebarList = document.querySelector("#sidebarList");

The templates establish the DOM contract (IDs, element types). The JS classes assume those IDs exist and will fail silently or throw if a template changes an ID without updating the corresponding JS.

5. Dynamic HTML Generation

Not all HTML comes from templates. Some elements are created entirely in JavaScript:

  • Sidebar project items — built by App.#buildProjectItem() in main.js
  • Context menusProjectContextMenu, SegmentContextMenu and others extend ContextMenu and create their own DOM trees
  • Confirm dialogsConfirmDialog appends a modal to document.body
  • Status badgesWorkspace.updateProjectServerStatus() writes badge elements into #projectServerStatus

These dynamic elements inherit styles from the globally-loaded CSS via shared class names (e.g., .ctx-item, .sidebar-item, .project-cloud-badge).

6. Cross-Panel Communication

The three workspace panels (WaveformPanel, TranscriptPanel, SpeakersPanel) do not reference each other directly. Workspace owns all three and wires them together at construction time via callbacks:

TranscriptPanel  --onSegmentHover-->  Workspace  --calls-->  WaveformPanel.setHoveredRegion()
WaveformPanel    --onRegionSelect-->  Workspace  --calls-->  TranscriptPanel.setSelectedSegment()
SpeakersPanel    --onSpeakerHover-->  Workspace  --calls-->  WaveformPanel.drawRegions()

This keeps panels decoupled: each panel exposes a callback API; Workspace provides the implementations.

7. State Management

State is split across two layers:

LayerLocationContents
Server/connectionServer (server.js)Server connection, auth token, connection status
Per-projectProject instancesTranscript, speakers, waveform data, dirty flags

Project tracks dirty state per data category (transcriptDirty, speakersDirty, waveformDirty). When a category is marked dirty, the project fires registered callbacks that trigger UI re-renders in Workspace. This is the primary mechanism for keeping the three panels in sync after an edit.

8. Server Communication

Server communication is handled by two layers:

  • Server class (server.js) — stateful class owned by App. Manages connection URL, auth token, and connection lifecycle. Exposes all server operations as methods. Fires callbacks (onStatusChanged, onConnect, onDisconnect) when connection state changes.
  • server_access.js (utilities) — stateless module of raw fetch() wrappers. Called by Server with the current base URL and token. All functions are async and throw on non-2xx responses.

9. Backend Routing

Routes are split into blueprints registered in app.py:

  • routing/pages.py — page routes (/, /account, /landing, /docs, /presentation/<id>, etc.)
  • routing/admin.py — admin panel routes
  • routing/api/project.py/api/projects — list, create, get, update, delete, duplicate
  • routing/api/files.py/api/projects/<id>/audio, /transcript, /speakers, /waveform, /transcribe, /samples
  • routing/api/folder.py/api/folders — folder CRUD and project-folder assignment
  • routing/api/auth.py/auth/login, /auth/logout
  • routing/api/user.py/api/user — account management
  • routing/api/signup.py/api/signup — registration
  • routing/api/stats.py/api/stats — usage statistics
  • routing/api/embeds.py/api/embeds — quote embed management
  • routing/api/versions.py/api/projects/<id>/versions — version history
  • routing/api/stripe_routes.py/api/billing, Stripe webhooks
  • routing/api/reporting.py — abuse/content reporting
  • routing/api/dialog.py — dialog state endpoints

10. Storage and Database Backends

Storage and database are abstracted behind interfaces to support both local and cloud deployments:

  • storage/local.py — stores files on the local filesystem
  • storage/gcs.py — stores files in Google Cloud Storage (production)
  • db_access/db.py — DB interface; selects backend based on config
  • db_access/db_sqlite.py — SQLite backend (local/desktop)
  • db_access/db_postgres.py — PostgreSQL backend (cloud/production)