From 5af1f14a0b436ce9caa93b31cdbc0a4f086a53eb Mon Sep 17 00:00:00 2001 From: Gigi Date: Wed, 15 Oct 2025 18:49:25 +0200 Subject: [PATCH] refactor: merge PWA and Flight Mode settings into single section --- src/components/Settings.tsx | 4 +- .../Settings/OfflineModeSettings.tsx | 173 ------------------ src/components/Settings/PWASettings.tsx | 170 ++++++++++++++++- 3 files changed, 167 insertions(+), 180 deletions(-) delete mode 100644 src/components/Settings/OfflineModeSettings.tsx diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index 44f823ec..038a4fd6 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -9,7 +9,6 @@ import ReadingDisplaySettings from './Settings/ReadingDisplaySettings' import LayoutNavigationSettings from './Settings/LayoutNavigationSettings' import StartupPreferencesSettings from './Settings/StartupPreferencesSettings' import ZapSettings from './Settings/ZapSettings' -import OfflineModeSettings from './Settings/OfflineModeSettings' import RelaySettings from './Settings/RelaySettings' import PWASettings from './Settings/PWASettings' import { useRelayStatus } from '../hooks/useRelayStatus' @@ -166,8 +165,7 @@ const Settings: React.FC = ({ settings, onSave, onClose, relayPoo - - + diff --git a/src/components/Settings/OfflineModeSettings.tsx b/src/components/Settings/OfflineModeSettings.tsx deleted file mode 100644 index 868b010e..00000000 --- a/src/components/Settings/OfflineModeSettings.tsx +++ /dev/null @@ -1,173 +0,0 @@ -import React, { useState, useEffect } from 'react' -import { useNavigate } from 'react-router-dom' -import { faTrash } from '@fortawesome/free-solid-svg-icons' -import { UserSettings } from '../../services/settingsService' -import { getImageCacheStatsAsync, clearImageCache } from '../../services/imageCacheService' -import IconButton from '../IconButton' - -interface OfflineModeSettingsProps { - settings: UserSettings - onUpdate: (updates: Partial) => void - onClose?: () => void -} - -const OfflineModeSettings: React.FC = ({ settings, onUpdate, onClose }) => { - const navigate = useNavigate() - const [cacheStats, setCacheStats] = useState<{ - totalSizeMB: number - itemCount: number - items: Array<{ url: string, sizeMB: number }> - }>({ totalSizeMB: 0, itemCount: 0, items: [] }) - - const handleLinkClick = (url: string) => { - if (onClose) onClose() - navigate(`/r/${encodeURIComponent(url)}`) - } - - const handleClearCache = async () => { - if (confirm('Are you sure you want to clear all cached images?')) { - await clearImageCache() - const stats = await getImageCacheStatsAsync() - setCacheStats(stats) - } - } - - // Update cache stats periodically - useEffect(() => { - const updateStats = async () => { - const stats = await getImageCacheStatsAsync() - setCacheStats(stats) - } - - updateStats() // Initial load - const interval = setInterval(updateStats, 3000) // Update every 3 seconds - return () => clearInterval(interval) - }, []) - - return ( -
-

Flight Mode

- -
- - - {(settings.enableImageCache ?? true) && ( -
- - ( {cacheStats.totalSizeMB.toFixed(1)} MB / - onUpdate({ imageCacheSizeMB: parseInt(e.target.value) || 210 })} - style={{ - width: '50px', - padding: '0.15rem 0.35rem', - background: 'var(--surface-secondary)', - border: '1px solid var(--border-color, #333)', - borderRadius: '4px', - color: 'inherit', - fontSize: 'inherit', - fontFamily: 'inherit', - textAlign: 'center' - }} - /> - MB used ) - - -
- )} -
- -
- -
- - -
- ) -} - -export default OfflineModeSettings - diff --git a/src/components/Settings/PWASettings.tsx b/src/components/Settings/PWASettings.tsx index a29484dc..989d6128 100644 --- a/src/components/Settings/PWASettings.tsx +++ b/src/components/Settings/PWASettings.tsx @@ -1,10 +1,26 @@ -import React from 'react' -import { faDownload, faCheckCircle, faMobileAlt } from '@fortawesome/free-solid-svg-icons' +import React, { useState, useEffect } from 'react' +import { useNavigate } from 'react-router-dom' +import { faDownload, faCheckCircle, faMobileAlt, faTrash } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { usePWAInstall } from '../../hooks/usePWAInstall' +import { UserSettings } from '../../services/settingsService' +import { getImageCacheStatsAsync, clearImageCache } from '../../services/imageCacheService' +import IconButton from '../IconButton' -const PWASettings: React.FC = () => { +interface PWASettingsProps { + settings: UserSettings + onUpdate: (updates: Partial) => void + onClose?: () => void +} + +const PWASettings: React.FC = ({ settings, onUpdate, onClose }) => { + const navigate = useNavigate() const { isInstallable, isInstalled, installApp } = usePWAInstall() + const [cacheStats, setCacheStats] = useState<{ + totalSizeMB: number + itemCount: number + items: Array<{ url: string, sizeMB: number }> + }>({ totalSizeMB: 0, itemCount: 0, items: [] }) const handleInstall = async () => { if (isInstalled) return @@ -14,13 +30,40 @@ const PWASettings: React.FC = () => { } } + const handleLinkClick = (url: string) => { + if (onClose) onClose() + navigate(`/r/${encodeURIComponent(url)}`) + } + + const handleClearCache = async () => { + if (confirm('Are you sure you want to clear all cached images?')) { + await clearImageCache() + const stats = await getImageCacheStatsAsync() + setCacheStats(stats) + } + } + + // Update cache stats periodically + useEffect(() => { + const updateStats = async () => { + const stats = await getImageCacheStatsAsync() + setCacheStats(stats) + } + + updateStats() // Initial load + const interval = setInterval(updateStats, 3000) // Update every 3 seconds + return () => clearInterval(interval) + }, []) + if (!isInstallable && !isInstalled) { return null } return (
-

App

+

PWA & Flight Mode

+ + {/* PWA Install Section */}
@@ -46,6 +89,125 @@ const PWASettings: React.FC = () => { style={{ width: '120px', height: 'auto', flexShrink: 0, opacity: 0.8 }} />
+ + {/* Flight Mode Section */} +
+ + + {(settings.enableImageCache ?? true) && ( +
+ + ( {cacheStats.totalSizeMB.toFixed(1)} MB / + onUpdate({ imageCacheSizeMB: parseInt(e.target.value) || 210 })} + style={{ + width: '50px', + padding: '0.15rem 0.35rem', + background: 'var(--surface-secondary)', + border: '1px solid var(--border-color, #333)', + borderRadius: '4px', + color: 'inherit', + fontSize: 'inherit', + fontFamily: 'inherit', + textAlign: 'center' + }} + /> + MB used ) + + +
+ )} +
+ +
+ +
+ +
) }