your personal website on atproto - mirror blento.app

Compare changes

Choose any two refs to compare.

+29 -6
+1 -1
.gitignore
··· 22 vite.config.js.timestamp-* 23 vite.config.ts.timestamp-* 24 25 - react-grid-layout
··· 22 vite.config.js.timestamp-* 23 vite.config.ts.timestamp-* 24 25 + references
+28 -5
src/lib/components/qr/qrOverlay.svelte.ts
··· 18 const LONG_PRESS_DURATION = 500; 19 let longPressTimer: ReturnType<typeof setTimeout> | null = null; 20 let isLongPress = false; 21 22 function getHref() { 23 return params.href || (node as HTMLAnchorElement).href || ''; 24 } 25 26 - function startLongPress() { 27 if (params.disabled) return; 28 isLongPress = false; 29 longPressTimer = setTimeout(() => { 30 isLongPress = true; ··· 37 clearTimeout(longPressTimer); 38 longPressTimer = null; 39 } 40 } 41 42 function handleClick(e: MouseEvent) { 43 if (isLongPress) { 44 e.preventDefault(); 45 isLongPress = false; 46 } 47 } 48 49 - function handleContextMenu(e: MouseEvent) { 50 - if (params.disabled) return; 51 - e.preventDefault(); 52 - openModal?.(getHref(), params.context ?? {}); 53 } 54 55 node.addEventListener('pointerdown', startLongPress); ··· 71 node.removeEventListener('click', handleClick); 72 node.removeEventListener('contextmenu', handleContextMenu); 73 cancelLongPress(); 74 } 75 }; 76 }
··· 18 const LONG_PRESS_DURATION = 500; 19 let longPressTimer: ReturnType<typeof setTimeout> | null = null; 20 let isLongPress = false; 21 + let touchActive = false; 22 + 23 + // Prevent iOS link preview on long-press 24 + const originalCallout = node.style.getPropertyValue('-webkit-touch-callout'); 25 + node.style.setProperty('-webkit-touch-callout', 'none'); 26 27 function getHref() { 28 return params.href || (node as HTMLAnchorElement).href || ''; 29 } 30 31 + function startLongPress(e: PointerEvent) { 32 if (params.disabled) return; 33 + // Only start long press for primary button (touch/left-click), not right-click 34 + if (e.button !== 0) return; 35 + touchActive = e.pointerType === 'touch'; 36 isLongPress = false; 37 longPressTimer = setTimeout(() => { 38 isLongPress = true; ··· 45 clearTimeout(longPressTimer); 46 longPressTimer = null; 47 } 48 + touchActive = false; 49 } 50 51 function handleClick(e: MouseEvent) { 52 if (isLongPress) { 53 e.preventDefault(); 54 isLongPress = false; 55 + return; 56 + } 57 + 58 + // Shift-click opens QR modal 59 + if (e.shiftKey && !params.disabled) { 60 + e.preventDefault(); 61 + openModal?.(getHref(), params.context ?? {}); 62 } 63 } 64 65 + function handleContextMenu(e: Event) { 66 + // Prevent context menu during touch to avoid iOS preview 67 + if (touchActive || isLongPress) { 68 + e.preventDefault(); 69 + } 70 } 71 72 node.addEventListener('pointerdown', startLongPress); ··· 88 node.removeEventListener('click', handleClick); 89 node.removeEventListener('contextmenu', handleContextMenu); 90 cancelLongPress(); 91 + // Restore original style 92 + if (originalCallout) { 93 + node.style.setProperty('-webkit-touch-callout', originalCallout); 94 + } else { 95 + node.style.removeProperty('-webkit-touch-callout'); 96 + } 97 } 98 }; 99 }