feat(web): Desktop-Client per Cookie erkennen — Download-Links und Browser-Kontextmenü in der App aus
- withDesktopCookie in middleware.ts setzt tessera_desktop=1 auf JEDER Antwort (Fruehausstieg, Redirects, next()), wenn ?desktop=1 anliegt - desktop-client.ts: isDesktopClient() liest das Cookie, useIsDesktopClient() kapselt es hydration-sicher per useEffect - DesktopDownloadLinks fragt /desktop/latest im Desktop-Client gar nicht erst an und rendert nichts - DesktopContextMenuGuard unterdrueckt das WebView2-Kontextmenue ausserhalb von Eingabefeldern/contenteditable, in layout.tsx eingebunden - middleware.test.ts (neu), desktop-client.test.ts (neu), desktop-context-menu-guard.test.tsx (neu), Test 4 in desktop-download-links.test.tsx — alle 417 Web-Tests und type-check gruen Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { useIsDesktopClient } from '@/lib/desktop-client';
|
||||
|
||||
/**
|
||||
* DesktopContextMenuGuard (260917-h2s) — unterdrueckt das
|
||||
* WebView2-Browser-Kontextmenue (Zurueck, Aktualisieren, Speichern unter,
|
||||
* Drucken …) im Desktop-Client; in Eingabefeldern und contenteditable-
|
||||
* Bereichen bleibt es erhalten, damit Kopieren/Einfuegen erreichbar bleibt.
|
||||
* jsdom kennt `isContentEditable` nicht -- deshalb zusaetzlich der Selektor.
|
||||
*/
|
||||
const EDITABLE_SELECTOR =
|
||||
'input, textarea, select, [contenteditable=""], [contenteditable="true"], [contenteditable="plaintext-only"]';
|
||||
|
||||
export function DesktopContextMenuGuard() {
|
||||
const isDesktop = useIsDesktopClient();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDesktop) return;
|
||||
|
||||
const handler = (event: MouseEvent) => {
|
||||
const target = event.target;
|
||||
if (!(target instanceof Element)) return;
|
||||
if (target.closest(EDITABLE_SELECTOR) || (target as HTMLElement).isContentEditable === true) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
document.addEventListener('contextmenu', handler);
|
||||
return () => {
|
||||
document.removeEventListener('contextmenu', handler);
|
||||
};
|
||||
}, [isDesktop]);
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user