Skip to content

refactor: options-page: Refactor options UI/UX, add new configurable modules, added app settings object for using configurables variables#34

Merged
jvillegasd merged 21 commits intomainfrom
refactor/options-page
Mar 4, 2026
Merged

refactor: options-page: Refactor options UI/UX, add new configurable modules, added app settings object for using configurables variables#34
jvillegasd merged 21 commits intomainfrom
refactor/options-page

Conversation

@jvillegasd
Copy link
Owner

This pull request delivers a major upgrade to the extension's configuration, history, and UI systems, along with foundational improvements for code maintainability and user experience. The most significant changes include a comprehensive redesign of the options page (now a full-featured settings UI with history and advanced controls), persistent download history with infinite scroll and batch actions, new notification features, and a refactor of configuration management for type safety and scalability. Additionally, design tokens and badge styles are introduced for a consistent UI, and relevant code is updated to support these new features.

Options Page and Configuration Overhaul

  • The options page is now a full settings UI with sidebar navigation, covering Download, History, Google Drive, S3, Recording, Notifications, and Advanced sections. All settings changes are confirmed via toast notifications, and the popup's History button opens the options page directly to the history section. [1] [2] [3]
  • Configuration is now managed via a typed AppSettings object, always accessed through loadSettings() in core/storage/settings.ts, ensuring all defaults are applied and type safety is enforced. The config includes advanced settings like detection cache sizes and sync intervals. [1] [2] [3] [4]
  • Constants are now separated into src/shared/constants.ts (cross-module) and src/options/constants.ts (options UI only), with clear documentation on time unit conversions and usage. [1] [2]

Download History and Batch Actions

  • Completed, failed, and cancelled downloads are persisted in IndexedDB when historyEnabled is true (default). The options page History section supports infinite scroll, re-download, copy URL, and bulk delete via the new bulkDeleteDownloads() function. [1] [2]
  • The popup UI now includes a History button that opens the options page directly to the history section. [1] [2]

Notification and Post-Download Features

  • Optional OS notifications and auto-open file actions are now available after download completion, controlled by AppSettings.notifications. [1] [2]
  • The manifest now requests the notifications permission.

Detection and Performance Improvements

  • Detection cache sizes are now configurable via the advanced settings, and these settings are passed through to detection handlers for improved performance and scalability. [1] [2] [3] [4] [5]

UI/UX Enhancements

  • Introduces a new shared stylesheet (public/shared.css) with design tokens, dark/light mode support, and consistent badge styles for download status and metadata.
  • Options page field validation is now robust, with clear error feedback and cross-field constraint handling.

These changes collectively modernize the extension's configuration, history, and UI, laying the groundwork for future features and improved user experience.

jvillegasd and others added 21 commits March 2, 2026 23:51
…nfig

- Replace flat options layout with a sidebar + multi-view layout (Download Settings, Cloud Providers, History)
- Add History view with search/format/status/date filters, bulk delete, per-item actions (re-download, copy URL, manifest health check, delete)
- Add S3/compatible cloud provider form alongside existing Google Drive panel
- Add history button (clock icon) in popup top bar that opens options directly to History view
- Add CHECK_URL message type so options page can probe manifest URLs via service worker (bypasses CORS)
- Add bulkDeleteDownloads() IDB utility for efficient multi-item deletion
- Extend StorageConfig with historyEnabled and s3 fields
- Auto-delete terminal downloads from IDB when historyEnabled is false
- All views centered; CSS tooltips on history action icon buttons

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Completed/failed/cancelled downloads now appear exclusively in the
History view on the options page, not in the popup Downloads tab.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Completed downloads no longer appear in the popup Downloads tab, so the
Open File button is now in the History view (options page). Only shown
for COMPLETED items with a known localPath. Removes dead completed/failed
action button code from render-downloads.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… settings icon

Replaces SVG placeholder logo with the actual extension icon (icon-32.png).
Swaps the messy gear/path icon on Download Settings for a clean sliders icon.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Collapses Open file / Re-download / Copy URL / Check manifest / Delete
into a single ··· button per row. Menu closes on outside click or action
selection. Check manifest state feedback is shown inline on the menu item.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the inline button state feedback with a bottom-center toast.
"Checking…" appears immediately, then resolves to success/warning/error
with the HTTP status or a CORS note. Toast auto-dismisses after 3 seconds.
Removes now-unused check-btn CSS from the menu item.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shows "Download queued" toast on success or an error toast if the
service worker rejects. Refreshes the history list in place so the
user stays on the history view without a full page reload.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
switchView() now calls history.replaceState to keep the URL hash in sync
with the active section. On refresh, init() reads the hash and opens the
correct view instead of always falling back to download-settings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Render first 50 items on load; append subsequent batches as the user
scrolls near the bottom via a sentinel div watched by IntersectionObserver.
Filters and search reset to the first page on every change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tory updates

