diff --git a/app/_layout.tsx b/app/_layout.tsx index 6ed6aef..2da16e6 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -1,9 +1,11 @@ import i18n from "@/i18n/i18n"; +import { COLORS } from "@/styles/styles"; import AppContext, { IAppContext } from "@/util/context"; import { MaterialIcons } from "@expo/vector-icons"; import { Stack } from "expo-router"; import React, { useMemo, useState } from "react"; import { I18nextProvider, useTranslation } from "react-i18next"; +import { useColorScheme } from "react-native"; const RootLayout: React.FC = () => { const [showSettings, setShowSettings] = useState(false); @@ -17,20 +19,36 @@ const RootLayout: React.FC = () => { [showSettings] ); + const colorScheme = useColorScheme(); + const darkMode = useMemo(() => colorScheme === "dark", [colorScheme]); + const colors = useMemo( + () => (darkMode ? COLORS.DARK : COLORS.LIGHT), + [darkMode] + ); return ( ( setShowSettings(!showSettings)} size={30} + color={colors.TEXT} /> ), + headerStyle: { + backgroundColor: colors.PRIMARY, + }, + headerTintColor: colors.TEXT, + statusBarBackgroundColor: "grey", }} /> diff --git a/app/index.tsx b/app/index.tsx index 7f1d8c7..97c3a43 100644 --- a/app/index.tsx +++ b/app/index.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect, useContext, useMemo } from "react"; -import { ScrollView, Alert } from "react-native"; +import { ScrollView, Alert, useColorScheme, Appearance } from "react-native"; import Button from "@/containers/Button"; import PlayerSelector from "@/components/PlayerSelector"; import BuyInSelector from "@/components/BuyInSelector"; @@ -7,16 +7,17 @@ import ChipsSelector from "@/components/ChipsSelector"; import ChipDistributionSummary from "@/components/ChipDistributionSummary"; import ChipDetection from "@/components/ChipDetection"; import CurrencySelector from "@/components/CurrencySelector"; -import { saveState, loadState } from "@/components/CalculatorState"; +import { saveState, loadState } from "@/util/CalculatorState"; import { savePersistentState, loadPersistentState, -} from "@/components/PersistentState"; -import styles from "@/styles/styles"; +} from "@/util/PersistentState"; +import styles, { COLORS } from "@/styles/styles"; import Section from "@/containers/Section"; import AppContext from "@/util/context"; -import { Picker } from "@react-native-picker/picker"; import i18n from "@/i18n/i18n"; +import { Picker, PickerItem } from "@/containers/Picker"; +import { ItemValue } from "@react-native-picker/picker/typings/Picker"; const IndexScreen: React.FC = () => { const [playerCount, setPlayerCount] = useState(2); @@ -25,23 +26,25 @@ const IndexScreen: React.FC = () => { const [totalChipsCount, setTotalChipsCount] = useState([]); const [selectedCurrency, setSelectedCurrency] = useState("$"); const [selectedLanguage, setSelectedLanguage] = useState("en"); + const colorScheme = useColorScheme(); + const darkMode = useMemo(() => colorScheme === "dark", [colorScheme]); + const colors = useMemo( + () => (darkMode ? COLORS.DARK : COLORS.LIGHT), + [darkMode] + ); const context = useContext(AppContext); const isSettingsVisible = useMemo(() => context.showSettings, [context]); useEffect(() => { const loadPersistentData = async () => { try { - console.log("Loading persistent game state..."); const savedState = await loadPersistentState(); if (savedState) { - console.log("Persistent state restored:", savedState); setPlayerCount(savedState.playerCount || 2); setBuyInAmount(savedState.buyInAmount || 20); setNumberOfChips(savedState.numberOfChips || 5); setTotalChipsCount(savedState.totalChipsCount || []); setSelectedCurrency(savedState.selectedCurrency || "$"); - } else { - console.log("No persistent state found, using defaults."); } } catch (error) { console.error("Error loading persistent state:", error); @@ -62,41 +65,29 @@ const IndexScreen: React.FC = () => { totalChipsCount, selectedCurrency, }; - try { - await saveState(slot, state); - await savePersistentState(state); - console.log(`Game state saved to ${slot}:`, state); - Alert.alert(i18n.t("success"), i18n.t("state_saved", { slot })); // Fixed interpolation - } catch (error) { - console.error("Error saving state:", error); - Alert.alert(i18n.t("error"), i18n.t("failed_to_save_state")); - } + await saveState(slot, state); + await savePersistentState(state); + Alert.alert(i18n.t("success"), i18n.t("state_saved", { slot })); }; const handleLoad = async (slot: "SLOT1" | "SLOT2") => { - try { - const loadedState = await loadState(slot); - if (loadedState) { - setPlayerCount(loadedState.playerCount); - setBuyInAmount(loadedState.buyInAmount ?? 20); - setNumberOfChips(loadedState.numberOfChips); - setTotalChipsCount(loadedState.totalChipsCount); - setSelectedCurrency(loadedState.selectedCurrency || "$"); - await savePersistentState(loadedState); - console.log(`Game state loaded from ${slot}:`, loadedState); - Alert.alert(i18n.t("success"), i18n.t("state_loaded_from", { slot })); // Fixed interpolation - } else { - Alert.alert(i18n.t("info"), i18n.t("no_saved_state_found")); - } - } catch (error) { - console.error("Error loading state:", error); - Alert.alert(i18n.t("error"), i18n.t("failed_to_load_state")); + const loadedState = await loadState(slot); + if (loadedState) { + setPlayerCount(loadedState.playerCount); + setBuyInAmount(loadedState.buyInAmount ?? 20); + setNumberOfChips(loadedState.numberOfChips); + setTotalChipsCount(loadedState.totalChipsCount); + setSelectedCurrency(loadedState.selectedCurrency || "$"); + await savePersistentState(loadedState); + Alert.alert(i18n.t("success"), i18n.t("state_loaded_from", { slot })); + } else { + Alert.alert(i18n.t("info"), i18n.t("no_saved_state_found")); } }; - const handleLanguageChange = (language: string) => { - setSelectedLanguage(language); - i18n.changeLanguage(language); + const handleLanguageChange = (language: ItemValue, _: any) => { + setSelectedLanguage(language.toString()); + i18n.changeLanguage(language.toString()); }; return ( @@ -105,33 +96,49 @@ const IndexScreen: React.FC = () => { contentContainerStyle={styles.scrollViewContent} > {isSettingsVisible && ( -
- +
- - - -
- )} +
- {isSettingsVisible && ( -
- -
+
+ + + + +
+ +
+ +
+ )}
{ title={i18n.t("save_slot_1")} onPress={() => handleSave("SLOT1")} disabled={buyInAmount === null} + size="small" />
diff --git a/components/BuyInSelector.tsx b/components/BuyInSelector.tsx index 93eae83..45fb4ca 100644 --- a/components/BuyInSelector.tsx +++ b/components/BuyInSelector.tsx @@ -1,5 +1,5 @@ -import React, { useState } from "react"; -import { View, Text, TextInput } from "react-native"; +import React, { useMemo, useState } from "react"; +import { View, Text, TextInput, useColorScheme } from "react-native"; import styles, { COLORS } from "@/styles/styles"; import Button from "@/containers/Button"; import i18n from "@/i18n/i18n"; @@ -25,6 +25,12 @@ const BuyInSelector: React.FC = ({ }) => { const [customAmount, setCustomAmount] = useState(""); const [buyInAmount, setBuyInAmountState] = useState(null); + const colorScheme = useColorScheme(); + const darkMode = useMemo(() => colorScheme === "dark", [colorScheme]); + const colors = useMemo( + () => (darkMode ? COLORS.DARK : COLORS.LIGHT), + [darkMode] + ); const handleCustomAmountChange = (value: string) => { const numericValue = parseRoundClamp(value); @@ -51,7 +57,6 @@ const BuyInSelector: React.FC = ({ {defaultBuyInOptions.map((amount) => (