a tool for shared writing and social publishing

remove long press to select on mobile docs, kept for canvas

+40 -31
+1 -11
components/Blocks/Block.tsx
··· 77 }); 78 let entity_set = useEntitySetContext(); 79 80 - let { isLongPress, handlers } = useLongPress(() => { 81 - if (isTextBlock[props.type]) return; 82 - if (isLongPress.current) { 83 - focusBlock( 84 - { type: props.type, value: props.entityID, parent: props.parent }, 85 - { type: "start" }, 86 - ); 87 - } 88 - }); 89 - 90 let selected = useUIState( 91 (s) => !!s.selectedBlocks.find((b) => b.value === props.entityID), 92 ); ··· 117 118 return ( 119 <div 120 - {...(!props.preview ? { ...mouseHandlers, ...handlers } : {})} 121 id={ 122 !props.preview ? elementId.block(props.entityID).container : undefined 123 }
··· 77 }); 78 let entity_set = useEntitySetContext(); 79 80 let selected = useUIState( 81 (s) => !!s.selectedBlocks.find((b) => b.value === props.entityID), 82 ); ··· 107 108 return ( 109 <div 110 + {...(!props.preview ? { ...mouseHandlers } : {})} 111 id={ 112 !props.preview ? elementId.block(props.entityID).container : undefined 113 }
+21 -3
components/Blocks/useBlockMouseHandlers.ts
··· 1 import { useSelectingMouse } from "components/SelectionManager/selectionState"; 2 - import { MouseEvent, useCallback, useRef } from "react"; 3 import { useUIState } from "src/useUIState"; 4 import { Block } from "./Block"; 5 import { isTextBlock } from "src/utils/isTextBlock"; ··· 12 import { elementId } from "src/utils/elementId"; 13 14 let debounce: number | null = null; 15 export function useBlockMouseHandlers(props: Block) { 16 let entity_set = useEntitySetContext(); 17 let isMobile = useIsMobile(); ··· 22 if ((e.target as Element).tagName === "BUTTON") return; 23 if ((e.target as Element).tagName === "SELECT") return; 24 if ((e.target as Element).tagName === "OPTION") return; 25 - if (isMobile) return; 26 if (!entity_set.permissions.write) return; 27 useSelectingMouse.setState({ start: props.value }); 28 if (e.shiftKey) { ··· 57 ); 58 let onMouseEnter = useCallback( 59 async (e: MouseEvent) => { 60 - if (isMobile) return; 61 if (!entity_set.permissions.write) return; 62 if (debounce) window.clearTimeout(debounce); 63 debounce = window.setTimeout(async () => {
··· 1 import { useSelectingMouse } from "components/SelectionManager/selectionState"; 2 + import { MouseEvent, useCallback } from "react"; 3 import { useUIState } from "src/useUIState"; 4 import { Block } from "./Block"; 5 import { isTextBlock } from "src/utils/isTextBlock"; ··· 12 import { elementId } from "src/utils/elementId"; 13 14 let debounce: number | null = null; 15 + 16 + // Track scrolling state for mobile 17 + let isScrolling = false; 18 + let scrollTimeout: number | null = null; 19 + 20 + if (typeof window !== "undefined") { 21 + window.addEventListener( 22 + "scroll", 23 + () => { 24 + isScrolling = true; 25 + if (scrollTimeout) window.clearTimeout(scrollTimeout); 26 + scrollTimeout = window.setTimeout(() => { 27 + isScrolling = false; 28 + }, 150); 29 + }, 30 + true, 31 + ); 32 + } 33 export function useBlockMouseHandlers(props: Block) { 34 let entity_set = useEntitySetContext(); 35 let isMobile = useIsMobile(); ··· 40 if ((e.target as Element).tagName === "BUTTON") return; 41 if ((e.target as Element).tagName === "SELECT") return; 42 if ((e.target as Element).tagName === "OPTION") return; 43 + if (isMobile && isScrolling) return; 44 if (!entity_set.permissions.write) return; 45 useSelectingMouse.setState({ start: props.value }); 46 if (e.shiftKey) { ··· 75 ); 76 let onMouseEnter = useCallback( 77 async (e: MouseEvent) => { 78 + if (isMobile && isScrolling) return; 79 if (!entity_set.permissions.write) return; 80 if (debounce) window.clearTimeout(debounce); 81 debounce = window.setTimeout(async () => {
+17 -16
components/Canvas.tsx
··· 290 }, 291 [props, rep, permissions], 292 ); 293 - let { dragDelta, handlers } = useDrag({ 294 onDragEnd, 295 delay: isMobile, 296 }); ··· 339 ); 340 let rotateHandle = useDrag({ onDragEnd: RotateOnDragEnd }); 341 342 - let { isLongPress, handlers: longPressHandlers } = useLongPress(() => { 343 - if (isLongPress.current && permissions.write) { 344 - focusBlock( 345 - { 346 - type: type?.data.value || "text", 347 - value: props.entityID, 348 - parent: props.parent, 349 - }, 350 - { type: "start" }, 351 - ); 352 - } 353 - }); 354 let angle = 0; 355 if (rotateHandle.dragDelta) { 356 let originX = rect.x + rect.width / 2; ··· 395 return ( 396 <div 397 ref={ref} 398 - {...(!props.preview ? { ...longPressHandlers } : {})} 399 - {...(isMobile && permissions.write ? { ...handlers } : {})} 400 id={props.preview ? undefined : elementId.block(props.entityID).container} 401 className={`absolute group/canvas-block will-change-transform rounded-lg flex items-stretch origin-center p-3 `} 402 style={{ ··· 408 }} 409 > 410 {/* the gripper show on hover, but longpress logic needs to be added for mobile*/} 411 - {!props.preview && permissions.write && <Gripper {...handlers} />} 412 <div 413 className={`contents ${dragDelta || widthHandle.dragDelta || rotateHandle.dragDelta ? "pointer-events-none" : ""} `} 414 >
··· 290 }, 291 [props, rep, permissions], 292 ); 293 + let { dragDelta, handlers: dragHandlers } = useDrag({ 294 onDragEnd, 295 delay: isMobile, 296 }); ··· 339 ); 340 let rotateHandle = useDrag({ onDragEnd: RotateOnDragEnd }); 341 342 + let { isLongPress, longPressHandlers: longPressHandlers } = useLongPress( 343 + () => { 344 + if (isLongPress.current && permissions.write) { 345 + focusBlock( 346 + { 347 + type: type?.data.value || "text", 348 + value: props.entityID, 349 + parent: props.parent, 350 + }, 351 + { type: "start" }, 352 + ); 353 + } 354 + }, 355 + ); 356 let angle = 0; 357 if (rotateHandle.dragDelta) { 358 let originX = rect.x + rect.width / 2; ··· 397 return ( 398 <div 399 ref={ref} 400 + {...(isMobile && permissions.write ? { ...dragHandlers } : {})} 401 id={props.preview ? undefined : elementId.block(props.entityID).container} 402 className={`absolute group/canvas-block will-change-transform rounded-lg flex items-stretch origin-center p-3 `} 403 style={{ ··· 409 }} 410 > 411 {/* the gripper show on hover, but longpress logic needs to be added for mobile*/} 412 + {!props.preview && permissions.write && <Gripper {...dragHandlers} />} 413 <div 414 className={`contents ${dragDelta || widthHandle.dragDelta || rotateHandle.dragDelta ? "pointer-events-none" : ""} `} 415 >
+1 -1
src/hooks/useLongPress.ts
··· 90 return useMemo( 91 () => ({ 92 isLongPress: isLongPress, 93 - handlers: { 94 onPointerDown, 95 onPointerUp: end, 96 onClickCapture: click,
··· 90 return useMemo( 91 () => ({ 92 isLongPress: isLongPress, 93 + longPressHandlers: { 94 onPointerDown, 95 onPointerUp: end, 96 onClickCapture: click,