diff --git a/package.json b/package.json index d0b7ff3..4f84adc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ruwio", "private": true, - "version": "0.18.0", + "version": "0.18.1", "type": "module", "scripts": { "dev": "vite", diff --git a/src/components/CanvasStage.vue b/src/components/CanvasStage.vue index 81eb633..d9bce85 100644 --- a/src/components/CanvasStage.vue +++ b/src/components/CanvasStage.vue @@ -821,11 +821,20 @@ const stackItems = computed(() => { instancesByTrack.set(ci.clipTrackId, arr) } + // Tracks whose parent TrackGroup is editor-hidden — same cascade + // as the Timeline's lockedGroupChildIds logic, just for the eye + // toggle. A child with its own editorHidden flag unset still + // disappears if its group carries one. + const hiddenGroupChildIds = new Set() + for (const g of store.scene.groups ?? []) { + if (g.editorHidden) for (const cid of g.childIds) hiddenGroupChildIds.add(cid) + } const expanded = expandedTrackOrder(store.scene) const order = expanded.length ? expanded : store.scene.layers.map((l) => l.id) // iterate bottom → top: reverse the array for (let i = order.length - 1; i >= 0; i--) { const id = order[i] + if (hiddenGroupChildIds.has(id)) continue const layer = layerById.get(id) if (layer) { // Editor-only hide: skip on the Konva stage while the scene diff --git a/src/components/Timeline.vue b/src/components/Timeline.vue index d9b2f9a..8820381 100644 --- a/src/components/Timeline.vue +++ b/src/components/Timeline.vue @@ -89,6 +89,7 @@ interface TimelineGroupTrack { collapsed: boolean color: string | null locked: boolean + editorHidden: boolean orderIndex: number childCount: number } @@ -808,6 +809,7 @@ const tracks = computed(() => { collapsed: !!grp.collapsed, color: grp.color ?? null, locked: !!grp.locked, + editorHidden: !!grp.editorHidden, orderIndex, childCount: grp.childIds.length, }) @@ -2741,6 +2743,36 @@ function duplicateTrackFromMenu() { async function renameFromMenu() { if (!trackMenu.value) return + if (trackMenu.value.kind === 'layer') { + const layer = store.activeLayers.find((l) => l.id === trackMenu.value!.trackId) + if (!layer) return + const id = trackMenu.value.trackId + const current = layer.name + trackMenu.value = null + const next = await promptDialog({ + title: t('timeline.renameLayerDialog.title'), + defaultValue: current, + confirmLabel: t('timeline.renameLayerDialog.confirm'), + }) + if (next === null) return + store.setLayerName(id, next) + return + } + if (trackMenu.value.kind === 'clip') { + const track = store.scene.clipTracks?.find((t) => t.id === trackMenu.value!.trackId) + if (!track) return + const id = trackMenu.value.trackId + const current = track.name ?? t('timeline.clipTrackName') + trackMenu.value = null + const next = await promptDialog({ + title: t('timeline.renameClipTrackDialog.title'), + defaultValue: current, + confirmLabel: t('timeline.renameClipTrackDialog.confirm'), + }) + if (next === null) return + store.setClipTrackName(id, next) + return + } if (trackMenu.value.kind === 'group') { const group = groupById.value.get(trackMenu.value.trackId) if (!group) return @@ -3778,6 +3810,16 @@ onBeforeUnmount(() => { {{ track.name }} {{ t('timeline.groupChildCount', { n: track.childCount }) }} + +