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
|
* Maus/Touch/Stift), inklusive Lang-Drücken zum Start (350ms), damit
|
||||||
* normales Scrollen nicht versehentlich als Ziehen interpretiert wird.
|
* 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,
|
* Signatur-Element: der Wallpaper-Hintergrund besteht aus den tatsächlichen,
|
||||||
* in den eigenen Kategorien hinterlegten Farben (Admin -> Kategorien).
|
* in den eigenen Kategorien hinterlegten Farben (Admin -> Kategorien).
|
||||||
*/
|
*/
|
||||||
@@ -137,7 +149,10 @@ function TileIcon({ favicon, label, size = "normal", dimmed }: TileVisualProps)
|
|||||||
<img
|
<img
|
||||||
src={resolveIconSrc(favicon)}
|
src={resolveIconSrc(favicon)}
|
||||||
alt=""
|
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)}
|
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"
|
className="flex items-center justify-center overflow-hidden rounded-md bg-white/70 dark:bg-white/10"
|
||||||
>
|
>
|
||||||
{item?.favicon ? (
|
{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 ? (
|
) : item ? (
|
||||||
<span className="text-[8px] font-semibold text-black/50">{item.label.charAt(0).toUpperCase()}</span>
|
<span className="text-[8px] font-semibold text-black/50">{item.label.charAt(0).toUpperCase()}</span>
|
||||||
) : null}
|
) : null}
|
||||||
@@ -304,6 +324,11 @@ export function MobileAndroidHome({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e.pointerId !== drag.pointerId) 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));
|
setDrag((d) => (d ? { ...d, x: e.clientX, y: e.clientY } : d));
|
||||||
|
|
||||||
const el = document.elementFromPoint(e.clientX, e.clientY);
|
const el = document.elementFromPoint(e.clientX, e.clientY);
|
||||||
@@ -401,7 +426,9 @@ export function MobileAndroidHome({
|
|||||||
onPointerMove={handlePointerMove}
|
onPointerMove={handlePointerMove}
|
||||||
onPointerUp={handlePointerUp}
|
onPointerUp={handlePointerUp}
|
||||||
onPointerCancel={handlePointerCancel}
|
onPointerCancel={handlePointerCancel}
|
||||||
|
onContextMenu={(e) => e.preventDefault()}
|
||||||
onClick={() => handleTileClick(() => setOpenFolderId(slot.id))}
|
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`}
|
className={`flex flex-col items-center gap-1.5 ${isHoverTarget ? "scale-110" : ""} transition-transform`}
|
||||||
>
|
>
|
||||||
<FolderTile icons={icons} dimmed={isDragging} />
|
<FolderTile icons={icons} dimmed={isDragging} />
|
||||||
@@ -424,7 +451,9 @@ export function MobileAndroidHome({
|
|||||||
onPointerMove={handlePointerMove}
|
onPointerMove={handlePointerMove}
|
||||||
onPointerUp={handlePointerUp}
|
onPointerUp={handlePointerUp}
|
||||||
onPointerCancel={handlePointerCancel}
|
onPointerCancel={handlePointerCancel}
|
||||||
|
onContextMenu={(e) => e.preventDefault()}
|
||||||
onClick={() => handleTileClick(() => onOpen({ url: item.url, id: item.id, kind: item.type }))}
|
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`}
|
className={`flex flex-col items-center gap-1.5 ${isHoverTarget ? "scale-110" : ""} transition-transform`}
|
||||||
>
|
>
|
||||||
<TileIcon favicon={item.favicon} label={item.displayName} dimmed={isDragging} />
|
<TileIcon favicon={item.favicon} label={item.displayName} dimmed={isDragging} />
|
||||||
|
|||||||
Reference in New Issue
Block a user