import React, { useState, useRef, useEffect } from 'react'; import ToggleSwitch from './ToggleSwitch'; import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd'; import { Server, Wallpaper } from '../types'; import Dropdown from './Dropdown'; import { baseWallpapers } from './utils/baseWallpapers'; import { addWallpaperToChromeStorageLocal, removeWallpaperFromChromeStorageLocal, checkChromeStorageLocalAvailable } from './utils/StorageLocalManager'; interface ConfigurationModalProps { onClose: () => void; onSave: (config: any) => void; currentConfig: any; onWallpaperChange: (newConfig: Partial) => void; } const ConfigurationModal: React.FC = ({ onClose, onSave, currentConfig, onWallpaperChange }) => { const [config, setConfig] = useState({ ...currentConfig, titleSize: currentConfig.titleSize || 'medium', subtitleSize: currentConfig.subtitleSize || 'medium', alignment: currentConfig.alignment || 'middle', tileSize: currentConfig.tileSize || 'medium', horizontalAlignment: currentConfig.horizontalAlignment || 'middle', wallpaperBlur: currentConfig.wallpaperBlur || 0, wallpaperBrightness: currentConfig.wallpaperBrightness || 100, wallpaperOpacity: currentConfig.wallpaperOpacity || 100, serverWidget: { enabled: false, pingFrequency: 15, servers: [], ...currentConfig.serverWidget, }, clock: { enabled: true, size: 'medium', font: 'Helvetica', format: 'h:mm A', ...currentConfig.clock, }, currentWallpapers: Array.isArray(currentConfig.currentWallpapers) ? currentConfig.currentWallpapers.filter((name: string) => typeof name === 'string') : [], wallpaperFrequency: currentConfig.wallpaperFrequency || '1d', }); const [activeTab, setActiveTab] = useState('general'); const [newServerName, setNewServerName] = useState(''); const [newServerAddress, setNewServerAddress] = useState(''); const [newWallpaperName, setNewWallpaperName] = useState(''); const [newWallpaperUrl, setNewWallpaperUrl] = useState(''); const [userWallpapers, setUserWallpapers] = useState([]); const [chromeStorageAvailable, setChromeStorageAvailable] = useState(false); const menuRef = useRef(null); const fileInputRef = useRef(null); const isSaving = useRef(false); const [isVisible, setIsVisible] = useState(false); useEffect(() => { setChromeStorageAvailable(checkChromeStorageLocalAvailable()); const storedUserWallpapers = localStorage.getItem('userWallpapers'); if (storedUserWallpapers) { setUserWallpapers(JSON.parse(storedUserWallpapers)); } }, []); useEffect(() => { const timer = setTimeout(() => { setIsVisible(true); }, 10); return () => clearTimeout(timer); }, []); useEffect(() => { return () => { if (!isSaving.current) { onWallpaperChange({ currentWallpapers: currentConfig.currentWallpapers }); } }; }, []); const handleClose = () => { setIsVisible(false); setTimeout(() => { onClose(); }, 300); }; const handleChange = (e: React.ChangeEvent | { target: { name: string; value: string | string[] } }) => { const { name, value } = e.target; if (name === 'currentWallpapers') { const wallpaperNames = Array.isArray(value) ? value : [value]; setConfig({ ...config, currentWallpapers: wallpaperNames }); } else if (name.startsWith('serverWidget.')) { const field = name.split('.')[1]; setConfig({ ...config, serverWidget: { ...config.serverWidget, [field]: value }, }); } else if (name.startsWith('clock.')) { const field = name.split('.')[1]; setConfig({ ...config, clock: { ...config.clock, [field]: value }, }); } else { setConfig({ ...config, [name]: value }); } }; useEffect(() => { onWallpaperChange({ currentWallpapers: config.currentWallpapers }); // Set wallpaperState in localStorage with lastWallpaperChange datetime localStorage.setItem('wallpaperState', JSON.stringify({ lastWallpaperChange: new Date().toISOString(), currentIndex: 0, })); }, [config.currentWallpapers]); const handleClockToggleChange = (checked: boolean) => { setConfig({ ...config, clock: { ...config.clock, enabled: checked } }); }; const handleServerWidgetToggleChange = (checked: boolean) => { setConfig({ ...config, serverWidget: { ...config.serverWidget, enabled: checked }, }); }; const handleAddServer = () => { if (newServerName.trim() === '' || newServerAddress.trim() === '') return; const newServer: Server = { id: Date.now().toString(), name: newServerName, address: newServerAddress, }; setConfig({ ...config, serverWidget: { ...config.serverWidget, servers: [...config.serverWidget.servers, newServer], }, }); setNewServerName(''); setNewServerAddress(''); }; const handleRemoveServer = (id: string) => { setConfig({ ...config, serverWidget: { ...config.serverWidget, servers: config.serverWidget.servers.filter((server: Server) => server.id !== id), }, }); }; const onDragEnd = (result: any) => { if (!result.destination) return; const items = Array.from(config.serverWidget.servers); const [reorderedItem] = items.splice(result.source.index, 1); items.splice(result.destination.index, 0, reorderedItem); setConfig({ ...config, serverWidget: { ...config.serverWidget, servers: items, }, }); }; const handleAddWallpaper = async () => { if (newWallpaperUrl.trim() === '') return; try { const finalName = await addWallpaperToChromeStorageLocal(newWallpaperName, newWallpaperUrl); const newWallpaper: Wallpaper = { name: finalName }; const updatedUserWallpapers = [...userWallpapers, newWallpaper]; setUserWallpapers(updatedUserWallpapers); localStorage.setItem('userWallpapers', JSON.stringify(updatedUserWallpapers)); setConfig({ ...config, currentWallpapers: [...config.currentWallpapers, newWallpaper.name] }); setNewWallpaperName(''); setNewWallpaperUrl(''); } catch (error) { alert('Error adding wallpaper. Please check the URL and try again.'); console.error(error); } }; const handleFileUpload = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { if (file.size > 4 * 1024 * 1024) { alert('File size exceeds 4MB. Please choose a smaller file.'); return; } const reader = new FileReader(); reader.onload = async () => { const base64 = reader.result as string; if (base64.length > 4.5 * 1024 * 1024) { alert('The uploaded image is too large. Please choose a smaller file.'); return; } try { const finalName = await addWallpaperToChromeStorageLocal(file.name, base64); const newWallpaper: Wallpaper = { name: finalName }; const updatedUserWallpapers = [...userWallpapers, newWallpaper]; setUserWallpapers(updatedUserWallpapers); localStorage.setItem('userWallpapers', JSON.stringify(updatedUserWallpapers)); setConfig({ ...config, currentWallpapers: [...config.currentWallpapers, newWallpaper.name] }); } catch (error) { alert('Error adding wallpaper. Please try again.'); console.error(error); } }; reader.readAsDataURL(file); } }; const handleDeleteUserWallpaper = async (wallpaper: Wallpaper) => { try { await removeWallpaperFromChromeStorageLocal(wallpaper.name); const updatedUserWallpapers = userWallpapers.filter(w => w.name !== wallpaper.name); setUserWallpapers(updatedUserWallpapers); localStorage.setItem('userWallpapers', JSON.stringify(updatedUserWallpapers)); const newcurrentWallpapers = config.currentWallpapers.filter((name: string) => name !== wallpaper.name); const newConfig = { ...config, currentWallpapers: newcurrentWallpapers }; setConfig(newConfig); onWallpaperChange({ currentWallpapers: newcurrentWallpapers }); } catch (error) { alert('Error deleting wallpaper. Please try again.'); console.error(error); } }; const allWallpapers = [...baseWallpapers, ...userWallpapers]; return (

