Compare commits
	
		
			2 Commits
		
	
	
		
			ffdaf06d55
			...
			2849ed3bb2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2849ed3bb2 | |||
| f1c1b0c6c6 | 
							
								
								
									
										30
									
								
								App.tsx
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								App.tsx
									
									
									
									
									
								
							@@ -94,7 +94,8 @@ const App: React.FC = () => {
 | 
				
			|||||||
    const updateWallpaper = () => {
 | 
					    const updateWallpaper = () => {
 | 
				
			||||||
      const availableWallpapers = allWallpapers.filter(w => config.backgroundUrls.includes(w.url || w.base64));
 | 
					      const availableWallpapers = allWallpapers.filter(w => config.backgroundUrls.includes(w.url || w.base64));
 | 
				
			||||||
      if (availableWallpapers.length > 0) {
 | 
					      if (availableWallpapers.length > 0) {
 | 
				
			||||||
        const currentIndex = availableWallpapers.findIndex(w => (w.url || w.base64) === wallpaperState.current);
 | 
					        const currentWallpaperFromState = allWallpapers.find(w => w.name === wallpaperState.current);
 | 
				
			||||||
 | 
					        const currentIndex = currentWallpaperFromState ? availableWallpapers.findIndex(w => w.name === currentWallpaperFromState.name) : -1;
 | 
				
			||||||
        const nextIndex = (currentIndex + 1) % availableWallpapers.length;
 | 
					        const nextIndex = (currentIndex + 1) % availableWallpapers.length;
 | 
				
			||||||
        const newWallpaper = availableWallpapers[nextIndex];
 | 
					        const newWallpaper = availableWallpapers[nextIndex];
 | 
				
			||||||
        const newWallpaperUrl = newWallpaper.url || newWallpaper.base64;
 | 
					        const newWallpaperUrl = newWallpaper.url || newWallpaper.base64;
 | 
				
			||||||
@@ -102,24 +103,20 @@ const App: React.FC = () => {
 | 
				
			|||||||
        localStorage.setItem('wallpaperState', JSON.stringify({ current: newWallpaper.name, lastChanged: new Date().toISOString() }));
 | 
					        localStorage.setItem('wallpaperState', JSON.stringify({ current: newWallpaper.name, lastChanged: new Date().toISOString() }));
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        setCurrentWallpaper('');
 | 
					        setCurrentWallpaper('');
 | 
				
			||||||
 | 
					        localStorage.removeItem('wallpaperState');
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (Date.now() - lastChanged > frequency) {
 | 
					    const currentWallpaperDetails = allWallpapers.find(w => w.name === wallpaperState.current);
 | 
				
			||||||
 | 
					    const isCurrentWallpaperValid = currentWallpaperDetails && config.backgroundUrls.includes(currentWallpaperDetails.url || currentWallpaperDetails.base64 || '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!isCurrentWallpaperValid || Date.now() - lastChanged > frequency) {
 | 
				
			||||||
      updateWallpaper();
 | 
					      updateWallpaper();
 | 
				
			||||||
 | 
					    } else if (currentWallpaperDetails) {
 | 
				
			||||||
 | 
					      setCurrentWallpaper(currentWallpaperDetails.url || currentWallpaperDetails.base64 || '');
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      const currentWallpaperName = wallpaperState.current;
 | 
					      // Fallback for when there's no valid wallpaper state
 | 
				
			||||||
      const wallpaper = allWallpapers.find(w => w.name === currentWallpaperName);
 | 
					      updateWallpaper();
 | 
				
			||||||
      if (wallpaper) {
 | 
					 | 
				
			||||||
        setCurrentWallpaper(wallpaper.url || wallpaper.base64 || '');
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        const firstWallpaperUrl = config.backgroundUrls[0] || '';
 | 
					 | 
				
			||||||
        const firstWallpaper = allWallpapers.find(w => (w.url || w.base64) === firstWallpaperUrl);
 | 
					 | 
				
			||||||
        setCurrentWallpaper(firstWallpaperUrl);
 | 
					 | 
				
			||||||
        if (firstWallpaper) {
 | 
					 | 
				
			||||||
          localStorage.setItem('wallpaperState', JSON.stringify({ current: firstWallpaper.name, lastChanged: new Date().toISOString() }));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }, [config.backgroundUrls, config.wallpaperFrequency, allWallpapers]);
 | 
					  }, [config.backgroundUrls, config.wallpaperFrequency, allWallpapers]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -133,6 +130,10 @@ const App: React.FC = () => {
 | 
				
			|||||||
    setIsConfigModalOpen(false);
 | 
					    setIsConfigModalOpen(false);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const handleWallpaperChange = (newConfig: Partial<Config>) => {
 | 
				
			||||||
 | 
					    setConfig(prev => ({ ...prev, ...newConfig }));
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const handleSaveWebsite = (website: Partial<Website>) => {
 | 
					  const handleSaveWebsite = (website: Partial<Website>) => {
 | 
				
			||||||
    if (editingWebsite) {
 | 
					    if (editingWebsite) {
 | 
				
			||||||
      const newCategories = categories.map(category => ({
 | 
					      const newCategories = categories.map(category => ({
 | 
				
			||||||
@@ -341,6 +342,7 @@ const App: React.FC = () => {
 | 
				
			|||||||
          currentConfig={config}
 | 
					          currentConfig={config}
 | 
				
			||||||
          onClose={() => setIsConfigModalOpen(false)} 
 | 
					          onClose={() => setIsConfigModalOpen(false)} 
 | 
				
			||||||
          onSave={handleSaveConfig} 
 | 
					          onSave={handleSaveConfig} 
 | 
				
			||||||
 | 
					          onWallpaperChange={handleWallpaperChange}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
      )}
 | 
					      )}
 | 
				
			||||||
    </main>
 | 
					    </main>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										34
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								README.md
									
									
									
									
									
								
							@@ -17,6 +17,38 @@
 | 
				
			|||||||
   `npm run dev`
 | 
					   `npm run dev`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## to-do
 | 
					## to-do
 | 
				
			||||||
* [] Multiple wallpapers
 | 
					* [x] Multiple Wallpapers
 | 
				
			||||||
* [x] Remake icons
 | 
					* [x] Remake icons
 | 
				
			||||||
* [] Increase offline compatibility
 | 
					* [] Increase offline compatibility
 | 
				
			||||||
 | 
					  * Use chrome.storage.local for wallpapers
 | 
				
			||||||
 | 
					  * Use chrome.storage.local for some logos
 | 
				
			||||||
 | 
					    * Some logos have CORS enabled, we can add `"<all_urls>"` to the manifest.json file and cache them on storage local
 | 
				
			||||||
 | 
					* Dynamic Weather Widget
 | 
				
			||||||
 | 
					  * A box with information about the current weather, with manual entry on the location
 | 
				
			||||||
 | 
					  * Display current temperature, weather condition (e.g., "Sunny," "Cloudy"), and a corresponding icon
 | 
				
			||||||
 | 
					  * Optionally, show a 3-day forecast when clicked or hovered
 | 
				
			||||||
 | 
					* Search Bar Widget
 | 
				
			||||||
 | 
					  * Positioned to the right or left side of the clock, display a nice search bar
 | 
				
			||||||
 | 
					  * Behaviour:
 | 
				
			||||||
 | 
					    * When not in focus, it could be highly transparent with just a faint border and a search icon.
 | 
				
			||||||
 | 
					    * When clicked, it would smoothly expand and become slightly more opaque, with a soft glow around the border (similar to the existing ones)
 | 
				
			||||||
 | 
					  * Config to allow changing the default search engine
 | 
				
			||||||
 | 
					* Draggable & Resizable Grid System
 | 
				
			||||||
 | 
					  * Allow users to drag and drop all widgets (Clock, Website Tiles, Weather, Title, etc.) into any position on a grid
 | 
				
			||||||
 | 
					* Notes / Scratchpad Widget
 | 
				
			||||||
 | 
					  * A simple text area that saves its content to local storage automatically.
 | 
				
			||||||
 | 
					  * Maybe some extra formatting (bold, italic, increase font size, etc).
 | 
				
			||||||
 | 
					* Theme-ing
 | 
				
			||||||
 | 
					  * A Light/Dark Mode toggle
 | 
				
			||||||
 | 
					  * Custom Accent Colors
 | 
				
			||||||
 | 
					    * Selection of 6-8 accent colors that are guaranteed to look good with both Light and Dark themes
 | 
				
			||||||
 | 
					    * Define CSS variables for the accent color
 | 
				
			||||||
 | 
					  * Dynamic Wallpaper-Based Theming
 | 
				
			||||||
 | 
					    * Automatically adapt the UI's accent color to match the current wallpaper
 | 
				
			||||||
 | 
					  * Minimal feel toggle
 | 
				
			||||||
 | 
					    * Disable title & subtitle and search widget
 | 
				
			||||||
 | 
					    * Tiles become small stylish lines
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					From a technical side:
 | 
				
			||||||
 | 
					* Refactor everything :(
 | 
				
			||||||
 | 
					* Add small nginx demo (with docker)
 | 
				
			||||||
@@ -10,9 +10,10 @@ interface ConfigurationModalProps {
 | 
				
			|||||||
  onClose: () => void;
 | 
					  onClose: () => void;
 | 
				
			||||||
  onSave: (config: any) => void;
 | 
					  onSave: (config: any) => void;
 | 
				
			||||||
  currentConfig: any;
 | 
					  currentConfig: any;
 | 
				
			||||||
 | 
					  onWallpaperChange: (newConfig: Partial<any>) => void;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ConfigurationModal: React.FC<ConfigurationModalProps> = ({ onClose, onSave, currentConfig }) => {
 | 
					const ConfigurationModal: React.FC<ConfigurationModalProps> = ({ onClose, onSave, currentConfig, onWallpaperChange }) => {
 | 
				
			||||||
  const [config, setConfig] = useState({
 | 
					  const [config, setConfig] = useState({
 | 
				
			||||||
    ...currentConfig,
 | 
					    ...currentConfig,
 | 
				
			||||||
    titleSize: currentConfig.titleSize || 'medium',
 | 
					    titleSize: currentConfig.titleSize || 'medium',
 | 
				
			||||||
@@ -47,6 +48,7 @@ const ConfigurationModal: React.FC<ConfigurationModalProps> = ({ onClose, onSave
 | 
				
			|||||||
  const [userWallpapers, setUserWallpapers] = useState<Wallpaper[]>([]);
 | 
					  const [userWallpapers, setUserWallpapers] = useState<Wallpaper[]>([]);
 | 
				
			||||||
  const menuRef = useRef<HTMLDivElement>(null);
 | 
					  const menuRef = useRef<HTMLDivElement>(null);
 | 
				
			||||||
  const fileInputRef = useRef<HTMLInputElement>(null);
 | 
					  const fileInputRef = useRef<HTMLInputElement>(null);
 | 
				
			||||||
 | 
					  const isSaving = useRef(false);
 | 
				
			||||||
  const [isVisible, setIsVisible] = useState(false);
 | 
					  const [isVisible, setIsVisible] = useState(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
@@ -64,6 +66,14 @@ const ConfigurationModal: React.FC<ConfigurationModalProps> = ({ onClose, onSave
 | 
				
			|||||||
    return () => clearTimeout(timer);
 | 
					    return () => clearTimeout(timer);
 | 
				
			||||||
  }, []);
 | 
					  }, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    return () => {
 | 
				
			||||||
 | 
					      if (!isSaving.current) {
 | 
				
			||||||
 | 
					        onWallpaperChange({ backgroundUrls: currentConfig.backgroundUrls });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const handleClose = () => {
 | 
					  const handleClose = () => {
 | 
				
			||||||
    setIsVisible(false);
 | 
					    setIsVisible(false);
 | 
				
			||||||
    setTimeout(() => {
 | 
					    setTimeout(() => {
 | 
				
			||||||
@@ -90,6 +100,10 @@ const ConfigurationModal: React.FC<ConfigurationModalProps> = ({ onClose, onSave
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    onWallpaperChange({ backgroundUrls: config.backgroundUrls });
 | 
				
			||||||
 | 
					  }, [config.backgroundUrls]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const handleClockToggleChange = (checked: boolean) => {
 | 
					  const handleClockToggleChange = (checked: boolean) => {
 | 
				
			||||||
    setConfig({ ...config, clock: { ...config.clock, enabled: checked } });
 | 
					    setConfig({ ...config, clock: { ...config.clock, enabled: checked } });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
@@ -201,7 +215,10 @@ const ConfigurationModal: React.FC<ConfigurationModalProps> = ({ onClose, onSave
 | 
				
			|||||||
    localStorage.setItem('userWallpapers', JSON.stringify(updatedUserWallpapers));
 | 
					    localStorage.setItem('userWallpapers', JSON.stringify(updatedUserWallpapers));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const newBackgroundUrls = config.backgroundUrls.filter((url: string) => url !== wallpaperIdentifier);
 | 
					    const newBackgroundUrls = config.backgroundUrls.filter((url: string) => url !== wallpaperIdentifier);
 | 
				
			||||||
    setConfig({ ...config, backgroundUrls: newBackgroundUrls });
 | 
					    
 | 
				
			||||||
 | 
					    const newConfig = { ...config, backgroundUrls: newBackgroundUrls };
 | 
				
			||||||
 | 
					    setConfig(newConfig);
 | 
				
			||||||
 | 
					    onWallpaperChange({ backgroundUrls: newBackgroundUrls });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const allWallpapers = [...baseWallpapers, ...userWallpapers];
 | 
					  const allWallpapers = [...baseWallpapers, ...userWallpapers];
 | 
				
			||||||
@@ -629,7 +646,7 @@ const ConfigurationModal: React.FC<ConfigurationModalProps> = ({ onClose, onSave
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div className="p-8 border-t border-white/10">
 | 
					        <div className="p-8 border-t border-white/10">
 | 
				
			||||||
            <div className="flex justify-end gap-4">
 | 
					            <div className="flex justify-end gap-4">
 | 
				
			||||||
                <button onClick={() => onSave(config)} className="bg-green-500 hover:bg-green-400 text-white font-bold py-2 px-6 rounded-lg">
 | 
					                <button onClick={() => { isSaving.current = true; onSave(config); }} className="bg-green-500 hover:bg-green-400 text-white font-bold py-2 px-6 rounded-lg">
 | 
				
			||||||
                    Save & Close
 | 
					                    Save & Close
 | 
				
			||||||
                </button>
 | 
					                </button>
 | 
				
			||||||
                <button onClick={handleClose} className="bg-gray-600 hover:bg-gray-500 text-white font-bold py-2 px-6 rounded-lg">
 | 
					                <button onClick={handleClose} className="bg-gray-600 hover:bg-gray-500 text-white font-bold py-2 px-6 rounded-lg">
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user