diff --git a/client/src/App.tsx b/client/src/App.tsx
index 42e0836..e153c3c 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -1,6 +1,4 @@
import { useCallback } from 'react';
-import { ApolloProvider } from '@apollo/client';
-import { client } from './graphql/client';
import { DesktopLayout } from './layouts/DesktopLayout';
import { MobileLayout } from './layouts/MobileLayout';
import { UserSelection } from './components/UserSelection';
@@ -64,37 +62,35 @@ export function App() {
}
return (
-
-
- {deviceType === 'desktop' ? (
-
- ) : (
-
- )}
-
-
+
+ {deviceType === 'desktop' ? (
+
+ ) : (
+
+ )}
+
);
}
diff --git a/client/src/components/Screensaver.tsx b/client/src/components/Screensaver.tsx
index 1706a13..e24acfb 100644
--- a/client/src/components/Screensaver.tsx
+++ b/client/src/components/Screensaver.tsx
@@ -155,18 +155,29 @@ export function Screensaver({ onClose }: ScreensaverProps) {
const animationRef = useRef();
const { primaryColor } = useThemeStore();
const [lastClearTime, setLastClearTime] = useState(Date.now());
+ const [interactionEnabled, setInteractionEnabled] = useState(false);
useEffect(() => {
+ console.log('Screensaver: useEffect triggered');
const canvas = canvasRef.current;
- if (!canvas) return;
+ if (!canvas) {
+ console.error('Screensaver: Canvas ref is null');
+ return;
+ }
const ctx = canvas.getContext('2d');
- if (!ctx) return;
+ if (!ctx) {
+ console.error('Screensaver: Could not get 2D context');
+ return;
+ }
+
+ console.log('Screensaver: Canvas and context initialized');
// Set canvas size
const resizeCanvas = () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
+ console.log('Screensaver: Canvas resized to', canvas.width, 'x', canvas.height);
};
resizeCanvas();
@@ -175,6 +186,7 @@ export function Screensaver({ onClose }: ScreensaverProps) {
// Get complementary colors
const complementaryColors = getComplementaryColors(primaryColor);
const colors = [primaryColor, ...complementaryColors];
+ console.log('Screensaver: Using colors', colors);
let startTime = Date.now();
let clearInterval = 0;
@@ -209,9 +221,11 @@ export function Screensaver({ onClose }: ScreensaverProps) {
animationRef.current = requestAnimationFrame(animate);
};
+ console.log('Screensaver: Starting animation');
animate();
return () => {
+ console.log('Screensaver: Cleaning up');
window.removeEventListener('resize', resizeCanvas);
if (animationRef.current) {
cancelAnimationFrame(animationRef.current);
@@ -219,9 +233,24 @@ export function Screensaver({ onClose }: ScreensaverProps) {
};
}, [primaryColor, lastClearTime]);
- // Close on any key press or mouse movement
+ // Enable interaction detection after a delay to prevent immediate closing
useEffect(() => {
- const handleInteraction = () => onClose();
+ const timer = setTimeout(() => {
+ console.log('Screensaver: Enabling interaction detection');
+ setInteractionEnabled(true);
+ }, 1000); // 1 second delay
+
+ return () => clearTimeout(timer);
+ }, []);
+
+ // Close on any key press or mouse movement (only when interaction is enabled)
+ useEffect(() => {
+ if (!interactionEnabled) return;
+
+ const handleInteraction = () => {
+ console.log('Screensaver: User interaction detected, closing');
+ onClose();
+ };
window.addEventListener('keydown', handleInteraction);
window.addEventListener('mousemove', handleInteraction);
@@ -234,7 +263,9 @@ export function Screensaver({ onClose }: ScreensaverProps) {
window.removeEventListener('click', handleInteraction);
window.removeEventListener('touchstart', handleInteraction);
};
- }, [onClose]);
+ }, [onClose, interactionEnabled]);
+
+ console.log('Screensaver: Rendering component');
return (
{
- setScreensaverOpen(true);
+ console.log('ScreensaverButton: Opening manual screensaver');
+ setManualScreensaverOpen(true);
};
const handleCloseScreensaver = () => {
- setScreensaverOpen(false);
+ console.log('ScreensaverButton: Closing screensaver');
+ setManualScreensaverOpen(false);
+ resetTimer(); // Reset the auto-screensaver timer when manually closed
};
+ const isScreensaverOpen = manualScreensaverOpen || autoScreensaverActive;
+
+ console.log('ScreensaverButton: Rendering, screensaverOpen =', isScreensaverOpen, 'autoActive =', autoScreensaverActive);
+
return (
<>
@@ -21,7 +30,7 @@ export function ScreensaverButton() {
- {screensaverOpen && (
+ {isScreensaverOpen && (
)}
>
diff --git a/client/src/hooks/useAutoScreensaver.ts b/client/src/hooks/useAutoScreensaver.ts
new file mode 100644
index 0000000..e07041e
--- /dev/null
+++ b/client/src/hooks/useAutoScreensaver.ts
@@ -0,0 +1,64 @@
+import { useState, useEffect, useCallback } from 'react';
+
+export function useAutoScreensaver(timeoutMinutes: number = 5) {
+ const [isActive, setIsActive] = useState(false);
+ const [lastActivity, setLastActivity] = useState(Date.now());
+
+ const resetTimer = useCallback(() => {
+ setLastActivity(Date.now());
+ if (isActive) {
+ setIsActive(false);
+ }
+ }, [isActive]);
+
+ const activateScreensaver = useCallback(() => {
+ setIsActive(true);
+ }, []);
+
+ // Track user activity
+ useEffect(() => {
+ const handleActivity = () => {
+ resetTimer();
+ };
+
+ // Listen for various user activities
+ window.addEventListener('mousemove', handleActivity);
+ window.addEventListener('mousedown', handleActivity);
+ window.addEventListener('keydown', handleActivity);
+ window.addEventListener('touchstart', handleActivity);
+ window.addEventListener('scroll', handleActivity);
+ window.addEventListener('click', handleActivity);
+
+ return () => {
+ window.removeEventListener('mousemove', handleActivity);
+ window.removeEventListener('mousedown', handleActivity);
+ window.removeEventListener('keydown', handleActivity);
+ window.removeEventListener('touchstart', handleActivity);
+ window.removeEventListener('scroll', handleActivity);
+ window.removeEventListener('click', handleActivity);
+ };
+ }, [resetTimer]);
+
+ // Check for timeout
+ useEffect(() => {
+ const timeoutMs = timeoutMinutes * 60 * 1000;
+
+ const checkTimeout = () => {
+ const now = Date.now();
+ if (now - lastActivity > timeoutMs && !isActive) {
+ console.log(`Auto-screensaver: Activating after ${timeoutMinutes} minutes of inactivity`);
+ activateScreensaver();
+ }
+ };
+
+ const interval = setInterval(checkTimeout, 1000); // Check every second
+
+ return () => clearInterval(interval);
+ }, [lastActivity, isActive, timeoutMinutes, activateScreensaver]);
+
+ return {
+ isActive,
+ activateScreensaver,
+ resetTimer,
+ };
+}
\ No newline at end of file