- Rename TERMINAL_STAGES → FINISHED_STAGES and handleTerminalDownload →
  handleFinishedDownload to align with DownloadStage terminology used
  elsewhere in the codebase
- Update service-worker.ts JSDoc comment to match ("terminal" → "finished")
- Add real-time history updates via DOWNLOAD_PROGRESS message listener —
  newly finished downloads appear/update without requiring a page reload
- Flash animation (history-item--new) highlights items as they arrive

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add three new options sections: Recording (poll intervals), Notifications
  (OS notify + auto-open), and Advanced (retries, backoff, caches, IDB sync)
- Wire all new settings through DownloadManager → BasePlaylistHandler →
  fetch-utils so retryDelayMs and retryBackoffFactor now take effect at runtime
- Read detectionCacheSize/masterPlaylistCacheSize from chrome.storage in
  content script init so detection cache limits are configurable
- Add cross-field validation: min poll interval must be < max poll interval
- Add notifications permission to manifest for OS completion alerts
- Add post-download actions handler (notify on completion, reveal in Finder)
- Fix re-recording: clean up finished IDB entry before starting fresh
- Fix CHECK_URL: use GET for HLS/DASH manifests to avoid CDN 403s on HEAD
- Fix history re-download: send START_RECORDING for live stream entries
- Add live badge to history items for recordings from live streams
- Add history-item flash animation on completion while history tab is open

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add src/core/storage/settings.ts with AppSettings interface and
  loadSettings() — single function that reads StorageConfig and applies
  all defaults, eliminating scattered ?? DEFAULT_X fallbacks
- Migrate all read-only config calls in service-worker.ts and options.ts
  load functions to use loadSettings(); save functions keep raw
  ChromeStorage reads to preserve merge-and-write-back pattern
- Consolidate maxConcurrent into StorageConfig (was stored under a
  separate "max_concurrent" key); remove MAX_CONCURRENT_KEY constant
- loadSettings() now does a single storage read instead of Promise.all
  with two keys

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…toast

- Add src/options/constants.ts for options-page-only validation bounds
  and UI timing constants (TOAST_DURATION_MS, MS_PER_DAY, MIN/MAX clamps)
- Add DEFAULT_GOOGLE_DRIVE_FOLDER_NAME to shared/constants (used by both
  options.ts and settings.ts)
- Replace showStatus(elementId, msg, type) with showStatus(msg, type)
  that delegates to showToast — all save confirmations now use the same
  bottom toast as history actions
- Remove all status-msg div elements and their CSS from options.html
- Replace every hardcoded clamp literal in saveRecordingSettings and
  saveAdvancedSettings with named constants

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All time inputs now display in seconds; internal storage remains ms
throughout. Conversion happens only at the options page boundary
(divide on load, multiply on save).

- ffmpeg-timeout: minutes → seconds (15 min = 900 s, range 300–3 600)
- poll-min/max: ms → seconds (1 000 ms = 1 s, 10 000 ms = 10 s)
- retry-delay: ms → seconds (100 ms = 0.1 s)
- db-sync-interval: ms → seconds (500 ms = 0.5 s)

Remove DEFAULT_FFMPEG_TIMEOUT_MINUTES, MIN/MAX_FFMPEG_TIMEOUT_MINUTES,
and MS_PER_MINUTE from shared/constants (options-only). Replace with
_S equivalents in options/constants.ts alongside updated _S clamp bounds.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove makeIconBtn and iconSpinner — defined but never called.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…anges

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…shared.css

Move duplicated @font-face declarations, CSS custom properties, reset,
scrollbar, and badge styles out of popup.html and options.html into a
new public/shared.css. Both pages now reference it via /shared.css.

Also unifies token drift between the two files: options gains --recording,
--space-*, and --radius-lg; badge colors are harmonised; options gets
light-mode badge overrides it was missing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace silent Math.max/Math.min clamping in all save handlers with
explicit validation. Invalid fields get a red border and an inline error
message; the button stays enabled and no write is attempted until all
fields pass.

Helpers: validateField(), markInvalid(), clearInvalid() in options.ts.
The recording cross-field check (min < max) now marks the specific field
invalid instead of falling back to the toast. Toast is reserved for
storage/network errors. Documents the pattern in CLAUDE.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jvillegasd jvillegasd self-assigned this Mar 4, 2026
@github-actions github-actions bot changed the title refactor/options-page: Refactor options UI/UX, add new configurable modules, added app settings object for using configurables variables refactor: options-page: Refactor options UI/UX, add new configurable modules, added app settings object for using configurables variables Mar 4, 2026
@jvillegasd jvillegasd merged commit 0c5e2bf into main Mar 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant