generated from Dicken/dickendock
round66: Natives Kontextmenue beim Lang-Druecken auf Icons unterdrueckt (verhinderte bisher das Drag-and-Drop)
This commit is contained in:
@@ -30,6 +30,18 @@ import { useHomeLayout, type HomeSlot, type ItemRef } from "../hooks/useHomeLayo
|
||||
* Maus/Touch/Stift), inklusive Lang-Drücken zum Start (350ms), damit
|
||||
* normales Scrollen nicht versehentlich als Ziehen interpretiert wird.
|
||||
*
|
||||
* Zusätzlich: mobile Browser fangen ein Lang-Drücken auf einem <img> (bzw.
|
||||
* dem umgebenden Element) standardmäßig SELBST ab und zeigen ihr eigenes
|
||||
* Kontextmenü ("Bild speichern"/"Bild kopieren" usw.), noch bevor unser
|
||||
* eigener Drag-Timer greift (siehe Bugreport). Dagegen: draggable={false} +
|
||||
* pointer-events-none auf den <img>-Tags (Touch-Events landen dadurch immer
|
||||
* auf dem umgebenden <button>), -webkit-touch-callout:none (unterdrückt das
|
||||
* iOS-Kontextmenü), onContextMenu-preventDefault (unterdrückt das
|
||||
* Android-Pendant) sowie touch-action:manipulation an den Kacheln kombiniert
|
||||
* mit einem gezielten preventDefault() in handlePointerMove NUR während
|
||||
* eines aktiven Drags (normales Scrollen bleibt dadurch möglich, wenn gerade
|
||||
* nicht gezogen wird).
|
||||
*
|
||||
* Signatur-Element: der Wallpaper-Hintergrund besteht aus den tatsächlichen,
|
||||
* in den eigenen Kategorien hinterlegten Farben (Admin -> Kategorien).
|
||||
*/
|
||||
@@ -137,7 +149,10 @@ function TileIcon({ favicon, label, size = "normal", dimmed }: TileVisualProps)
|
||||
<img
|
||||
src={resolveIconSrc(favicon)}
|
||||
alt=""
|
||||
className={size === "small" ? "h-5 w-5 object-contain" : "h-8 w-8 object-contain"}
|
||||
draggable={false}
|
||||
className={`pointer-events-none select-none [-webkit-touch-callout:none] ${
|
||||
size === "small" ? "h-5 w-5" : "h-8 w-8"
|
||||
} object-contain`}
|
||||
onError={() => setFailed(true)}
|
||||
/>
|
||||
) : (
|
||||
@@ -164,7 +179,12 @@ function FolderTile({ icons, dimmed }: { icons: Array<{ favicon: string | null;
|
||||
className="flex items-center justify-center overflow-hidden rounded-md bg-white/70 dark:bg-white/10"
|
||||
>
|
||||
{item?.favicon ? (
|
||||
<img src={resolveIconSrc(item.favicon)} alt="" className="h-full w-full object-contain p-0.5" />
|
||||
<img
|
||||
src={resolveIconSrc(item.favicon)}
|
||||
alt=""
|
||||
draggable={false}
|
||||
className="pointer-events-none h-full w-full select-none object-contain p-0.5 [-webkit-touch-callout:none]"
|
||||
/>
|
||||
) : item ? (
|
||||
<span className="text-[8px] font-semibold text-black/50">{item.label.charAt(0).toUpperCase()}</span>
|
||||
) : null}
|
||||
@@ -304,6 +324,11 @@ export function MobileAndroidHome({
|
||||
return;
|
||||
}
|
||||
if (e.pointerId !== drag.pointerId) return;
|
||||
// Solange aktiv gezogen wird, das native Scrollen unterdrücken (siehe
|
||||
// touch-action: manipulation an den Kacheln - das erlaubt normales
|
||||
// Scrollen, WENN nicht gezogen wird, verhindert aber, dass die Seite
|
||||
// während des Ziehens selbst "wegscrollt").
|
||||
e.preventDefault();
|
||||
setDrag((d) => (d ? { ...d, x: e.clientX, y: e.clientY } : d));
|
||||
|
||||
const el = document.elementFromPoint(e.clientX, e.clientY);
|
||||
@@ -401,7 +426,9 @@ export function MobileAndroidHome({
|
||||
onPointerMove={handlePointerMove}
|
||||
onPointerUp={handlePointerUp}
|
||||
onPointerCancel={handlePointerCancel}
|
||||
onContextMenu={(e) => e.preventDefault()}
|
||||
onClick={() => handleTileClick(() => setOpenFolderId(slot.id))}
|
||||
style={{ touchAction: "manipulation", WebkitTouchCallout: "none", WebkitUserSelect: "none", userSelect: "none" }}
|
||||
className={`flex flex-col items-center gap-1.5 ${isHoverTarget ? "scale-110" : ""} transition-transform`}
|
||||
>
|
||||
<FolderTile icons={icons} dimmed={isDragging} />
|
||||
@@ -424,7 +451,9 @@ export function MobileAndroidHome({
|
||||
onPointerMove={handlePointerMove}
|
||||
onPointerUp={handlePointerUp}
|
||||
onPointerCancel={handlePointerCancel}
|
||||
onContextMenu={(e) => e.preventDefault()}
|
||||
onClick={() => handleTileClick(() => onOpen({ url: item.url, id: item.id, kind: item.type }))}
|
||||
style={{ touchAction: "manipulation", WebkitTouchCallout: "none", WebkitUserSelect: "none", userSelect: "none" }}
|
||||
className={`flex flex-col items-center gap-1.5 ${isHoverTarget ? "scale-110" : ""} transition-transform`}
|
||||
>
|
||||
<TileIcon favicon={item.favicon} label={item.displayName} dimmed={isDragging} />
|
||||
|
||||
Reference in New Issue
Block a user