Compare commits
1 Commits
c0c73f9e44
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f2fd37e29 |
Generated
+18
-18
@@ -2342,9 +2342,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@remix-run/router": {
|
"node_modules/@remix-run/router": {
|
||||||
"version": "1.23.0",
|
"version": "1.23.2",
|
||||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz",
|
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.2.tgz",
|
||||||
"integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==",
|
"integrity": "sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
@@ -6042,9 +6042,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lodash": {
|
"node_modules/lodash": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.23",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/lodash.castarray": {
|
"node_modules/lodash.castarray": {
|
||||||
@@ -6977,9 +6977,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/qs": {
|
"node_modules/qs": {
|
||||||
"version": "6.14.0",
|
"version": "6.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz",
|
||||||
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
|
"integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -7157,12 +7157,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-router": {
|
"node_modules/react-router": {
|
||||||
"version": "6.30.1",
|
"version": "6.30.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.3.tgz",
|
||||||
"integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==",
|
"integrity": "sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@remix-run/router": "1.23.0"
|
"@remix-run/router": "1.23.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
@@ -7172,13 +7172,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-router-dom": {
|
"node_modules/react-router-dom": {
|
||||||
"version": "6.30.1",
|
"version": "6.30.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.3.tgz",
|
||||||
"integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==",
|
"integrity": "sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@remix-run/router": "1.23.0",
|
"@remix-run/router": "1.23.2",
|
||||||
"react-router": "6.30.1"
|
"react-router": "6.30.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
|
|||||||
@@ -74,7 +74,13 @@ const MatrixCursor = () => {
|
|||||||
document.removeEventListener('mouseenter', handleMouseEnter);
|
document.removeEventListener('mouseenter', handleMouseEnter);
|
||||||
document.removeEventListener('mouseleave', handleMouseLeave);
|
document.removeEventListener('mouseleave', handleMouseLeave);
|
||||||
document.removeEventListener('touchstart', handleTouch);
|
document.removeEventListener('touchstart', handleTouch);
|
||||||
document.body.classList.remove('matrix-cursor');
|
|
||||||
|
// Only remove cursor class if no other MatrixCursor components are mounted
|
||||||
|
// This prevents the cursor from showing when exiting fullscreen
|
||||||
|
const otherCursors = document.querySelectorAll('.matrix-cursor-crosshair');
|
||||||
|
if (otherCursors.length === 0) {
|
||||||
|
document.body.classList.remove('matrix-cursor');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}, [isTouchDevice]);
|
}, [isTouchDevice]);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { motion, AnimatePresence } from 'framer-motion';
|
|||||||
import { Settings, Monitor, Volume2, Cpu, X, Contrast, Binary, Smartphone } from 'lucide-react';
|
import { Settings, Monitor, Volume2, Cpu, X, Contrast, Binary, Smartphone } from 'lucide-react';
|
||||||
import { useSettings, MobileControlMode } from '@/contexts/SettingsContext';
|
import { useSettings, MobileControlMode } from '@/contexts/SettingsContext';
|
||||||
import { useAchievements } from '@/contexts/AchievementsContext';
|
import { useAchievements } from '@/contexts/AchievementsContext';
|
||||||
|
import { useIsMobile } from '@/hooks/use-mobile';
|
||||||
import CryptoConsentModal from './CryptoConsentModal';
|
import CryptoConsentModal from './CryptoConsentModal';
|
||||||
|
|
||||||
interface SettingsPanelProps {
|
interface SettingsPanelProps {
|
||||||
@@ -15,6 +16,7 @@ const SettingsPanel = ({ onToggleTheme, isRedTheme }: SettingsPanelProps) => {
|
|||||||
const [showCryptoModal, setShowCryptoModal] = useState(false);
|
const [showCryptoModal, setShowCryptoModal] = useState(false);
|
||||||
const { crtEnabled, setCrtEnabled, matrixEnabled, setMatrixEnabled, soundEnabled, setSoundEnabled, cryptoConsent, playSound, mobileControlMode, setMobileControlMode } = useSettings();
|
const { crtEnabled, setCrtEnabled, matrixEnabled, setMatrixEnabled, soundEnabled, setSoundEnabled, cryptoConsent, playSound, mobileControlMode, setMobileControlMode } = useSettings();
|
||||||
const { unlockAchievement } = useAchievements();
|
const { unlockAchievement } = useAchievements();
|
||||||
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
const handleToggle = (setter: (value: boolean) => void, currentValue: boolean, achievementId?: string) => {
|
const handleToggle = (setter: (value: boolean) => void, currentValue: boolean, achievementId?: string) => {
|
||||||
playSound('click');
|
playSound('click');
|
||||||
@@ -156,18 +158,20 @@ const SettingsPanel = ({ onToggleTheme, isRedTheme }: SettingsPanelProps) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Mobile Controls Mode */}
|
{/* Mobile Controls Mode */}
|
||||||
<div className="flex items-center justify-between">
|
{isMobile && (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center justify-between">
|
||||||
<Smartphone size={16} className="text-primary" />
|
<div className="flex items-center gap-2">
|
||||||
<span className="font-pixel text-sm text-foreground/90">Mobile Controls</span>
|
<Smartphone size={16} className="text-primary" />
|
||||||
|
<span className="font-pixel text-sm text-foreground/90">Game Controls (for touch devices)</span>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={handleMobileControlToggle}
|
||||||
|
className="px-3 py-1 text-xs font-pixel border border-primary transition-all duration-300 bg-transparent text-primary hover:bg-primary hover:text-background"
|
||||||
|
>
|
||||||
|
{mobileControlMode === 'buttons' ? 'BUTTONS' : 'SWIPE'}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<button
|
)}
|
||||||
onClick={handleMobileControlToggle}
|
|
||||||
className="px-3 py-1 text-xs font-pixel border border-primary transition-all duration-300 bg-transparent text-primary hover:bg-primary hover:text-background"
|
|
||||||
>
|
|
||||||
{mobileControlMode === 'buttons' ? 'BUTTONS' : 'SWIPE'}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-4 pt-4 border-t border-primary/30">
|
<div className="mt-4 pt-4 border-t border-primary/30">
|
||||||
|
|||||||
+2
-2
@@ -568,7 +568,7 @@ const Snake = () => {
|
|||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<button onClick={() => { setGameMode(null); setGameStarted(false); }} className="font-pixel text-sm text-foreground/50 hover:text-primary transition-colors">{'<'} Back</button>
|
<button onClick={() => { setGameMode(null); setGameStarted(false); }} className="font-pixel text-sm text-foreground/50 hover:text-primary transition-colors">{'<'} Back</button>
|
||||||
<h1 className="font-minecraft text-2xl md:text-3xl text-primary text-glow-strong">
|
<h1 className="font-minecraft text-2xl md:text-3xl text-primary text-glow-strong">
|
||||||
Snake {gameMode === '2p' && <span className="text-secondary">2P</span>}
|
Snake {gameMode === '2p' && <span className="text-secondary" style={{ textShadow: '0 0 10px hsl(var(--secondary) / 0.8), 0 0 20px hsl(var(--secondary) / 0.4)' }}>2P</span>}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<button onClick={toggleFullscreen} className="p-2 border border-primary/50 hover:bg-primary/20 transition-colors" title={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}>
|
<button onClick={toggleFullscreen} className="p-2 border border-primary/50 hover:bg-primary/20 transition-colors" title={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}>
|
||||||
@@ -768,4 +768,4 @@ const Snake = () => {
|
|||||||
: gameUi;
|
: gameUi;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Snake;
|
export default Snake;
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ const Tetris = () => {
|
|||||||
const availableHeight = window.innerHeight - 120;
|
const availableHeight = window.innerHeight - 120;
|
||||||
const cellFromWidth = Math.floor(availableWidth / (gameMode === '2p' ? BOARD_WIDTH * 2 + 4 : BOARD_WIDTH));
|
const cellFromWidth = Math.floor(availableWidth / (gameMode === '2p' ? BOARD_WIDTH * 2 + 4 : BOARD_WIDTH));
|
||||||
const cellFromHeight = Math.floor(availableHeight / BOARD_HEIGHT);
|
const cellFromHeight = Math.floor(availableHeight / BOARD_HEIGHT);
|
||||||
return Math.min(cellFromWidth, cellFromHeight, gameMode === '2p' ? 32 : 40);
|
return Math.min(cellFromWidth, cellFromHeight);
|
||||||
}
|
}
|
||||||
if (gameMode === '2p') return 22;
|
if (gameMode === '2p') return 22;
|
||||||
return 28;
|
return 28;
|
||||||
@@ -508,7 +508,7 @@ const Tetris = () => {
|
|||||||
{nextP.shape.map((row, y) => (
|
{nextP.shape.map((row, y) => (
|
||||||
<div key={y} className="flex gap-1">
|
<div key={y} className="flex gap-1">
|
||||||
{row.map((val, x) => (
|
{row.map((val, x) => (
|
||||||
<div key={`${y}-${x}`} className={`w-4 h-4`} style={{ backgroundColor: val ? nextP.color : 'transparent', boxShadow: val ? `0 0 5px ${nextP.color}` : 'none' }} />
|
<div key={`${y}-${x}`} style={{ width: cellSize * 0.6, height: cellSize * 0.6, backgroundColor: val ? nextP.color : 'transparent', boxShadow: val ? `0 0 5px ${nextP.color}` : 'none' }} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
Reference in New Issue
Block a user