Commit Graph

242 Commits

Author SHA1 Message Date
Enriquefft af159e8a2b tighten legacy normalizer and guard against BackgroundLoadError double-wrap
Reviewer audit found two real risks in the prior amendment:

1. LEGACY_FILE_WALLPAPER_RE was too permissive. Any file:// URL
   containing /wallpapers/wallpaperN.jpg would match — including a user's
   own file at /home/me/wallpapers/wallpaper1.jpg that happened to share
   the name pattern. Silent data-loss potential: user's photo replaced
   with a bundled asset. In-app upload flow uses data: URIs today so it
   can't actually produce such a value, but the regex should be tight
   on intent. Now requires a known install-layout segment:
   resources/[assets/]wallpapers/ (packaged) or public/wallpapers/ (dev).

2. No upper bound on \d+. A corrupted or future-schema project with
   wallpaper99.jpg was silently rewritten to /wallpapers/wallpaper99.jpg
   which 404s. Now validates against WALLPAPER_PATHS; out-of-set
   bundled-looking values fall back to DEFAULT_WALLPAPER.

Also applied R2.2 defensive guard: resolveImageWallpaperUrl's catch
block now checks instanceof BackgroundLoadError and rethrows unchanged
instead of wrapping a second time. Current getAssetPath cannot throw
BackgroundLoadError so this is a future-proof against refactors.

Tests: 56 pass (up from 54). Added coverage for "user file outside
install dir stays untouched" and "bundled-looking but out-of-set falls
back to default".
2026-04-24 18:58:34 -05:00
Enriquefft f2ff7fb21c address review audit: persist canonical wallpaper, dedupe types, tighten edge cases
R1 — Persisted wallpaper is now always the canonical /wallpapers/wallpaperN.jpg
form, never the resolved file:// URL. Swatch clicks pass WALLPAPER_PATHS[i]
(the relative path) to onWallpaperChange; the resolved URL stays in
wallpaperPreviewUrls for rendering only. This prevents machine-specific paths
from being written into project JSON and avoids break-on-upgrade /
break-on-share regressions. Legacy projects carrying resolved file:// URLs are
rewritten by a new normalizer in normalizeProjectEditor:
file://…(/assets)?/wallpapers/wallpaperN.jpg → /wallpapers/wallpaperN.jpg.

R2 — resolveImageWallpaperUrl now catches anything getAssetPath throws
(UnsafeAssetPathError, AssetBaseUnavailableError) and rewraps as
BackgroundLoadError with the original as cause. Callers (videoExporter retry
loop, gifExporter catch, VideoEditor toast) only need one instanceof check and
users always see the translated errors.exportBackgroundLoadFailed toast.

R3 — src/vite-env.d.ts no longer duplicates Window.electronAPI. The interface
had drifted — renderer declaration was missing readBinaryFile, getPlatform,
revealInFolder, getShortcuts, saveShortcuts, hudOverlay*, countdown overlay
methods that electron-env.d.ts already declares. Removed the duplicate and
kept the triple-slash reference so the authoritative declaration is the one
in electron/electron-env.d.ts.

N1 — GRADIENT_RE accepts optional "repeating-" prefix so
repeating-linear/radial/conic-gradient values classify as gradients instead
of falling through to color.

