From 4d673ab556dd7b917f0a3a42535f867875abd0c4 Mon Sep 17 00:00:00 2001 From: dtoro Date: Sun, 15 Mar 2026 21:46:08 +0100 Subject: [PATCH] fix: scroll events --- .../src/app/recollections/logos/LogosPage.tsx | 68 +++++++++++-------- frontend/src/styles.css | 23 +++---- 2 files changed, 50 insertions(+), 41 deletions(-) diff --git a/frontend/src/app/recollections/logos/LogosPage.tsx b/frontend/src/app/recollections/logos/LogosPage.tsx index d36f1a9..ec075cf 100644 --- a/frontend/src/app/recollections/logos/LogosPage.tsx +++ b/frontend/src/app/recollections/logos/LogosPage.tsx @@ -3,16 +3,48 @@ * Layout and styling aligned with Flux (same flex/overflow, bg-background, theme). */ -import React, { useCallback, useEffect, useMemo, useRef } from 'react' +import React, { useCallback, useEffect, useMemo, useRef, forwardRef } from 'react' import { useLocation, useParams } from 'react-router-dom' import { useCreateBlockNote } from '@blocknote/react' import { BlockNoteView } from '@blocknote/shadcn' import { useTheme } from '@/lib/themeContext' + +/** Wraps BlockNoteView so refs go to a div, not the function component (avoids ref warning). */ +const BlockNoteViewWrapper = forwardRef>( + function BlockNoteViewWrapper(props, ref) { + const { className, ref: _ref, ...rest } = props as React.ComponentProps & { ref?: unknown } + return ( +
+ +
+ ) + } +) import { useRecollectionMenubar } from '../RecollectionMenubarContext' import { getLogosContent, setLogosContent, type StoredLogosContent } from '../recollectionStore' const SAVE_DEBOUNCE_MS = 400 +/** Known React ref warning from BlockNote/Radix internals; we can't fix it in our code. Suppress once at load so it's active before first BlockNote render. */ +function isBlockNoteRefWarning(args: unknown[]): boolean { + const s = args.map((a) => (typeof a === 'string' ? a : String(a))).join(' ') + return ( + s.includes('Function components cannot be given refs') && + s.includes('ForwardRef') && + s.includes('blocknote') + ) +} +let blockNoteRefWarningPatched = false +function patchBlockNoteRefWarning() { + if (blockNoteRefWarningPatched) return + blockNoteRefWarningPatched = true + const orig = console.error + console.error = (...args: unknown[]) => { + if (isBlockNoteRefWarning(args)) return + orig.apply(console, args) + } +} + export function LogosPage() { const { pathname } = useLocation() const { recollectionId } = useParams<{ recollectionId: string }>() @@ -80,34 +112,16 @@ export function LogosPage() { ) } - const handleWheel = useCallback((e: React.WheelEvent) => { - const el = scrollContainerRef.current - if (!el) return - const { scrollTop, scrollHeight, clientHeight } = el - const canScrollUp = scrollTop > 0 - const canScrollDown = scrollTop < scrollHeight - clientHeight - const scrollingDown = e.deltaY > 0 - const scrollingUp = e.deltaY < 0 - if ((scrollingDown && canScrollDown) || (scrollingUp && canScrollUp)) { - e.preventDefault() - el.scrollBy({ top: e.deltaY, behavior: 'auto' }) - } - }, []) + patchBlockNoteRefWarning() return ( -
-
-
- -
+
+
+
) diff --git a/frontend/src/styles.css b/frontend/src/styles.css index 785cd91..72c114c 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -426,24 +426,19 @@ pre { overflow: hidden; } +/* Non-visible face must not capture pointer/wheel so scroll and click work on the visible face only */ +.recollection-flip-card[data-flipped="false"] .recollection-flip-face-back { + pointer-events: none; +} + +.recollection-flip-card[data-flipped="true"] .recollection-flip-face-front { + pointer-events: none; +} + .recollection-flip-face-front { transform: rotateY(0deg); } .recollection-flip-face-back { transform: rotateY(-180deg); -} - -/* Logos page: BlockNote editor aligned with Flux (bg, theme). Document-style column. */ -.logos-page { - background: hsl(var(--background)); -} - -.logos-editor.bn-shadcn { - --bn-editor-background: transparent; -} - -.logos-editor .bn-editor { - min-height: 100%; - padding: 0; } \ No newline at end of file