mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-21 14:36:31 +00:00
f0877a2e7d
The 3.0 "what's new" notices have served their purpose, so swap them for a single thank-you notice that comes back once on every fresh install and version bump. It carries Buy Me a Coffee and Ko-fi buttons and only shows on desktop. Adds a per-version recurring mode (new dismissed_app_version column) plus external-link CTAs to support it; the 3.0.14 whitespace-collision admin notice stays active.
51 lines
1.8 KiB
TypeScript
51 lines
1.8 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { useSystemNoticeStore } from '../../store/systemNoticeStore.js';
|
|
import { ModalRenderer } from './SystemNoticeModal.js';
|
|
import { BannerRenderer, ToastRenderer } from './SystemNoticeBanner.js';
|
|
|
|
// Mobile breakpoint matches the modal sheet's (max-width: 639px).
|
|
function useIsMobile() {
|
|
const [isMobile, setIsMobile] = useState(
|
|
() => typeof window !== 'undefined' && (window.matchMedia?.('(max-width: 639px)')?.matches ?? false)
|
|
);
|
|
useEffect(() => {
|
|
const mq = window.matchMedia?.('(max-width: 639px)');
|
|
if (!mq) return;
|
|
const handler = (e: MediaQueryListEvent) => setIsMobile(e.matches);
|
|
mq.addEventListener('change', handler);
|
|
return () => mq.removeEventListener('change', handler);
|
|
}, []);
|
|
return isMobile;
|
|
}
|
|
|
|
export function SystemNoticeHost() {
|
|
const { notices, loaded } = useSystemNoticeStore();
|
|
const isMobile = useIsMobile();
|
|
|
|
// Notices are fetched by authStore after login (see App.tsx / authStore modification).
|
|
// Cold-session fetch (page reload with valid session) is triggered here:
|
|
useEffect(() => {
|
|
// Only fetch if not already loaded (authStore may have already triggered)
|
|
if (!loaded) {
|
|
useSystemNoticeStore.getState().fetch();
|
|
}
|
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
|
|
if (!loaded) return null;
|
|
|
|
// desktopOnly notices (e.g. the thank-you/support modal) are hidden on mobile.
|
|
const visible = isMobile ? notices.filter(n => !n.desktopOnly) : notices;
|
|
|
|
const modals = visible.filter(n => n.display === 'modal');
|
|
const banners = visible.filter(n => n.display === 'banner');
|
|
const toasts = visible.filter(n => n.display === 'toast');
|
|
|
|
return (
|
|
<>
|
|
<BannerRenderer notices={banners} />
|
|
<ModalRenderer notices={modals} />
|
|
<ToastRenderer notices={toasts} />
|
|
</>
|
|
);
|
|
}
|