0.5.2: paste images, shared import helper, clipart persistence

- Clipboard paste creates an image layer: a document-level paste
  listener detects image items in the clipboard (Strg+V after a
  screenshot, e.g.) and imports them via the shared helper. Skipped
  when focus is in a real text input / textarea / contenteditable.
- Shared importImageFile() helper in fileLoader.ts replaces the
  duplicated image-import logic in AssetSidebar and CanvasStage's
  clipart-drop path. Optional position argument for drop-at-point.
- Clipart folder persistence hardened for reloads:
  - initialize() is now safely re-runnable (no-ops only once a handle
    is actually loaded, tolerates refresh failures so the folder name
    survives even if permission isn't auto-granted)
  - App.vue's onMounted kicks off initialize() so it runs regardless
    of whether the drawer component has mounted
  - DocumentSettings re-invokes initialize() each time the modal
    opens — covers app-start races and gives the user gesture needed
    for FS Access permission prompts
  - Opening the drawer refreshes thumbnails when handle is set but
    items are empty, so the user-gesture context restores permission

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
thandClaude Opus 4.7 committed 2026-04-20 14:05:48 +02:00
1 parent cbc309bc8c
commit 07b0ef2659
8 files changed
+126 -65

No files matched your search

+12 -2
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
import { computed, ref, watch } from 'vue'
import {
PhClock,
PhFolder,
@@ -15,13 +15,23 @@ import type { Theme } from '@/composables/useTheme'
import { Modal } from '@/components/ui'
import { t } from '@/i18n'
defineProps<{ modelValue: boolean }>()
const props = defineProps<{ modelValue: boolean }>()
const emit = defineEmits<{ 'update:modelValue': [value: boolean] }>()
const store = useSceneStore()
const clipart = useClipartStore()
const { theme, setTheme } = useTheme()
// Re-check the stored clipart folder whenever settings opens — covers the
// case where initial App.vue init raced ahead of IDB or the user opens
// settings before the drawer ever mounted.
watch(
() => props.modelValue,
(open) => {
if (open) void clipart.initialize()
},
)
type TabId = 'document' | 'timeline' | 'clipart' | 'theme'
const tabs: { id: TabId; label: string; icon: typeof PhFrameCorners }[] = [