From 1f08cfbc75c283062c8aa8a914042a63fea71b72 Mon Sep 17 00:00:00 2001 From: itsrubberduck Date: Wed, 6 May 2026 15:28:55 +0200 Subject: [PATCH] ui fixes --- .claude/worktrees/hopeful-cori-2f93b9 | 1 + app/pages/copilot.vue | 193 ++++++++++++++++---------- 2 files changed, 122 insertions(+), 72 deletions(-) create mode 160000 .claude/worktrees/hopeful-cori-2f93b9 diff --git a/.claude/worktrees/hopeful-cori-2f93b9 b/.claude/worktrees/hopeful-cori-2f93b9 new file mode 160000 index 0000000..e716262 --- /dev/null +++ b/.claude/worktrees/hopeful-cori-2f93b9 @@ -0,0 +1 @@ +Subproject commit e716262fe25a4f7c02147a055abd1cc252c16650 diff --git a/app/pages/copilot.vue b/app/pages/copilot.vue index d355f59..32db31d 100644 --- a/app/pages/copilot.vue +++ b/app/pages/copilot.vue @@ -70,6 +70,7 @@ const simbriefLoading = ref(false) const simbriefError = ref('') const showCanvas = ref(true) const showSimbrief = ref(false) +const asideHeight = ref(280) // Glossary const glossaryByTerm = new Map(glossary.map(g => [g.term.toUpperCase(), g])) @@ -336,10 +337,11 @@ function persist() { simbriefUser: simbriefUser.value, showCanvas: showCanvas.value, canvasImage: canvasImage.value, + asideHeight: asideHeight.value, })) } -watch([scratch, variantSel, activeStepId, showCanvas, simbriefUser], persist, {deep: true}) +watch([scratch, variantSel, activeStepId, showCanvas, simbriefUser, asideHeight], persist, {deep: true}) // Keyboard function onKey(e: KeyboardEvent) { @@ -402,6 +404,7 @@ onMounted(() => { if (typeof v.simbriefUser === 'string') simbriefUser.value = v.simbriefUser if (typeof v.showCanvas === 'boolean') showCanvas.value = v.showCanvas if (typeof v.canvasImage === 'string') canvasImage.value = v.canvasImage + if (typeof v.asideHeight === 'number') asideHeight.value = v.asideHeight } catch { } } @@ -420,8 +423,34 @@ onUnmounted(() => { window.removeEventListener('keydown', onKey) }) +// Resize Handle für Scratchpad +let resizing = false +let resizeStartY = 0 +let resizeStartH = 0 + +function onResizeStart(e: PointerEvent) { + resizing = true + resizeStartY = e.clientY + resizeStartH = asideHeight.value + ;(e.target as HTMLElement).setPointerCapture(e.pointerId) +} + +function onResizeMove(e: PointerEvent) { + if (!resizing) return + const dy = resizeStartY - e.clientY + asideHeight.value = Math.max(100, Math.min(resizeStartH + dy, window.innerHeight * 0.8)) +} + +function onResizeEnd(e: PointerEvent) { + if (!resizing) return + resizing = false + ;(e.target as HTMLElement).releasePointerCapture(e.pointerId) + persist() +} + // Canvas const canvasRef = ref(null) +const canvasWrapRef = ref(null) const drawColor = '#fde68a' const lineWidth = 2.6 let canvasInited = false @@ -531,11 +560,13 @@ function clearCanvas() { function cleanfeedCanvas() { const cv = canvasRef.value + const wrap = canvasWrapRef.value if (!cv) return const ctx = cv.getContext('2d')! const dpr = window.devicePixelRatio || 1 - const rect = cv.getBoundingClientRect() - const shift = Math.round(rect.height * 0.4) + // shift = 40% der sichtbaren Wrapper-Höhe + const wrapH = wrap ? wrap.clientHeight : 400 + const shift = Math.round(wrapH * 0.4) const img = ctx.getImageData(0, 0, cv.width, cv.height) ctx.save() ctx.setTransform(1, 0, 0, 1, 0, 0) @@ -543,6 +574,8 @@ function cleanfeedCanvas() { ctx.putImageData(img, 0, -shift * dpr) ctx.restore() ctx.scale(dpr, dpr) + // Scroll-Position mitnehmen: gleicher Viewport-Bereich sichtbar nach Shift + if (wrap) wrap.scrollTop = Math.max(0, wrap.scrollTop - shift) saveCanvasImage() } @@ -615,7 +648,7 @@ const actorLabel: Record = { - - -
- - - -
-
@@ -767,11 +783,36 @@ const actorLabel: Record = {
+ + - -