0.12.0: document drawer redesign, PWA install, clip/audio context menus + push-cascade

- Document drawer slides out from under the topbar (no tab, no hover
  peek); opens via project-name button, closes on outside-click or ESC.
  Layout: inputs row + divider + preset row, presets user-managed via
  popup and persisted in localStorage.
- PWA manifest + minimal service worker so Chrome installs RUWIO as a
  standalone app — suppresses the native fullscreen exit overlay.
- Clips and audio clips get right-click context menus (Duplicate /
  Delete) via new `duplicateClipInstance` / `duplicateAudioClip` store
  actions.
- Clip moves cascade non-overlap in both directions; `setAudioClipPosition`
  now pushes backward as well as forward. New `setClipInstancePosition`
  gives clip instances the same behaviour.
- Library drags carry timeline-shaped ghost previews (audio pill, clip
  pill, button thumb) instead of the library row; clip lane renders a
  dashed drop-target ghost and rejects window-overlap drops.
- Scene / Clipart drawer tabs disappear in fullscreen; the 24 px they
  occupied is reclaimed for the stage. Play button sits on the exact
  horizontal center via a 3-column grid in the transport cluster.
- Tests: context menu + push-cascade + duplicate action coverage for
  both clip kinds; DocumentDrawer suite rewritten for the slide-out
  model.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
thandClaude Opus 4.7 committed 2026-04-24 07:41:26 +02:00
1 parent fa66ba69bb
commit 354dd8a4f0
25 files changed
+2294 -405

No files matched your search

+38 -2
View File
@@ -23,7 +23,7 @@ export const en = {
},
renameProject: 'Rename project',
renameProjectHelp:
'Click to rename. Saved projects update in place; new names apply at the next save.',
'Opens the document drawer where you can rename the project. Saved projects update in place; unsaved names apply at the next save.',
renameProjectDialog: {
title: 'Rename project',
message: 'Choose a new name for this project.',
@@ -370,6 +370,18 @@ export const en = {
bgVideoUrlTitle: 'Background video URL',
bgVideoUrlMessage: 'Paste the video URL (must be reachable by the browser):',
bgVideoUrlConfirm: 'Load',
bgVideoButton: 'Background video',
bgVideoPicker: 'Click to choose a video · right-click for URL / clear',
presetsLabel: 'Presets',
presetAddTitle: 'Add preset',
presetAddMessage: 'Enter dimensions as WxH (e.g. 1920x1080).',
presetAddPlaceholder: '1920x1080',
presetAddConfirm: 'Add',
presetAddInvalid: 'Please enter dimensions like 1920x1080.',
presetAddTooltip: 'Add preset',
presetRemoveTitle: 'Remove preset?',
presetRemoveMessage: 'Remove "{label}" from your presets?',
presetRemoveConfirm: 'Remove',
canvas: 'Canvas',
width: 'Width',
height: 'Height',
@@ -438,6 +450,12 @@ export const en = {
'Point to a local folder with your images and audio files. The app remembers the folder; permissions may be re-asked after browser restart.',
},
documentDrawer: {
open: 'Open document settings',
close: 'Close document settings',
projectName: 'Project',
},
scenes: {
title: 'Scenes',
open: 'Open scenes',
@@ -952,7 +970,7 @@ export const de: DeepPartial<Messages> = {
},
renameProject: 'Projekt umbenennen',
renameProjectHelp:
'Klicken, um den Namen zu ändern. Gespeicherte Projekte werden direkt aktualisiert. Neue Namen gelten beim nächsten Speichern.',
'Öffnet die Dokument-Schublade, in der das Projekt umbenannt werden kann. Gespeicherte Projekte werden direkt aktualisiert, ungespeicherte Namen gelten beim nächsten Speichern.',
renameProjectDialog: {
title: 'Projekt umbenennen',
message: 'Wähle einen neuen Namen für dieses Projekt.',
@@ -1122,6 +1140,18 @@ export const de: DeepPartial<Messages> = {
bgVideoUrlTitle: 'Hintergrundvideo-URL',
bgVideoUrlMessage: 'Video-URL einfügen. Sie muss im Browser erreichbar sein:',
bgVideoUrlConfirm: 'Laden',
bgVideoButton: 'Hintergrundvideo',
bgVideoPicker: 'Klick für Videoauswahl · Rechtsklick für URL / Entfernen',
presetsLabel: 'Presets',
presetAddTitle: 'Preset hinzufügen',
presetAddMessage: 'Maße als BxH eingeben (z. B. 1920x1080).',
presetAddPlaceholder: '1920x1080',
presetAddConfirm: 'Hinzufügen',
presetAddInvalid: 'Bitte Maße wie 1920x1080 eingeben.',
presetAddTooltip: 'Preset hinzufügen',
presetRemoveTitle: 'Preset entfernen?',
presetRemoveMessage: '„{label}" aus den Presets entfernen?',
presetRemoveConfirm: 'Entfernen',
canvas: 'Canvas',
width: 'Breite',
height: 'Höhe',
@@ -1188,6 +1218,12 @@ export const de: DeepPartial<Messages> = {
settingsHint:
'Verweise auf einen lokalen Ordner mit Bildern und Audio. Die App merkt sich den Ordner. Nach einem Browser-Neustart kann die Berechtigung erneut abgefragt werden.',
},
documentDrawer: {
open: 'Dokument-Einstellungen öffnen',
close: 'Dokument-Einstellungen schließen',
projectName: 'Projekt',
},
scenes: {
title: 'Szenen',
open: 'Szenen öffnen',