// Mode Gate Overlay // Purpose: Defines the Mode Gate Overlay module and the local helpers/components used in this file. // Scope: Keeps behavior unchanged while isolating this concern into a clear, single-responsibility unit. import { useMemo } from 'react'; import AuthPanel from '../AuthPanel/index.jsx'; import { useSessionSelector } from '../../context/SessionContext.jsx'; import { useSharedClock } from '../../hooks/useSharedClock.js'; import SocialButton from '../SocialButton/index.jsx'; import ChatPanel from '../ChatPanel/index.jsx'; import InterInstancePanel from '../InterInstancePanel/index.jsx'; import { isFeatureEnabled } from '../../lib/features.js'; const PRIVILEGED_ROLES = new Set(['admin', 'lockdown']); const LOCKDOWN_ROLES = new Set(['lockdown']); const RESTRICTED_MODES = new Set(['admin', 'lockdown']); function getModeDetails(mode = 'admin') { if (mode === 'lockdown') { return { title: 'Lockdown mode active', description: 'Only the server owners can access the interface at this time.', }; } return { title: 'Admin mode active', // description: // 'The server is currently in admin mode. Only admins can access the interface.', }; } export default function ModeGateOverlay() { const mode = useSessionSelector((state) => state.session?.mode || null); const role = useSessionSelector((state) => state.session?.role || null); const reason = useSessionSelector((state) => state.session?.adminReason?.text || ''); const timezone = useSessionSelector((state) => state.session?.timezone || 'UTC'); const interInstanceEnabled = useSessionSelector((state) => isFeatureEnabled(state, 'interInstance')); const restricted = RESTRICTED_MODES.has(mode); const privileged = mode === 'lockdown' ? LOCKDOWN_ROLES.has(role) : PRIVILEGED_ROLES.has(role); /* The overlay is mounted for the whole app, but the server-time display is only visible while access is actually blocked. Gating the shared clock here prevents the hidden overlay from registering a permanent interval. */ const nowMs = useSharedClock(1000, restricted && !privileged); const serverTime = useMemo(() => { const now = new Date(nowMs); try { return new Intl.DateTimeFormat('en-US', { timeZone: timezone, hour: 'numeric', minute: '2-digit', second: '2-digit', }).format(now); } catch { return now.toLocaleTimeString(); } }, [nowMs, timezone]); if (!restricted || privileged) { return null; } const details = getModeDetails(mode); return (
{details.title}
{details.description}
Reason for locking:
{reason ? reason : 'No reason set.'}
Server time: {serverTime}
Your controls are paused until access is granted. You will automatically regain the interface once the mode changes or after a successful login.
*/}