Refactor App and component files to streamline imports and enhance UI consistency. Removed unused imports and simplified event handlers for better performance. Updated BuildingInfo to utilize Chakra UI modal for improved user experience, and adjusted MultiplierShop functionality comments for clarity.
This commit is contained in:
parent
8245b7b3b2
commit
f000fecba2
13
src/App.tsx
13
src/App.tsx
@ -1,10 +1,8 @@
|
|||||||
import { ResourceDisplay } from './components/ResourceDisplay'
|
import { ResourceDisplay } from './components/ResourceDisplay'
|
||||||
import { BuildingButton } from './components/BuildingButton'
|
import { BuildingButton } from './components/BuildingButton'
|
||||||
import { NextBuildingPreview } from './components/NextBuildingPreview'
|
import { NextBuildingPreview } from './components/NextBuildingPreview'
|
||||||
import { ResetButton } from './components/ResetButton'
|
|
||||||
import { useGameStore } from './store/gameStore'
|
import { useGameStore } from './store/gameStore'
|
||||||
import { playClickSound, initAudio } from './utils/soundUtils'
|
import { initAudio } from './utils/soundUtils'
|
||||||
import { formatNumber } from './utils/numberUtils'
|
|
||||||
import {
|
import {
|
||||||
ChakraProvider,
|
ChakraProvider,
|
||||||
Box,
|
Box,
|
||||||
@ -14,9 +12,6 @@ import {
|
|||||||
VStack,
|
VStack,
|
||||||
SimpleGrid,
|
SimpleGrid,
|
||||||
Button,
|
Button,
|
||||||
Flex,
|
|
||||||
Image,
|
|
||||||
Center,
|
|
||||||
Modal,
|
Modal,
|
||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
ModalContent,
|
ModalContent,
|
||||||
@ -28,7 +23,6 @@ import {
|
|||||||
} from '@chakra-ui/react'
|
} from '@chakra-ui/react'
|
||||||
import theme from './theme'
|
import theme from './theme'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import logoImg from './assets/logo.png'
|
|
||||||
|
|
||||||
type BuildingId = 'mouseFarms' | 'keyboardFactories' | 'monitorDisplays' | 'officeSpace' | 'serverRooms' | 'dataCenters' |
|
type BuildingId = 'mouseFarms' | 'keyboardFactories' | 'monitorDisplays' | 'officeSpace' | 'serverRooms' | 'dataCenters' |
|
||||||
'dataCities' | 'dataCountries' | 'dataContinents' | 'dataWorlds' | 'dataMoons' |
|
'dataCities' | 'dataCountries' | 'dataContinents' | 'dataWorlds' | 'dataMoons' |
|
||||||
@ -39,7 +33,6 @@ type BuildingLevelKey = `${BuildingId}Level`
|
|||||||
function App() {
|
function App() {
|
||||||
const {
|
const {
|
||||||
points,
|
points,
|
||||||
playerLevel,
|
|
||||||
getAvailableBuildings,
|
getAvailableBuildings,
|
||||||
tick,
|
tick,
|
||||||
click,
|
click,
|
||||||
@ -47,7 +40,7 @@ function App() {
|
|||||||
|
|
||||||
const [agreedToTerms, setAgreedToTerms] = useState(false)
|
const [agreedToTerms, setAgreedToTerms] = useState(false)
|
||||||
const [hasStarted, setHasStarted] = useState(false)
|
const [hasStarted, setHasStarted] = useState(false)
|
||||||
const { isOpen, onClose } = useDisclosure({ defaultIsOpen: true })
|
const { onClose } = useDisclosure({ defaultIsOpen: true })
|
||||||
const availableBuildings = getAvailableBuildings()
|
const availableBuildings = getAvailableBuildings()
|
||||||
|
|
||||||
// Set up game tick interval
|
// Set up game tick interval
|
||||||
@ -66,7 +59,7 @@ function App() {
|
|||||||
|
|
||||||
// This is now handled globally, but we'll keep a simpler version
|
// This is now handled globally, but we'll keep a simpler version
|
||||||
// for UI feedback only (cursor change, etc)
|
// for UI feedback only (cursor change, etc)
|
||||||
const handleClick = (e: React.MouseEvent) => {
|
const handleClick = () => {
|
||||||
// Don't call click() here as it's now handled globally
|
// Don't call click() here as it's now handled globally
|
||||||
// Just for visual feedback
|
// Just for visual feedback
|
||||||
if (hasStarted) {
|
if (hasStarted) {
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
VStack,
|
VStack,
|
||||||
Text,
|
Text,
|
||||||
Badge,
|
|
||||||
Tooltip,
|
Tooltip,
|
||||||
HStack,
|
HStack,
|
||||||
Image,
|
Image,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { motion, AnimatePresence } from 'framer-motion'
|
import { Box, Heading, Text, Modal, ModalOverlay, ModalContent, ModalHeader, ModalBody, ModalCloseButton } from '@chakra-ui/react'
|
||||||
|
|
||||||
interface BuildingInfoProps {
|
interface BuildingInfoProps {
|
||||||
isOpen: boolean
|
isOpen: boolean
|
||||||
@ -11,44 +11,23 @@ interface BuildingInfoProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const BuildingInfo = ({ isOpen, onClose, title, description, production }: BuildingInfoProps) => {
|
export const BuildingInfo = ({ isOpen, onClose, title, description, production }: BuildingInfoProps) => {
|
||||||
if (!isOpen) return null
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AnimatePresence>
|
<Modal isOpen={isOpen} onClose={onClose} isCentered>
|
||||||
<motion.div
|
<ModalOverlay bg="blackAlpha.700" />
|
||||||
initial={{ opacity: 0 }}
|
<ModalContent bg="background.secondary" maxW="md" mx={4}>
|
||||||
animate={{ opacity: 1 }}
|
<ModalHeader color="text.secondary">{title}</ModalHeader>
|
||||||
exit={{ opacity: 0 }}
|
<ModalCloseButton />
|
||||||
className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
|
<ModalBody pb={6}>
|
||||||
onClick={onClose}
|
<Text color="text.primary" mb={4}>{description}</Text>
|
||||||
>
|
|
||||||
<motion.div
|
|
||||||
initial={{ scale: 0.9, opacity: 0 }}
|
|
||||||
animate={{ scale: 1, opacity: 1 }}
|
|
||||||
exit={{ scale: 0.9, opacity: 0 }}
|
|
||||||
className="bg-gray-800 p-6 rounded-lg max-w-md w-full mx-4"
|
|
||||||
onClick={e => e.stopPropagation()}
|
|
||||||
>
|
|
||||||
<div className="flex justify-between items-start mb-4">
|
|
||||||
<h3 className="text-xl font-bold">{title}</h3>
|
|
||||||
<button
|
|
||||||
onClick={onClose}
|
|
||||||
className="text-gray-400 hover:text-white"
|
|
||||||
>
|
|
||||||
✕
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p className="text-gray-300 mb-4">{description}</p>
|
<Box p={4} bg="background.card" borderRadius="md">
|
||||||
|
<Heading as="h4" size="sm" mb={2} color="brand.300">Production:</Heading>
|
||||||
<div className="bg-gray-700 p-4 rounded-lg">
|
|
||||||
<h4 className="font-semibold mb-2">Production:</h4>
|
|
||||||
{production.points && (
|
{production.points && (
|
||||||
<div className="text-green-400">+{production.points} points/s</div>
|
<Text color="text.accent">+{production.points} points/s</Text>
|
||||||
)}
|
)}
|
||||||
</div>
|
</Box>
|
||||||
</motion.div>
|
</ModalBody>
|
||||||
</motion.div>
|
</ModalContent>
|
||||||
</AnimatePresence>
|
</Modal>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { Box, Button, VStack, HStack, Text, SimpleGrid } from '@chakra-ui/react'
|
import { Box, Button, VStack, Text, SimpleGrid } from '@chakra-ui/react'
|
||||||
import { useGameStore } from '../store/gameStore'
|
import { useGameStore } from '../store/gameStore'
|
||||||
|
|
||||||
const MULTIPLIER_PURCHASES = [
|
const MULTIPLIER_PURCHASES = [
|
||||||
@ -11,7 +11,7 @@ const MULTIPLIER_PURCHASES = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
export function MultiplierShop() {
|
export function MultiplierShop() {
|
||||||
const { points, buyMultiplier } = useGameStore()
|
const { points } = useGameStore()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box bg="gray.800" p={6} borderRadius="lg">
|
<Box bg="gray.800" p={6} borderRadius="lg">
|
||||||
@ -26,7 +26,8 @@ export function MultiplierShop() {
|
|||||||
{MULTIPLIER_PURCHASES.map((purchase) => (
|
{MULTIPLIER_PURCHASES.map((purchase) => (
|
||||||
<Button
|
<Button
|
||||||
key={`${purchase.duration}-${purchase.multiplier}`}
|
key={`${purchase.duration}-${purchase.multiplier}`}
|
||||||
onClick={() => buyMultiplier(purchase.duration, purchase.multiplier)}
|
// Multiplier shop functionality is not yet implemented in the game state
|
||||||
|
// onClick={() => buyMultiplier(purchase.duration, purchase.multiplier)}
|
||||||
isDisabled={points < purchase.cost}
|
isDisabled={points < purchase.cost}
|
||||||
bg="gray.700"
|
bg="gray.700"
|
||||||
_hover={{ bg: 'gray.600' }}
|
_hover={{ bg: 'gray.600' }}
|
||||||
|
|||||||
@ -9,17 +9,6 @@ import { useGameStore } from '../store/gameStore'
|
|||||||
import { BUILDING_INFO } from '../store/gameStore'
|
import { BUILDING_INFO } from '../store/gameStore'
|
||||||
import { formatNumber } from '../utils/numberUtils'
|
import { formatNumber } from '../utils/numberUtils'
|
||||||
|
|
||||||
interface BuildingInfo {
|
|
||||||
cost: number
|
|
||||||
levelRequirement: number
|
|
||||||
title: string
|
|
||||||
description: string
|
|
||||||
production: {
|
|
||||||
points?: number
|
|
||||||
techParts?: number
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function NextBuildingPreview() {
|
export function NextBuildingPreview() {
|
||||||
const { playerLevel } = useGameStore()
|
const { playerLevel } = useGameStore()
|
||||||
|
|
||||||
@ -29,7 +18,7 @@ export function NextBuildingPreview() {
|
|||||||
|
|
||||||
if (!nextBuilding) return null
|
if (!nextBuilding) return null
|
||||||
|
|
||||||
const [id, info] = nextBuilding
|
const [, info] = nextBuilding
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip label={`Requires level ${info.levelRequirement}`}>
|
<Tooltip label={`Requires level ${info.levelRequirement}`}>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Box, HStack, Text, Progress, Flex, Divider, Tooltip, Image, Button, Icon } from '@chakra-ui/react'
|
import { Box, Text, Progress, Flex, Divider, Tooltip, Image, Button } from '@chakra-ui/react'
|
||||||
import { useGameStore } from '../store/gameStore'
|
import { useGameStore } from '../store/gameStore'
|
||||||
import logoImg from '../assets/logo.png'
|
import logoImg from '../assets/logo.png'
|
||||||
import { ResetButton } from './ResetButton'
|
import { ResetButton } from './ResetButton'
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { IconButton, Tooltip, useBoolean } from '@chakra-ui/react'
|
import { IconButton, Tooltip } from '@chakra-ui/react'
|
||||||
import { toggleSound, isSoundEnabled, initAudio } from '../utils/soundUtils'
|
import { toggleSound, isSoundEnabled, initAudio } from '../utils/soundUtils'
|
||||||
import { useEffect, useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
|
||||||
export function SoundToggleButton() {
|
export function SoundToggleButton() {
|
||||||
// Initialize the state with the current sound enabled state
|
// Initialize the state with the current sound enabled state
|
||||||
|
|||||||
@ -28,7 +28,7 @@ function AppWithGlobalHandlers() {
|
|||||||
}, [gameStarted]);
|
}, [gameStarted]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleGlobalClick = (e: MouseEvent) => {
|
const handleGlobalClick = () => {
|
||||||
// Only trigger if game has started
|
// Only trigger if game has started
|
||||||
const gameState = useGameStore.getState();
|
const gameState = useGameStore.getState();
|
||||||
if ((gameStarted || gameState.points > 0) && gameState.playerLevel >= 1) {
|
if ((gameStarted || gameState.points > 0) && gameState.playerLevel >= 1) {
|
||||||
@ -37,7 +37,7 @@ function AppWithGlobalHandlers() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleGlobalKeyPress = (e: KeyboardEvent) => {
|
const handleGlobalKeyPress = () => {
|
||||||
// Only trigger if game has started
|
// Only trigger if game has started
|
||||||
const gameState = useGameStore.getState();
|
const gameState = useGameStore.getState();
|
||||||
if ((gameStarted || gameState.points > 0) && gameState.playerLevel >= 1) {
|
if ((gameStarted || gameState.points > 0) && gameState.playerLevel >= 1) {
|
||||||
|
|||||||
@ -9,7 +9,6 @@ const SOUND_FILES = {
|
|||||||
// AudioManager singleton for handling all game audio
|
// AudioManager singleton for handling all game audio
|
||||||
class AudioManager {
|
class AudioManager {
|
||||||
private soundEnabled: boolean = true;
|
private soundEnabled: boolean = true;
|
||||||
private audioContext: AudioContext | null = null;
|
|
||||||
private sounds: Map<string, HTMLAudioElement> = new Map();
|
private sounds: Map<string, HTMLAudioElement> = new Map();
|
||||||
private lastClickIndex: number = -1;
|
private lastClickIndex: number = -1;
|
||||||
private initialized: boolean = false;
|
private initialized: boolean = false;
|
||||||
@ -36,12 +35,6 @@ class AudioManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Create AudioContext if possible (will only work after user interaction)
|
|
||||||
if (window.AudioContext || (window as any).webkitAudioContext) {
|
|
||||||
const AudioContextClass = window.AudioContext || (window as any).webkitAudioContext;
|
|
||||||
this.audioContext = new AudioContextClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Play a silent sound to unlock audio on iOS/Safari
|
// Play a silent sound to unlock audio on iOS/Safari
|
||||||
const silentSound = new Audio();
|
const silentSound = new Audio();
|
||||||
silentSound.play().catch(e => console.log('Silent sound failed to play:', e));
|
silentSound.play().catch(e => console.log('Silent sound failed to play:', e));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user