From c13158a5c518447aee7a3833bb19633d3aa266d9 Mon Sep 17 00:00:00 2001 From: AlexZ005 Date: Tue, 4 Aug 2026 20:23:52 +0300 Subject: [PATCH 1/8] [feat] scene notes v2: name/desc/color/label model, near-pin view+edit popover, drawer groups w/ traversal + pins toggle - H1 model: annotations gain optional name/color/label on top of `text` (still the description). ONE normalizeAnnotation() at every store boundary (local set, remote apply, snapshot, autosave restore) so old autosaves, .tpscene sessions and old-version peers load with defaults. Wire shape UNCHANGED ({type:'annotation', op:'set'}); saves spread the base so a newer peer's fields survive our edit. displayName()/noteNumber() helpers - numbering is the GLOBAL 1-based index, matching the in-scene pin labels. - H2 openAnnotation(id, 'view'|'edit'); activeAnnotation is {id, mode} (a bare {id} still means view). Pin clicks open the view face. - H3 showNotePins LOCAL pref (lightHelpers idiom) gates BOTH the pins render and Scene's pin-click raycast branch; toggle lives in the drawer header. - H4 pin circle + cone take the note color (amber stays the default). - H5 popover v2: full runes rewrite, one card with a view and an edit face, anchored by a continuous rAF screen projection of the pin (it rides the openAnnotation fly and later orbiting - flyTo has no completion hook), flips sides + clamps to the viewport, centre-fallback when the pin is behind the camera, bottom sheet at <=640px (closes the other sheets). Edit fields: name, description, fixed bright swatch row, label w/ a datalist of existing labels. - H6 drawer v2: rows are "#n name - description" (grey, single-line truncated), row click = fly + view, per-row Edit = fly + edit, collapsible label groups with 'General' first then alphabetical, per-group arrows traversing in pin order with wrap; runes flip. - H7 new suite notes-v2 (29 checks): legacy normalization, anchored popover + re-anchor on pin move, draft at the clicked point, edit saves + replicates the v2 fields (send spy) and applies from a peer, pin colors, group order, numbering vs pin indices, arrow traversal + wrap, collapse, pins toggle. A two-peer handshake check is env-gated (TWO_PEER=1). annotation-anchor, autosave-object-flows and roadmap-13-notifications-notes stay green; build green; svelte-check holds 419/62. Co-Authored-By: Claude Opus 5 (1M context) --- src/components/AnnotationPins.svelte | 17 +- src/components/Scene.svelte | 9 +- src/components/menu/AnnotationPopover.svelte | 488 +++++++++++++++++-- src/components/menu/NotesDrawer.svelte | 249 ++++++++-- src/lib/annotationsHandler.js | 107 +++- tests/e2e/notes-v2.test.cjs | 410 ++++++++++++++++ 6 files changed, 1169 insertions(+), 111 deletions(-) create mode 100644 tests/e2e/notes-v2.test.cjs diff --git a/src/components/AnnotationPins.svelte b/src/components/AnnotationPins.svelte index 8992585b..9f00d4eb 100644 --- a/src/components/AnnotationPins.svelte +++ b/src/components/AnnotationPins.svelte @@ -3,7 +3,7 @@ import { T, useTask, useThrelte } from '@threlte/core' // @ts-ignore - Text typing clashes with verbatimModuleSyntax import { Text } from '@threlte/extras' - import { annotations, pinsGroup } from '$lib/annotationsHandler' + import { annotations, pinsGroup, showNotePins, DEFAULT_NOTE_COLOR } from '$lib/annotationsHandler' import { objectsGroup, globalScene } from '../stores/sceneStore' // Billboarded note pins. Each pin re-anchors to its object every frame @@ -19,6 +19,7 @@ const cameraPosition = new THREE.Vector3() useTask(() => { + if (!$showNotePins) return camera.current.getWorldPosition(cameraPosition) $annotations.forEach((annotation) => { const pin = pinRefs[annotation.id] @@ -46,16 +47,24 @@ }) - + + {#each $annotations as annotation, index (annotation.id)} (pinRefs[annotation.id] = ref)} name={`pin-${annotation.id}`}> - + + - +