'use client'; import { usePathname } from 'next/navigation'; import { lazy, Suspense, useEffect, useRef, useState } from 'react'; import type { ReleaseNotice } from '@/lib/release-notes'; import { fetchReleaseNotice, markReleaseSeenAction } from '@/lib/release-notice-actions'; /** * Laedt das "Was ist neu"-Fenster einmal je Seitenladung im Portal-Rahmen * (quick-260925-bow, D-03/D-05/D-08). * * Eingebunden nur in `AppShell` — die Anmeldeseite liegt im `(auth)`-Layout * ohne AppShell, der Erststart-Dialog der Desktop-App ist die lokale * `apps/desktop/src/setup.html` vor dem Portal. Auf `/change-password` * (liegt im Portal-Rahmen, Pflicht-Passwortwechsel) wird nicht abgefragt; * erst die naechste Seite danach fragt. Eine Ref-Sperre verhindert einen * zweiten Abruf (StrictMode-Doppeleffekt, Seitenwechsel ohne Neuladen). * * Gemerkt wird erst beim Schliessen, nie beim Oeffnen: zuerst verschwindet * das Fenster, dann geht `markReleaseSeenAction` an die API. Schlaegt das * Merken fehl, erscheint das Fenster beim naechsten Laden erneut — gewollt, * statt die Nachricht stumm zu verlieren. * * Das Fenster (mit dem Markdown-Renderer) wird per `React.lazy` nur geladen, * wenn wirklich eine Nachricht da ist. */ const ReleaseNoticeDialog = lazy(() => import('./release-notice-dialog').then((mod) => ({ default: mod.ReleaseNoticeDialog })), ); export function ReleaseNoticeHost() { const pathname = usePathname(); const [notice, setNotice] = useState(null); const requestedRef = useRef(false); useEffect(() => { if (requestedRef.current) return; if (pathname?.startsWith('/change-password')) return; requestedRef.current = true; // Bewusst ohne Abbruch-Flag im Aufraeumen: der StrictMode-Doppeleffekt // raeumt nach dem ersten Lauf auf, der zweite Lauf fragt wegen der Sperre // nicht erneut — ein Flag wuerde das einzige Ergebnis verwerfen. fetchReleaseNotice() .then((result) => { if (result) setNotice(result); }) .catch(() => { // Still: ohne Nachricht kein Fenster. }); }, [pathname]); if (!notice) return null; const handleClose = () => { const version = notice.currentRelease; setNotice(null); void markReleaseSeenAction(version).catch(() => { // Still: das Fenster erscheint beim naechsten Laden erneut. }); }; return ( ); }