Configuration

{activeTab === 'general' && (
)} {activeTab === 'theme' && (
({ value: w.name, label: w.name }))} />
{Array.isArray(config.currentWallpapers) && config.currentWallpapers.length > 1 && (
)}
{config.wallpaperBlur}px
{config.wallpaperBrightness}%
{config.wallpaperOpacity}%
{chromeStorageAvailable && ( <>

User Wallpapers

{userWallpapers.map((wallpaper) => (
{wallpaper.name}
))}

Add New Wallpaper

setNewWallpaperName(e.target.value)} className="bg-white/10 p-2 rounded-lg w-full focus:outline-none focus:ring-2 focus:ring-cyan-400" />
setNewWallpaperUrl(e.target.value)} className="bg-white/10 p-2 rounded-lg w-full focus:outline-none focus:ring-2 focus:ring-cyan-400" />
)}
)} {activeTab === 'clock' && (
)} {activeTab === 'serverWidget' && (
{config.serverWidget.enabled && ( <>
{config.serverWidget.pingFrequency}s

Servers

{(provided) => (
{config.serverWidget.servers.map((server: Server, index: number) => ( {(provided) => (

{server.name}

{server.address}

)}
))} {provided.placeholder}
)}
setNewServerName(e.target.value)} className="bg-white/10 p-2 rounded-lg w-full focus:outline-none focus:ring-2 focus:ring-cyan-400" /> setNewServerAddress(e.target.value)} className="bg-white/10 p-2 rounded-lg w-full focus:outline-none focus:ring-2 focus:ring-cyan-400" />
)}
)}
); }; export default ConfigurationModal;