mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-11-16 01:21:16 +01:00
# Description of Changes Refactor user preferences to all be in one service and all stored in localStorage instead of indexeddb. This allows simpler & quicker accessing of them, and ensures that they're all neatly stored in one consistent place instead of spread out over local storage.
193 lines
5.9 KiB
TypeScript
193 lines
5.9 KiB
TypeScript
import { useCallback, useRef, useEffect } from 'react';
|
|
import { usePreferences } from '../contexts/PreferencesContext';
|
|
import type { ThemeMode } from '../constants/theme';
|
|
|
|
interface RainbowThemeHook {
|
|
themeMode: ThemeMode;
|
|
isRainbowMode: boolean;
|
|
isToggleDisabled: boolean;
|
|
toggleTheme: () => void;
|
|
activateRainbow: () => void;
|
|
deactivateRainbow: () => void;
|
|
}
|
|
|
|
const allowRainbowMode = false; // Override to allow/disallow fun
|
|
|
|
export function useRainbowTheme(): RainbowThemeHook {
|
|
const { preferences, updatePreference } = usePreferences();
|
|
const themeMode = preferences.theme;
|
|
|
|
// Track rapid toggles for easter egg
|
|
const toggleCount = useRef(0);
|
|
const lastToggleTime = useRef(Date.now());
|
|
const isToggleDisabled = useRef(false);
|
|
|
|
// Apply rainbow class to body whenever theme changes
|
|
useEffect(() => {
|
|
if (themeMode === 'rainbow') {
|
|
document.body.classList.add('rainbow-mode-active');
|
|
showRainbowNotification();
|
|
} else {
|
|
document.body.classList.remove('rainbow-mode-active');
|
|
}
|
|
}, [themeMode]);
|
|
|
|
const showRainbowNotification = () => {
|
|
// Remove any existing notification
|
|
const existingNotification = document.getElementById('rainbow-notification');
|
|
if (existingNotification) {
|
|
existingNotification.remove();
|
|
}
|
|
|
|
// Create and show rainbow notification
|
|
const notification = document.createElement('div');
|
|
notification.id = 'rainbow-notification';
|
|
notification.innerHTML = '🌈 RAINBOW MODE ACTIVATED! 🌈<br><small>Button disabled for 3 seconds, then click to exit</small>';
|
|
notification.style.cssText = `
|
|
position: fixed;
|
|
top: 20px;
|
|
right: 20px;
|
|
background: linear-gradient(45deg, #ff0000, #ff8800, #ffff00, #88ff00, #00ff88, #00ffff, #0088ff, #8800ff);
|
|
background-size: 300% 300%;
|
|
animation: rainbowBackground 1s ease infinite;
|
|
color: white;
|
|
padding: 15px 20px;
|
|
border-radius: 25px;
|
|
font-weight: bold;
|
|
font-size: 16px;
|
|
z-index: 1000;
|
|
border: 2px solid white;
|
|
box-shadow: 0 0 20px rgba(255, 255, 255, 0.8);
|
|
user-select: none;
|
|
pointer-events: none;
|
|
transition: opacity 0.3s ease;
|
|
`;
|
|
|
|
document.body.appendChild(notification);
|
|
|
|
// Auto-remove notification after 3 seconds
|
|
setTimeout(() => {
|
|
if (notification) {
|
|
notification.style.opacity = '0';
|
|
setTimeout(() => {
|
|
if (notification.parentNode) {
|
|
notification.parentNode.removeChild(notification);
|
|
}
|
|
}, 300);
|
|
}
|
|
}, 3000);
|
|
};
|
|
|
|
const showExitNotification = () => {
|
|
// Remove any existing notification
|
|
const existingNotification = document.getElementById('rainbow-exit-notification');
|
|
if (existingNotification) {
|
|
existingNotification.remove();
|
|
}
|
|
|
|
// Create and show exit notification
|
|
const notification = document.createElement('div');
|
|
notification.id = 'rainbow-exit-notification';
|
|
notification.innerHTML = '🌙 Rainbow mode deactivated';
|
|
notification.style.cssText = `
|
|
position: fixed;
|
|
top: 20px;
|
|
right: 20px;
|
|
background: linear-gradient(45deg, #333, #666);
|
|
color: white;
|
|
padding: 15px 20px;
|
|
border-radius: 25px;
|
|
font-weight: bold;
|
|
font-size: 16px;
|
|
z-index: 1000;
|
|
border: 2px solid #999;
|
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
|
|
user-select: none;
|
|
pointer-events: none;
|
|
transition: opacity 0.3s ease;
|
|
`;
|
|
|
|
document.body.appendChild(notification);
|
|
|
|
// Auto-remove notification after 2 seconds
|
|
setTimeout(() => {
|
|
if (notification) {
|
|
notification.style.opacity = '0';
|
|
setTimeout(() => {
|
|
if (notification.parentNode) {
|
|
notification.parentNode.removeChild(notification);
|
|
}
|
|
}, 300);
|
|
}
|
|
}, 2000);
|
|
};
|
|
|
|
const toggleTheme = useCallback(() => {
|
|
// Don't allow toggle if disabled
|
|
if (isToggleDisabled.current) {
|
|
return;
|
|
}
|
|
|
|
const currentTime = Date.now();
|
|
|
|
// Simple exit from rainbow mode with single click (after cooldown period)
|
|
if (themeMode === 'rainbow') {
|
|
updatePreference('theme', 'light');
|
|
console.log('🌈 Rainbow mode deactivated. Thanks for trying it!');
|
|
showExitNotification();
|
|
return;
|
|
}
|
|
|
|
// Reset counter if too much time has passed (2.5 seconds)
|
|
if (currentTime - lastToggleTime.current > 2500) {
|
|
toggleCount.current = 1;
|
|
} else {
|
|
toggleCount.current++;
|
|
}
|
|
lastToggleTime.current = currentTime;
|
|
|
|
// Easter egg: Activate rainbow mode after 10 rapid toggles
|
|
if (allowRainbowMode && toggleCount.current >= 10) {
|
|
updatePreference('theme', 'rainbow');
|
|
console.log('🌈 RAINBOW MODE ACTIVATED! 🌈 You found the secret easter egg!');
|
|
console.log('🌈 Button will be disabled for 3 seconds, then click once to exit!');
|
|
|
|
// Disable toggle for 3 seconds
|
|
isToggleDisabled.current = true;
|
|
setTimeout(() => {
|
|
isToggleDisabled.current = false;
|
|
console.log('🌈 Theme toggle re-enabled! Click once to exit rainbow mode.');
|
|
}, 3000);
|
|
|
|
// Reset counter
|
|
toggleCount.current = 0;
|
|
return;
|
|
}
|
|
|
|
// Normal theme switching
|
|
const nextTheme = themeMode === 'light' ? 'dark' : 'light';
|
|
updatePreference('theme', nextTheme);
|
|
}, [themeMode, updatePreference]);
|
|
|
|
const activateRainbow = useCallback(() => {
|
|
updatePreference('theme', 'rainbow');
|
|
console.log('🌈 Rainbow mode manually activated!');
|
|
}, [updatePreference]);
|
|
|
|
const deactivateRainbow = useCallback(() => {
|
|
if (themeMode === 'rainbow') {
|
|
updatePreference('theme', 'light');
|
|
console.log('🌈 Rainbow mode manually deactivated.');
|
|
}
|
|
}, [themeMode, updatePreference]);
|
|
|
|
return {
|
|
themeMode,
|
|
isRainbowMode: themeMode === 'rainbow',
|
|
isToggleDisabled: isToggleDisabled.current,
|
|
toggleTheme,
|
|
activateRainbow,
|
|
deactivateRainbow,
|
|
};
|
|
}
|