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,34 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
/**
|
||||
* desktop-client — erkennt, ob die Seite im Desktop-Client laeuft
|
||||
* (260917-h2s). Gegenstueck zur Middleware (apps/web/src/middleware.ts,
|
||||
* `withDesktopCookie`): der Rust-Client haengt `desktop=1` an seine erste
|
||||
* Navigation, die Middleware setzt daraufhin das Cookie `tessera_desktop`
|
||||
* auf jede Antwort. `isDesktopClient()` liest das Cookie synchron.
|
||||
*/
|
||||
export const DESKTOP_COOKIE_NAME = 'tessera_desktop';
|
||||
|
||||
export function isDesktopClient(): boolean {
|
||||
if (typeof document === 'undefined') {
|
||||
return false;
|
||||
}
|
||||
return document.cookie
|
||||
.split(';')
|
||||
.some((c) => c.trim() === `${DESKTOP_COOKIE_NAME}=1`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook statt direktem Aufruf beim Render: `isDesktopClient()` synchron im
|
||||
* ersten Render zu nutzen wuerde Server-HTML (kein `document`) und den
|
||||
* ersten Client-Render auseinanderlaufen lassen -- Hydration-Fehler. Der
|
||||
* `useEffect` gleicht das an; `useState(false)` haelt Server- und
|
||||
* Erst-Render-Ergebnis identisch.
|
||||
*/
|
||||
export function useIsDesktopClient(): boolean {
|
||||
const [isDesktop, setIsDesktop] = useState(false);
|
||||
useEffect(() => {
|
||||
setIsDesktop(isDesktopClient());
|
||||
}, []);
|
||||
return isDesktop;
|
||||
}
|
||||
Reference in New Issue
Block a user