From bfbe7b8325f96620ead67a429dce3794d353d0c1 Mon Sep 17 00:00:00 2001 From: Jeff-Emmett Date: Sat, 18 Jan 2025 01:57:54 +0700 Subject: [PATCH] expand board zoom & fixed embedshape focus on mobile --- src/routes/Board.tsx | 21 +++++++++++++++- src/shapes/EmbedShapeUtil.tsx | 46 +++++++++++++++++++++++++++++++++++ src/ui/overrides.tsx | 10 ++++++-- 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/src/routes/Board.tsx b/src/routes/Board.tsx index 6339121..8951453 100644 --- a/src/routes/Board.tsx +++ b/src/routes/Board.tsx @@ -63,7 +63,26 @@ export function Board() { tools={tools} components={components} overrides={overrides} - //maxZoom={20} + cameraOptions={{ + zoomSteps: [ + 0.001, // Min zoom + 0.0025, + 0.005, + 0.01, + 0.025, + 0.05, + 0.1, + 0.25, + 0.5, + 1, + 2, + 4, + 8, + 16, + 32, + 64 // Max zoom + ] + }} onMount={(editor) => { setEditor(editor) editor.registerExternalAssetHandler("url", unfurlBookmarkUrl) diff --git a/src/shapes/EmbedShapeUtil.tsx b/src/shapes/EmbedShapeUtil.tsx index ce18a2a..02da099 100644 --- a/src/shapes/EmbedShapeUtil.tsx +++ b/src/shapes/EmbedShapeUtil.tsx @@ -206,6 +206,14 @@ export class EmbedShape extends BaseBoxShapeUtil {
document.querySelector("input")?.focus()} + onPointerDown={(e) => { + e.preventDefault() + document.querySelector("input")?.focus() + }} + onTouchStart={(e) => { + e.preventDefault() + document.querySelector("input")?.focus() + }} >
{
) } + + override onDoubleClick = (shape: IEmbedShape) => { + // If no URL is set, focus the input field + if (!shape.props.url) { + const input = document.querySelector('input') + input?.focus() + return + } + + // For Medium articles and Twitter profiles that show alternative content + if ( + shape.props.url.includes('medium.com') || + (shape.props.url && shape.props.url.match(/(?:twitter\.com|x\.com)\/[^\/]+$/)) + ) { + window.top?.open(shape.props.url, '_blank', 'noopener,noreferrer') + return + } + + // For other embeds, enable interaction by temporarily removing pointer-events: none + const iframe = document.querySelector(`[data-shape-id="${shape.id}"] iframe`) as HTMLIFrameElement + if (iframe) { + iframe.style.pointerEvents = 'all' + // Reset pointer-events after interaction + const cleanup = () => { + iframe.style.pointerEvents = 'none' + window.removeEventListener('pointerdown', cleanup) + } + window.addEventListener('pointerdown', cleanup) + } + } + + // Add new method to handle all pointer interactions + onPointerDown = (shape: IEmbedShape) => { + if (!shape.props.url) { + const input = document.querySelector('input') + input?.focus() + } + } } diff --git a/src/ui/overrides.tsx b/src/ui/overrides.tsx index 20c1ede..944871e 100644 --- a/src/ui/overrides.tsx +++ b/src/ui/overrides.tsx @@ -8,6 +8,7 @@ import { } from "./cameraUtils" import { saveToPdf } from "../utils/pdfUtils" import { searchText } from "../utils/searchUtils" +import { EmbedShape, IEmbedShape } from "@/shapes/EmbedShapeUtil" export const overrides: TLUiOverrides = { tools(editor, tools) { @@ -42,8 +43,13 @@ export const overrides: TLUiOverrides = { //TODO: Fix double click to zoom on selector tool later... onDoubleClick: (info: any) => { - // Prevent default double-click behavior (which would start text editing) - info.preventDefault?.() + const shape = editor.getShapeAtPoint(info.point) + if (shape?.type === 'Embed') { + // Let the Embed shape handle its own double-click behavior + const util = editor.getShapeUtil(shape) as EmbedShape + util?.onDoubleClick?.(shape as IEmbedShape) + return + } // Handle all pointer types (mouse, touch, pen) const point = info.point || (info.touches && info.touches[0]) || info