aboutsummaryrefslogtreecommitdiff
path: root/web/src/hooks
diff options
context:
space:
mode:
authorsrdusr <trevorgray@srdusr.com>2025-09-26 13:39:28 +0200
committersrdusr <trevorgray@srdusr.com>2025-09-26 13:39:28 +0200
commit8d60c7f93407988ee0232ea90980028f299cb0f3 (patch)
treeb343b691d1bce64fb3bc9b40324857486f2be244 /web/src/hooks
parent76f0d0e902e6ed164704572bd81faa5e5e560cf3 (diff)
downloadtyperpunk-8d60c7f93407988ee0232ea90980028f299cb0f3.tar.gz
typerpunk-8d60c7f93407988ee0232ea90980028f299cb0f3.zip
Initial Commit
Diffstat (limited to 'web/src/hooks')
-rw-r--r--web/src/hooks/useCoreGame.ts80
-rw-r--r--web/src/hooks/useTheme.ts21
2 files changed, 101 insertions, 0 deletions
diff --git a/web/src/hooks/useCoreGame.ts b/web/src/hooks/useCoreGame.ts
new file mode 100644
index 0000000..3aa69ec
--- /dev/null
+++ b/web/src/hooks/useCoreGame.ts
@@ -0,0 +1,80 @@
+import { useEffect, useRef, useState } from 'react';
+import init, { TyperPunkGame as Game } from '@typerpunk/wasm';
+
+export function useCoreGame() {
+ const [isLoading, setIsLoading] = useState(true);
+ const [error, setError] = useState<string | null>(null);
+ const gameRef = useRef<Game | null>(null);
+
+ useEffect(() => {
+ let mounted = true;
+
+ const initGame = async () => {
+ try {
+ await init();
+ if (!mounted) return;
+
+ const game = new Game();
+ gameRef.current = game;
+ setIsLoading(false);
+ } catch (err) {
+ console.error('Failed to initialize game:', err);
+ if (mounted) {
+ setError('Failed to initialize game');
+ setIsLoading(false);
+ }
+ }
+ };
+
+ initGame();
+
+ return () => {
+ mounted = false;
+ if (gameRef.current) {
+ try {
+ gameRef.current.free();
+ } catch (err) {
+ console.error('Error cleaning up game:', err);
+ }
+ gameRef.current = null;
+ }
+ };
+ }, []);
+
+ const resetGame = async () => {
+ if (gameRef.current) {
+ try {
+ gameRef.current.free();
+ } catch (err) {
+ console.error('Error freeing old game:', err);
+ }
+ }
+
+ try {
+ const game = new Game();
+ gameRef.current = game;
+ } catch (err) {
+ console.error('Error resetting game:', err);
+ setError('Failed to reset game');
+ }
+ };
+
+ const cleanupGame = () => {
+ if (gameRef.current) {
+ try {
+ gameRef.current.free();
+ } catch (err) {
+ console.error('Error cleaning up game:', err);
+ }
+ gameRef.current = null;
+ }
+ };
+
+ return {
+ game: gameRef.current,
+ isLoading,
+ error,
+ resetGame,
+ cleanupGame
+ };
+} \ No newline at end of file
diff --git a/web/src/hooks/useTheme.ts b/web/src/hooks/useTheme.ts
new file mode 100644
index 0000000..a5457b6
--- /dev/null
+++ b/web/src/hooks/useTheme.ts
@@ -0,0 +1,21 @@
+import { useState, useEffect } from 'react';
+import { Theme } from '../types';
+
+export const useTheme = () => {
+ const [theme, setTheme] = useState<Theme>(() => {
+ const savedTheme = localStorage.getItem('theme');
+ return (savedTheme as Theme) || Theme.Light;
+ });
+
+ useEffect(() => {
+ localStorage.setItem('theme', theme);
+ document.documentElement.classList.remove(Theme.Light, Theme.Dark);
+ document.documentElement.classList.add(theme);
+ }, [theme]);
+
+ const toggleTheme = () => {
+ setTheme(prev => prev === Theme.Light ? Theme.Dark : Theme.Light);
+ };
+
+ return { theme, toggleTheme };
+}; \ No newline at end of file