"use client"; import { useState, useRef, useEffect } from 'react'; import { useTranslations } from 'next-intl'; import { useSettingsStore } from '@/stores/settings-store'; import { useConfig } from '@/hooks/use-config'; import { SettingsSection, SettingItem, ToggleSwitch } from './settings-section'; import { Button } from '@/components/ui/button'; import { usePolicyStore } from '@/stores/policy-store'; import { useUpdateStore } from '@/stores/update-store'; import { ExternalLink } from 'lucide-react'; import { cn } from '@/lib/utils'; import { getPathPrefix } from '@/lib/browser-navigation'; import { clearCachedData } from '@/lib/clear-cached-data'; import { SpamSiegeGame } from './spam-siege-game'; const APP_VERSION = process.env.NEXT_PUBLIC_APP_VERSION || "0.0.0"; const GIT_COMMIT = process.env.NEXT_PUBLIC_GIT_COMMIT || "unknown"; function VersionUpdateTag() { const status = useUpdateStore((s) => s.status); const startPolling = useUpdateStore((s) => s.startPolling); useEffect(() => { startPolling(); }, [startPolling]); if (!status?.updateAvailable) return null; if (status.severity === 'unknown' || status.severity === 'none') return null; const important = status.severity === 'security' || status.severity === 'deprecated'; const label = status.severity === 'security' ? 'security' : status.severity === 'deprecated' ? 'deprecated' : status.latest ?? 'update'; return ( {important ? label : `update: ${label}`} ); } export function AboutDataSettings() { const t = useTranslations('settings.advanced'); const tCommon = useTranslations('common'); const { settingsSyncDisabled, updateSetting, resetToDefaults, exportSettings, importSettings } = useSettingsStore(); const { settingsSyncEnabled } = useConfig(); const [showResetConfirm, setShowResetConfirm] = useState(false); const [showRefreshConfirm, setShowRefreshConfirm] = useState(false); const fileInputRef = useRef(null); const { isFeatureEnabled } = usePolicyStore(); const [showGame, setShowGame] = useState(false); const logoClickCount = useRef(0); const logoClickTimer = useRef | null>(null); const handleLogoClick = () => { logoClickCount.current++; if (logoClickTimer.current) clearTimeout(logoClickTimer.current); if (logoClickCount.current >= 3) { logoClickCount.current = 0; setShowGame(true); } else { logoClickTimer.current = setTimeout(() => { logoClickCount.current = 0; }, 2000); } }; const handleExport = () => { const settingsJson = exportSettings(); const blob = new Blob([settingsJson], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `webmail-settings-${new Date().toISOString().split('T')[0]}.json`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); }; const handleImport = () => { fileInputRef.current?.click(); }; const handleFileChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; const reader = new FileReader(); reader.onload = (event) => { const json = event.target?.result as string; const success = importSettings(json); if (success) { alert(t('../../settings.import_success')); } else { alert(t('../../settings.import_error')); } }; reader.readAsText(file); }; const handleRefreshCache = () => { if (showRefreshConfirm) { clearCachedData(); // reloads the page } else { setShowRefreshConfirm(true); setTimeout(() => setShowRefreshConfirm(false), 5000); } }; const handleReset = () => { if (showResetConfirm) { resetToDefaults(); setShowResetConfirm(false); alert(t('../../settings.save_success')); } else { setShowResetConfirm(true); setTimeout(() => setShowResetConfirm(false), 5000); } }; return ( <> {showGame && setShowGame(false)} />}
GitHub
{settingsSyncEnabled && ( updateSetting('settingsSyncDisabled', !checked)} /> )} {isFeatureEnabled('settingsExportEnabled') && ( )} {isFeatureEnabled('settingsExportEnabled') && ( <> )} ); }