N2 — displayBasename returns "(unknown)" sentinel for URLs without a
meaningful basename (file:///, bare /) instead of leaking the original string.

N3 — electron-builder.json5 extraResources block gets an inline comment
pointing at preload.ts:assetBaseDir so the bidirectional coupling is
discoverable from either file.

Tests: 54 unit tests pass (up from 35). New coverage for repeating
gradients, displayBasename sentinels, BackgroundLoadError cause wrapping,
legacy file:// wallpaper normalization (5 cases).
2026-04-24 18:55:04 -05:00
Enriquefft 702b733074 resolve asset base path synchronously from preload
Every consumer of /wallpapers/*.jpg — SettingsPanel, VideoPlayback,
frameRenderer — was doing async IPC round trips, useEffect dances, and
Promise.all for a value that is a build-time constant per process. Each
consumer showed briefly-empty or briefly-404ing state on first paint
until the handler's reply resolved.

The asset base URL depends only on process.defaultApp and
process.resourcesPath / __dirname — all available in preload at
context-bridge time. Compute once there, expose as a sync string.

- preload.ts resolves baseDir (process.resourcesPath packaged,
  <appRoot>/public unpackaged) and emits assetBaseUrl synchronously.
- get-asset-base-path IPC handler + main-process branching deleted.
- getAssetPath() is now sync. Returns string, not Promise<string>.
  Throws AssetBaseUnavailableError (new) when electronAPI.assetBaseUrl
  is missing — catastrophic preload failure, not silent 404.
- resolveImageWallpaperUrl() sync; same sync throw semantics.
- SettingsPanel: Promise.all + useState + useEffect collapse to one
  useMemo. First paint has real URLs, no 18× ERR_FILE_NOT_FOUND, no
  flicker.
- VideoPlayback: wallpaper-resolve useEffect collapses to useMemo.
- frameRenderer.setupBackground: drops the await.
- electronAPI type decls updated in both .d.ts files.
- 35 unit tests updated to reflect sync signature + new
  AssetBaseUnavailableError contract.

Silent-fallback behavior from getAssetPath (returning /relative when
electronAPI failed) is gone. Renderers now surface preload failures
instead of rendering 404s.
2026-04-24 18:33:03 -05:00
Enriquefft 86c1c483d4 avoid 404s on first swatch render
SettingsPanel fell back to rendering WALLPAPER_PATHS (raw
/wallpapers/*.jpg strings) during the brief window before the
resolveImageWallpaperUrl effect populated wallpaperPaths. In packaged
Electron the browser resolved those against a file:// origin, producing
18 ERR_FILE_NOT_FOUND requests per load / reload. The second render
replaced them with correct URLs, so swatches appeared — but the wasted
requests showed up in devtools and churned the network panel.

Drop the fallback; render nothing until the effect completes. The
resolution is effectively instant and avoids the empty-origin round
trip.
2026-04-24 18:22:27 -05:00
Enriquefft adf3855ac8 harden wallpaper resolver against traversal, PII, and SSOT drift
Adversarial review surfaced four defects and four drive-bys. All applied:

B1 (security, MEDIUM) — Path traversal via encodeRelativeAssetPath.
encodeURIComponent passed "." and ".." through unchanged; percent-encoded
"%2e%2e" got decoded by the URL constructor. Either form escaped the
asset root: new URL("../../etc/passwd", "file:///opt/Openscreen/resources/")
→ file:///opt/etc/passwd. Reject both at src/lib/assetPath.ts via a new
UnsafeAssetPathError thrown when a decoded segment equals "." or "..".

B2 (correctness) — classifyWallpaper returned { kind: "image" } for
conic-gradient(...), rgb(...), hsl(...), oklch(...), empty string,
and named colors like "red". Old frameRenderer's bare fillStyle = value
handled these; new code would throw BackgroundLoadError with misleading
message. Classification now anchors on regexes, accepts all CSS color
functions and all three gradient types, treats unknown strings as
fallthrough color (old behavior), and normalizes "" to "#000000".

B3 (SSOT) — DEFAULT_WALLPAPER, projectPersistence.WALLPAPER_PATHS, and
SettingsPanel.WALLPAPER_RELATIVE independently hardcoded the same
/wallpapers/wallpaperN.jpg pattern. Three drift sites collapse into one:
WALLPAPER_PATHS lives in src/lib/wallpaper.ts, DEFAULT_WALLPAPER derives
from WALLPAPER_PATHS[0], projectPersistence re-exports from the canonical
module, SettingsPanel imports it directly.

B4 (privacy) — BackgroundLoadError.message and the translated toast
surfaced full file paths like file:///home/<user>/…/wallpaper.jpg —
leaks the user's home directory in copy-pasted bug reports. Added a
displayUrl getter that returns just the basename (or "data:…" for data
URIs), wired into the toast. Full URL remains in console.error and
error.url for debugging.

N1 — resolveImageWallpaperUrl now rejects image paths that don't live
under /wallpapers/ (throws BackgroundLoadError). Narrows the blast
radius of the returned <resourcesPath>/ base so the renderer can only
request files within the wallpapers directory, regardless of what the
project JSON claims.

N2 — videoExporter retry loop no longer calls cleanup() twice in the
BackgroundLoadError branch; the finally handles it.

N3 — Browser tests assert BackgroundLoadError.url contains the failing
path. Guards the {{url}} i18n interpolation contract.

N4 — VideoPlayback wallpaper resolve effect now catches resolver
throws (UnsafeAssetPathError, BackgroundLoadError from /wallpapers/
prefix enforcement). Prevents the new strict-rejection logic from
silently leaving the preview without a background.

Tests: 35 unit tests pass (up from 20); new coverage for all color
functions, all gradient types, empty string, named color fallback,
whitespace trimming, /wallpapers/ prefix enforcement, traversal
rejection, percent-encoded traversal rejection, displayUrl basename
and data-URI abbreviation.
2026-04-24 18:16:57 -05:00
Enriquefft d145f80041 fix: wallpaper backgrounds black in exported video (#376)
Three independent defects plus one SSOT violation caused reported symptom
of image wallpapers rendering solid black in exported MP4/GIF while
appearing correctly in the editor preview.

Bug A — Dev-mode IPC handler returned <appPath>/public/assets/, but
wallpapers live at public/wallpapers/. No assets/ subdirectory exists in
source.

Bug B — FrameRenderer.setupBackground bypassed getAssetPath and did
window.location.origin + wallpaper, producing file:///wallpapers/*.jpg
404s in packaged Electron.

Bug C — setupBackground silently caught any background-load error and
filled black. Masked Bug B from the export pipeline; why the bug shipped.

Smell D — Asset layout asymmetric: public/wallpapers/ (dev) vs
resources/assets/wallpapers/ (packaged). assets/ subdirectory had no
other consumers.

Fixes:

- Unify asset layout. electron-builder extraResources now copies to
  resources/wallpapers/ (no assets/). Main handler returns
  <resourcesPath>/ packaged and <appPath>/public/ unpackaged. Same
  convention in both modes: /wallpapers/x.jpg maps to <base>/wallpapers/x.jpg.
  Nix package.nix mirror updated.

- New src/lib/wallpaper.ts module owns the wallpaper contract:
  DEFAULT_WALLPAPER, classifyWallpaper (color/gradient/image), and
  resolveImageWallpaperUrl (pure URL resolver, wraps getAssetPath).
  BackgroundLoadError typed error for short-circuit detection.

- FrameRenderer.setupBackground uses the new helpers. Silent black
  fallback removed; rethrows as BackgroundLoadError. Export pipeline
  (VideoExporter + GifExporter) short-circuits encoder-retry loop on
  BackgroundLoadError. VideoEditor catch site dispatches to translated
  exportBackgroundLoadFailed toast.

- VideoPlayback editor preview consolidated onto the same helpers.
  Three default-wallpaper path literals (useEditorHistory,
  projectPersistence, VideoPlayback) collapsed onto DEFAULT_WALLPAPER.

- i18n: new errors.exportBackgroundLoadFailed key added to all seven
  locales (en, zh-CN, zh-TW, es, fr, tr, ko-KR).

- Tests: 20 unit tests for wallpaper module (classifyWallpaper +
  resolveImageWallpaperUrl branches + BackgroundLoadError).
  videoExporter.browser.test.ts and gifExporter.browser.test.ts extended
  with image-wallpaper happy path and BackgroundLoadError failure path.

Migration note: packaged users upgrading in place may retain an empty
resources/assets/ directory from the prior layout. Unreferenced at
runtime; cosmetic only. DMG/AppImage fresh installs get the new layout
directly.
2026-04-24 17:59:21 -05:00
Siddharth d22c4190cf fix 2026-04-18 11:05:33 -07:00
Sid 57c6a590a9 Merge pull request #423 from org-cyber/fix/windows-export-clean
fix(windows): Fixed windows Export Issue and early decode Crash
2026-04-18 10:54:13 -07:00
Sid a20a31f27d Merge branch 'main' into fix/bug-fixes-security-and-reliability 2026-04-18 10:50:05 -07:00
Sid 0ec18358d5 Merge branch 'main' into cocoon/feature-duplicate-annotation 2026-04-18 10:37:56 -07:00
Test User 721e8f4759 Fix lint, type check errors, and apply CodeRabbit review feedback
- Remove trailing comma in SUPPORTED_LOCALES that caused Locale type to
  include undefined, fixing all downstream type errors
- Remove unused webcamSizePreset from useMemo dependency array
- Use parsed.toString() instead of raw url in shell.openExternal per
  Electron security best practice

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 21:37:16 +08:00
Cocoon-Break 64e011f798 style: wrap long onDuplicate prop to fix Biome formatter 2026-04-16 17:01:02 +08:00
Cocoon-Break 8b7047365c style: sort lucide-react imports alphabetically to fix Biome lint 2026-04-16 17:00:48 +08:00
Azeru 5caee9bc2d chore(merge): resolve merge conflict in streamingDecoder.ts
Address merge conflict markers added during resolution of Windows export fixes, ensuring clean integration of decode termination logic updates.
2026-04-16 09:51:26 +01:00
Sid ff52e55fa1 Merge branch 'main' into detect-system-lang 2026-04-15 23:02:34 -07:00
Cocoon-Break 12f3be02f2 fix: sort lucide-react imports alphabetically
Signed-off-by: Cocoon-Break <54054995+kuishou68@users.noreply.github.com>
2026-04-16 09:31:37 +08:00
LorenzoLancia 8bcce473d5 feat: add mosaic blur with black shading 2026-04-12 18:04:43 +02:00
imAaryash d1c9555464 feat(i18n): auto-discover valid locales and harden language menu
- derive available locales from locale folders with required namespace validation

- exclude incomplete locales and report missing namespace files

- align system-language suggestion and selectors with discovered locales

- improve launch HUD language menu interaction, scrolling, and viewport clipping

- make i18n-check discover locale folders automatically
2026-04-12 05:13:31 +05:30
moncef e8d6fe3d1b Merge branch 'main' into adjust-zoom-speed 2026-04-11 23:27:50 +01:00
Siddharth b713b6a9e8 fix: zoom focus now matches indicator position including wallpaper edges 2026-04-11 10:26:26 -07:00
Siddharth 40028cfd55 feat: add dual frame webcam layout preset (#347) 2026-04-11 10:01:19 -07:00
Siddharth 7169e583c7 revert: undo local merge of PR #347 2026-04-11 09:58:15 -07:00
Shreyas b1a1f45e93 refactor: simplify dual frame preset normalization 2026-04-11 09:30:01 -07:00
Shreyas bce1957505 fix: clear webcam position for non-pip layouts 2026-04-11 09:30:00 -07:00
Shreyas 24b4b4254a fix: normalize dual frame preset for portrait projects 2026-04-11 09:26:15 -07:00
Shreyas c55f462f1c feat: add dual frame webcam layout preset 2026-04-11 09:20:34 -07:00
moncef 8118a0cf89 Merge branch 'main' into adjust-zoom-speed 2026-04-08 22:10:55 +01:00
LorenzoLancia 38d72217c2 fix little things blur 2026-04-08 22:43:30 +02:00
LorenzoLancia f6b7c463f0 Fix last issues 2026-04-08 22:21:19 +02:00
LorenzoLancia f8232d9c76 Fix some little issues 2026-04-08 21:36:53 +02:00
LorenzoLancia 5a9c85c345 Fix formatting and locale config 2026-04-08 20:26:16 +02:00
Lorenzo Lancia a4f1c6a2ee feat: add blur selection (rectangle, oval) 2026-04-08 16:42:12 +02:00
moncef 0cb298d20b Fix Pr reviews 2026-04-07 11:58:45 +01:00
moncef 7409631207 Fix pr review SelecedSpeedId 2026-04-07 11:43:20 +01:00
moncef 8f35cf090c feat: add zoomRegionUtils to calculate dominant zoom regions and handle smooth transitions between connected regions 2026-04-07 11:40:39 +01:00
Garry Priambudi 0e1a69a7b2 Merge branch 'main' into feature/webcam-resize-slider 2026-04-07 17:13:38 +07:00
Sid 9024eaae61 Merge pull request #307 from Ayush765-spec/main
Added the new recording button so that user does not exit the entire application
2026-04-06 23:00:24 -07:00
Sid 306b61a902 Merge pull request #291 from 1shanpanta/feat/extended-speed-options
feat: extend speed options with higher presets and custom speed input
2026-04-06 22:14:08 -07:00
moncef 112f02fe03 feat: implement video editor timeline components with interactive zoom, trim, and speed region controls. 2026-04-07 00:30:23 +01:00
Garry Priambudi 5320f76aae Merge branch 'main' into feature/webcam-resize-slider 2026-04-06 07:56:28 +07:00
Sid f3d761b28d Merge pull request #324 from JasonOA888/fix/306-persist-user-settings
fix: persist user settings across sessions
2026-04-05 12:55:31 -07:00
Siddharth ae971bc480 fix: resolve type error, formatting, and import order from PR #321 2026-04-05 11:03:45 -07:00
Sid 213637967e fix(editor): track unsaved changes for new projects (#321)
fix(editor): track unsaved changes for new projects
2026-04-05 11:02:42 -07:00
JasonOA888 a8427b950e fix: resolve lint errors for CI
- Add updateState to useEffect dependency array
- Remove ineffective biome-ignore suppression comment
- Fix formatting in userPreferences.ts per biome rules
2026-04-06 02:01:01 +08:00
Ayush765-spec 013312be1f Refactor: update 'New Recording' dialog and atomize confirm workflow (plus lint fixes) 2026-04-05 22:27:32 +05:30
Ayush Mukherjee 735dd2a191 Merge branch 'siddharthvaddem:main' into main 2026-04-05 22:14:49 +05:30
Sid 5340272530 Merge pull request #313 from theaiagent/feature/frame-step-navigation
feat: add arrow key frame-by-frame playhead navigation
2026-04-05 08:49:43 -07:00
Garry Laly 79201569c5 feat: Add webcam size presets with slider 2026-04-05 20:00:44 +07:00
Garry Laly ca962ff16b feat: Add webcam size presets (small/medium/large) 2026-04-05 19:45:50 +07:00
cocoon 5426b6284c feat(editor): duplicate annotations 2026-04-05 09:16:04 +00:00