import React, { useEffect, useMemo, useState } from "react"; import { Platform, ScrollView, StyleSheet, Text, TextInput, TouchableOpacity, View, } from "react-native"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { useNavigation } from "@react-navigation/native"; import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; import BrandLockup from "../components/BrandLockup"; import ExitGameButton from "../components/ExitGameButton"; import { useI18n } from "../i18n"; import type { RootStackParamList } from "../navigation/types"; import { useSession } from "../state/session-context"; import { useTheme, type AppTheme } from "../theme"; export default function LobbyScreen() { const navigation = useNavigation>(); const manager = useSession(); const { t } = useI18n(); const theme = useTheme(); const styles = useMemo(() => createStyles(theme), [theme]); const placeholderColor = theme.colors.placeholder; const [dummyName, setDummyName] = useState(""); const [dummyBalance, setDummyBalance] = useState("1500"); const insets = useSafeAreaInsets(); const topInset = insets.top || (Platform.OS === "ios" ? 44 : 0); const customers = manager.session?.players.filter((player) => player.role !== "banker") ?? []; const assistedCount = customers.filter((player) => player.isDummy).length; useEffect(() => { if (!manager.session || !manager.me) return; if (manager.session.status === "active") { navigation.replace(manager.isBanker ? "BankerTabs" : "PlayerTabs"); } }, [manager.session, manager.me, manager.isBanker, navigation]); if (!manager.session || !manager.me) { return ( {t("common.loadingLobby")} {manager.error ? {manager.error} : null} ); } const session = manager.session; const me = manager.me; const canStart = manager.isBanker && session.status === "lobby"; const pendingTakeover = session.takeoverRequests.find( (request) => request.requesterId === manager.playerId && request.status === "pending", ); const pendingRequests = manager.isBanker ? session.takeoverRequests.filter((request) => request.status === "pending") : []; return ( {t("lobby.code", { code: session.code })} {manager.isBanker ? t("lobby.heroAdvisor") : t("lobby.heroCustomer")} {customers.length} {t("lobby.customers")} {assistedCount} {t("lobby.assisted")} {pendingTakeover ? ( {t("entry.takeoverPending")} ) : null} {t("lobby.rosterTitle")} {session.players.map((item) => ( {item.name} {item.role === "banker" ? t("common.banker") : t("common.player")} {item.isDummy ? ` ยท ${t("common.dummy")}` : ""} {item.connected ? t("common.online") : t("common.offline")} ))} {manager.isBanker && pendingRequests.length > 0 ? ( {t("banker.takeoverApprovals")} {pendingRequests.map((request) => { const requester = session.players.find((player) => player.id === request.requesterId) ?? null; const dummy = session.players.find((player) => player.id === request.dummyId) ?? null; const requesterName = requester?.name ?? request.requesterName ?? t("common.player"); return ( {requesterName} {t("banker.wants", { name: dummy?.name ?? t("common.dummy") })} manager.sendMessage({ type: "banker_takeover_approve", sessionId: manager.sessionId, bankerId: me.id, dummyId: request.dummyId, requesterId: request.requesterId, }) } > {t("banker.approve")} ); })} ) : null} {manager.isBanker ? ( {t("lobby.addDummyTitle")} {t("lobby.addDummySubtitle")} { manager.sendMessage({ type: "banker_create_dummy", sessionId: manager.sessionId, bankerId: me.id, name: dummyName, balance: Number(dummyBalance) || undefined, }); setDummyName(""); setDummyBalance("1500"); }} > {t("lobby.addDummyButton")} ) : ( {t("lobby.waitingTitle")} {t("lobby.waitingBody")} )} {canStart ? ( manager.sendMessage({ type: "banker_start", sessionId: manager.sessionId, bankerId: me.id, }) } > {t("lobby.startGame")} ) : null} ); } const createStyles = (theme: AppTheme) => StyleSheet.create({ scroll: { flex: 1, backgroundColor: theme.colors.background, }, loadingContainer: { flex: 1, gap: 16, backgroundColor: theme.colors.background, justifyContent: "center", }, loadingText: { color: theme.colors.text, fontSize: 20, fontWeight: "700", }, hero: { borderRadius: 28, padding: 22, gap: 12, backgroundColor: theme.colors.brandSurface, borderWidth: 1, borderColor: theme.colors.brandSurfaceAlt, }, heroTitle: { color: theme.colors.brandText, fontSize: 26, fontWeight: "800", letterSpacing: -0.8, }, heroBody: { color: theme.colors.brandTextMuted, fontSize: 15, lineHeight: 22, }, metrics: { flexDirection: "row", gap: 12, }, metricCard: { flex: 1, borderRadius: 18, padding: 14, backgroundColor: theme.colors.brandSurfaceAlt, gap: 4, }, metricValue: { color: theme.colors.brandText, fontSize: 22, fontWeight: "800", }, metricLabel: { color: theme.colors.brandTextMuted, fontSize: 12, textTransform: "uppercase", letterSpacing: 1, }, noticeCard: { borderRadius: 18, padding: 14, backgroundColor: theme.colors.warningSurface, borderWidth: 1, borderColor: theme.colors.warningBorder, }, noticeText: { color: theme.colors.warningTextStrong, fontWeight: "600", }, card: { backgroundColor: theme.colors.surface, borderRadius: 24, padding: 20, gap: 12, borderWidth: 1, borderColor: theme.colors.border, }, cardTitle: { color: theme.colors.text, fontSize: 20, fontWeight: "700", }, cardSubtitle: { color: theme.colors.textMuted, lineHeight: 21, }, roster: { gap: 10, }, listItem: { backgroundColor: theme.colors.surfaceAlt, borderRadius: 18, padding: 14, flexDirection: "row", justifyContent: "space-between", alignItems: "center", gap: 12, }, listCopy: { flex: 1, gap: 3, }, playerName: { fontWeight: "700", color: theme.colors.text, }, playerMeta: { fontSize: 12, color: theme.colors.textMuted, }, statusText: { color: theme.colors.textMuted, fontSize: 12, fontWeight: "600", textTransform: "uppercase", letterSpacing: 0.8, }, input: { borderWidth: 1, borderColor: theme.colors.border, backgroundColor: theme.colors.inputBackground, color: theme.colors.inputText, borderRadius: 16, paddingHorizontal: 14, paddingVertical: 13, }, button: { backgroundColor: theme.colors.primary, paddingVertical: 15, borderRadius: 999, alignItems: "center", }, buttonText: { color: theme.colors.primaryText, fontWeight: "700", }, buttonSecondary: { backgroundColor: theme.colors.secondary, paddingVertical: 14, borderRadius: 999, alignItems: "center", }, buttonSecondaryText: { color: theme.colors.secondaryText, fontWeight: "700", }, waitingCard: { backgroundColor: theme.colors.accentSurface, borderRadius: 24, padding: 20, gap: 8, borderWidth: 1, borderColor: theme.colors.borderMuted, }, waitingTitle: { color: theme.colors.text, fontSize: 18, fontWeight: "700", }, waitingBody: { color: theme.colors.textMuted, lineHeight: 21, }, helper: { color: theme.colors.textMuted, fontSize: 12, }, takeoverList: { gap: 10, }, takeoverRow: { borderRadius: 18, padding: 14, backgroundColor: theme.colors.surfaceAlt, borderWidth: 1, borderColor: theme.colors.borderMuted, flexDirection: "row", alignItems: "center", gap: 12, }, takeoverMeta: { flex: 1, gap: 3, }, takeoverName: { fontWeight: "700", color: theme.colors.text, }, takeoverSub: { color: theme.colors.textMuted, fontSize: 12, }, buttonSmall: { backgroundColor: theme.colors.primary, borderRadius: 999, paddingHorizontal: 14, paddingVertical: 10, }, buttonSmallText: { color: theme.colors.primaryText, fontWeight: "700", }, });