mirror of
https://github.com/mudabbir-ahmad/MAD-Treasure-Hunt.git
synced 2026-10-07 19:00:20 +00:00
refactored app theme
changed texts to suit dark theme.
This commit is contained in:
1 parent
07b12cdd0f
commit
12847cc46c
5 files changed
+204
-144
No files matched your search
@@ -1,10 +1,10 @@
|
||||
import {useEffect} from "react";
|
||||
import {StyleSheet, Text, View} from "react-native";
|
||||
import { useEffect } from "react";
|
||||
import { StyleSheet, Text, View } from "react-native";
|
||||
import Screen from "../../layout/Screen";
|
||||
import {Button, ButtonTray} from "../../UI/Button";
|
||||
import { Button, ButtonTray } from "../../UI/Button";
|
||||
import Card from "../../UI/Card";
|
||||
import {getSession} from "../../../hooks/SessionStore";
|
||||
import {GAME_MODE} from "../../../utils/gameConstants";
|
||||
import { getSession } from "../../../hooks/SessionStore";
|
||||
import { GAME_MODE } from "../../../utils/gameConstants";
|
||||
|
||||
const GlobalCacheViewScreen = ({ navigation, route }) => {
|
||||
// Initialisations ---------------------
|
||||
@@ -67,7 +67,8 @@ const GlobalCacheViewScreen = ({ navigation, route }) => {
|
||||
|
||||
{!initIsFound ? (
|
||||
<Text style={styles.claimHint}>
|
||||
Claim this cache from the Global Map while within 30m and facing it.
|
||||
Claim this cache from the Global Map while within 30m and facing
|
||||
it.
|
||||
</Text>
|
||||
) : null}
|
||||
</Card>
|
||||
@@ -91,7 +92,7 @@ const styles = StyleSheet.create({
|
||||
title: {
|
||||
fontSize: 22,
|
||||
fontWeight: "700",
|
||||
color: "#111827",
|
||||
color: "#cdd6f4",
|
||||
},
|
||||
statusBadge: {
|
||||
alignSelf: "flex-start",
|
||||
@@ -100,15 +101,15 @@ const styles = StyleSheet.create({
|
||||
borderRadius: 12,
|
||||
},
|
||||
badgeFound: {
|
||||
backgroundColor: "#d1fae5",
|
||||
backgroundColor: "#1e3a2f",
|
||||
},
|
||||
badgeOpen: {
|
||||
backgroundColor: "#fef3c7",
|
||||
backgroundColor: "#3d3117",
|
||||
},
|
||||
statusText: {
|
||||
fontSize: 13,
|
||||
fontWeight: "600",
|
||||
color: "#374151",
|
||||
color: "#cdd6f4",
|
||||
},
|
||||
detailRow: {
|
||||
gap: 2,
|
||||
@@ -116,17 +117,17 @@ const styles = StyleSheet.create({
|
||||
label: {
|
||||
fontSize: 12,
|
||||
fontWeight: "600",
|
||||
color: "#6b7280",
|
||||
color: "#a6adc8",
|
||||
textTransform: "uppercase",
|
||||
letterSpacing: 0.5,
|
||||
},
|
||||
value: {
|
||||
fontSize: 15,
|
||||
color: "#111827",
|
||||
color: "#cdd6f4",
|
||||
},
|
||||
claimHint: {
|
||||
marginTop: 6,
|
||||
color: "#2563eb",
|
||||
color: "#89b4fa",
|
||||
fontSize: 13,
|
||||
fontWeight: "600",
|
||||
},
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
import {useCallback, useEffect, useRef, useState} from "react";
|
||||
import {ActivityIndicator, StyleSheet, Text, View} from "react-native";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { ActivityIndicator, StyleSheet, Text, View } from "react-native";
|
||||
import Screen from "../../layout/Screen";
|
||||
import {Button, ButtonTray} from "../../UI/Button";
|
||||
import { Button, ButtonTray } from "../../UI/Button";
|
||||
import EventList from "../../../entity/event/EventList";
|
||||
import useGlobalHook from "../../../hooks/useGlobalHook";
|
||||
import {getSession, setGlobalSession} from "../../../hooks/SessionStore";
|
||||
import {GAME_MODE} from "../../../utils/gameConstants";
|
||||
import { getSession, setGlobalSession } from "../../../hooks/SessionStore";
|
||||
import { GAME_MODE } from "../../../utils/gameConstants";
|
||||
|
||||
const GlobalEventsScreen = ({ navigation }) => {
|
||||
// Initialisations ---------------------
|
||||
|
||||
const {
|
||||
getPublicEvents,
|
||||
getPlayersByEvent,
|
||||
joinEvent,
|
||||
isGlobalApiReady,
|
||||
} = useGlobalHook();
|
||||
const { getPublicEvents, getPlayersByEvent, joinEvent, isGlobalApiReady } =
|
||||
useGlobalHook();
|
||||
const session = getSession();
|
||||
const globalApiRef = useRef({
|
||||
getPublicEvents,
|
||||
@@ -45,7 +41,9 @@ const GlobalEventsScreen = ({ navigation }) => {
|
||||
|
||||
if (!globalApiRef.current.isGlobalApiReady()) {
|
||||
setEvents([]);
|
||||
setError("Global API URL is not configured yet. Add it in src/components/API/api.json.");
|
||||
setError(
|
||||
"Global API URL is not configured yet. Add it in src/components/API/api.json.",
|
||||
);
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
@@ -68,7 +66,9 @@ const GlobalEventsScreen = ({ navigation }) => {
|
||||
setJoining(event.EventID);
|
||||
|
||||
if (!globalApiRef.current.isGlobalApiReady()) {
|
||||
setError("Global API URL is not configured yet. Add it in src/components/API/api.json.");
|
||||
setError(
|
||||
"Global API URL is not configured yet. Add it in src/components/API/api.json.",
|
||||
);
|
||||
setJoining(null);
|
||||
return;
|
||||
}
|
||||
@@ -82,7 +82,10 @@ const GlobalEventsScreen = ({ navigation }) => {
|
||||
};
|
||||
|
||||
// Check if already a player
|
||||
const players = await globalApiRef.current.getPlayersByEvent(event.EventID, {forceRefresh: true});
|
||||
const players = await globalApiRef.current.getPlayersByEvent(
|
||||
event.EventID,
|
||||
{ forceRefresh: true },
|
||||
);
|
||||
const existing = (players || []).find(
|
||||
(p) => String(p.PlayerUserID) === String(globalUserId),
|
||||
);
|
||||
@@ -110,7 +113,10 @@ const GlobalEventsScreen = ({ navigation }) => {
|
||||
}
|
||||
|
||||
// If create fails due duplicate race/server behavior, recover by re-reading players.
|
||||
const refreshedPlayers = await globalApiRef.current.getPlayersByEvent(event.EventID, {forceRefresh: true});
|
||||
const refreshedPlayers = await globalApiRef.current.getPlayersByEvent(
|
||||
event.EventID,
|
||||
{ forceRefresh: true },
|
||||
);
|
||||
const recovered = (refreshedPlayers || []).find(
|
||||
(p) => String(p.PlayerUserID) === String(globalUserId),
|
||||
);
|
||||
@@ -131,7 +137,10 @@ const GlobalEventsScreen = ({ navigation }) => {
|
||||
<Screen>
|
||||
<View style={styles.container}>
|
||||
<ButtonTray>
|
||||
<Button label="Refresh" onClick={() => loadEvents({forceRefresh: true})} />
|
||||
<Button
|
||||
label="Refresh"
|
||||
onClick={() => loadEvents({ forceRefresh: true })}
|
||||
/>
|
||||
</ButtonTray>
|
||||
|
||||
{error ? <Text style={styles.error}>{error}</Text> : null}
|
||||
@@ -174,21 +183,21 @@ const styles = StyleSheet.create({
|
||||
gap: 10,
|
||||
},
|
||||
loadingText: {
|
||||
color: "#6b7280",
|
||||
color: "#a6adc8",
|
||||
fontSize: 14,
|
||||
},
|
||||
empty: {
|
||||
textAlign: "center",
|
||||
color: "#9ca3af",
|
||||
color: "#a6adc8",
|
||||
marginTop: 30,
|
||||
fontSize: 15,
|
||||
},
|
||||
hint: {
|
||||
fontSize: 13,
|
||||
color: "#6b7280",
|
||||
color: "#a6adc8",
|
||||
},
|
||||
error: {
|
||||
color: "#dc2626",
|
||||
color: "#f38ba8",
|
||||
fontSize: 14,
|
||||
},
|
||||
overlay: {
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import {useCallback, useEffect, useRef, useState} from "react";
|
||||
import {ActivityIndicator, ScrollView, StyleSheet, Text, View,} from "react-native";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from "react-native";
|
||||
import Screen from "../../layout/Screen";
|
||||
import {Button, ButtonTray} from "../../UI/Button";
|
||||
import { Button, ButtonTray } from "../../UI/Button";
|
||||
import Card from "../../UI/Card";
|
||||
import FindList from "../../../entity/find/FindList";
|
||||
import useGlobalHook from "../../../hooks/useGlobalHook";
|
||||
import {getSession} from "../../../hooks/SessionStore";
|
||||
import {GAME_MODE} from "../../../utils/gameConstants";
|
||||
import { getSession } from "../../../hooks/SessionStore";
|
||||
import { GAME_MODE } from "../../../utils/gameConstants";
|
||||
|
||||
const GlobalLeaderboardScreen = ({ navigation, route }) => {
|
||||
// Initialisations ---------------------
|
||||
@@ -35,75 +41,78 @@ const GlobalLeaderboardScreen = ({ navigation, route }) => {
|
||||
|
||||
// Handlers ----------------------------
|
||||
|
||||
const loadData = useCallback(async (options = {}) => {
|
||||
if (!eventId) return;
|
||||
const loadData = useCallback(
|
||||
async (options = {}) => {
|
||||
if (!eventId) return;
|
||||
|
||||
setIsLoading(true);
|
||||
setIsLoading(true);
|
||||
|
||||
const [finds, caches, players] = await Promise.all([
|
||||
globalApiRef.current.getFindsByEvent(eventId, options),
|
||||
globalApiRef.current.getCachesByEvent(eventId, options),
|
||||
globalApiRef.current.getPlayersByEvent(eventId, options),
|
||||
]);
|
||||
const [finds, caches, players] = await Promise.all([
|
||||
globalApiRef.current.getFindsByEvent(eventId, options),
|
||||
globalApiRef.current.getCachesByEvent(eventId, options),
|
||||
globalApiRef.current.getPlayersByEvent(eventId, options),
|
||||
]);
|
||||
|
||||
// Build cache points lookup
|
||||
const cacheMap = {};
|
||||
(caches || []).forEach((c) => {
|
||||
cacheMap[String(c.CacheID)] = c;
|
||||
});
|
||||
// Build cache points lookup
|
||||
const cacheMap = {};
|
||||
(caches || []).forEach((c) => {
|
||||
cacheMap[String(c.CacheID)] = c;
|
||||
});
|
||||
|
||||
// Augment finds with cache info for FindList
|
||||
const augmented = (finds || []).map((f) => ({
|
||||
...f,
|
||||
FindCache: f.FindCache || cacheMap[String(f.FindCacheID)] || null,
|
||||
}));
|
||||
// Augment finds with cache info for FindList
|
||||
const augmented = (finds || []).map((f) => ({
|
||||
...f,
|
||||
FindCache: f.FindCache || cacheMap[String(f.FindCacheID)] || null,
|
||||
}));
|
||||
|
||||
// Sort recent first
|
||||
const sorted = [...augmented].sort(
|
||||
(a, b) => new Date(b.FindDatetime) - new Date(a.FindDatetime),
|
||||
);
|
||||
setRecentFinds(sorted.slice(0, 50));
|
||||
// Sort recent first
|
||||
const sorted = [...augmented].sort(
|
||||
(a, b) => new Date(b.FindDatetime) - new Date(a.FindDatetime),
|
||||
);
|
||||
setRecentFinds(sorted.slice(0, 50));
|
||||
|
||||
// Start ranking map with all players so zero-point players are visible.
|
||||
const pointsMap = {};
|
||||
(players || []).forEach((p) => {
|
||||
const pid = p.PlayerID;
|
||||
pointsMap[String(pid)] = {
|
||||
playerId: pid,
|
||||
points: Number(p.PlayerPoints || 0),
|
||||
finds: 0,
|
||||
name: p.PlayerUser?.UserUsername || `Player #${p.PlayerUserID}`,
|
||||
};
|
||||
});
|
||||
|
||||
// Aggregate points and finds from recorded discoveries.
|
||||
augmented.forEach((f) => {
|
||||
const pid = f.FindPlayerID;
|
||||
const key = String(pid);
|
||||
const pts = Number(f.FindCache?.CachePoints || 0);
|
||||
|
||||
if (!pointsMap[key]) {
|
||||
pointsMap[key] = {
|
||||
// Start ranking map with all players so zero-point players are visible.
|
||||
const pointsMap = {};
|
||||
(players || []).forEach((p) => {
|
||||
const pid = p.PlayerID;
|
||||
pointsMap[String(pid)] = {
|
||||
playerId: pid,
|
||||
points: 0,
|
||||
points: Number(p.PlayerPoints || 0),
|
||||
finds: 0,
|
||||
name: `Player #${f.FindPlayerID}`,
|
||||
name: p.PlayerUser?.UserUsername || `Player #${p.PlayerUserID}`,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
pointsMap[key].points += pts;
|
||||
pointsMap[key].finds += 1;
|
||||
});
|
||||
// Aggregate points and finds from recorded discoveries.
|
||||
augmented.forEach((f) => {
|
||||
const pid = f.FindPlayerID;
|
||||
const key = String(pid);
|
||||
const pts = Number(f.FindCache?.CachePoints || 0);
|
||||
|
||||
const ranked = Object.values(pointsMap).sort((a, b) => {
|
||||
if (b.points !== a.points) return b.points - a.points;
|
||||
if (b.finds !== a.finds) return b.finds - a.finds;
|
||||
return String(a.name || "").localeCompare(String(b.name || ""));
|
||||
});
|
||||
if (!pointsMap[key]) {
|
||||
pointsMap[key] = {
|
||||
playerId: pid,
|
||||
points: 0,
|
||||
finds: 0,
|
||||
name: `Player #${f.FindPlayerID}`,
|
||||
};
|
||||
}
|
||||
|
||||
setRankings(ranked);
|
||||
setIsLoading(false);
|
||||
}, [eventId]);
|
||||
pointsMap[key].points += pts;
|
||||
pointsMap[key].finds += 1;
|
||||
});
|
||||
|
||||
const ranked = Object.values(pointsMap).sort((a, b) => {
|
||||
if (b.points !== a.points) return b.points - a.points;
|
||||
if (b.finds !== a.finds) return b.finds - a.finds;
|
||||
return String(a.name || "").localeCompare(String(b.name || ""));
|
||||
});
|
||||
|
||||
setRankings(ranked);
|
||||
setIsLoading(false);
|
||||
},
|
||||
[eventId],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (session.isBusiness || session.currentGameMode !== GAME_MODE.GLOBAL) {
|
||||
@@ -126,12 +135,21 @@ const GlobalLeaderboardScreen = ({ navigation, route }) => {
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!eventId || session.currentGameMode !== GAME_MODE.GLOBAL || !session.currentGlobalPlayerId) {
|
||||
if (
|
||||
!eventId ||
|
||||
session.currentGameMode !== GAME_MODE.GLOBAL ||
|
||||
!session.currentGlobalPlayerId
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
loadData();
|
||||
}, [eventId, loadData, session.currentGameMode, session.currentGlobalPlayerId]);
|
||||
}, [
|
||||
eventId,
|
||||
loadData,
|
||||
session.currentGameMode,
|
||||
session.currentGlobalPlayerId,
|
||||
]);
|
||||
|
||||
// View --------------------------------
|
||||
|
||||
@@ -199,7 +217,10 @@ const GlobalLeaderboardScreen = ({ navigation, route }) => {
|
||||
)}
|
||||
|
||||
<ButtonTray>
|
||||
<Button label="Refresh" onClick={() => loadData({forceRefresh: true})} />
|
||||
<Button
|
||||
label="Refresh"
|
||||
onClick={() => loadData({ forceRefresh: true })}
|
||||
/>
|
||||
</ButtonTray>
|
||||
</View>
|
||||
</Screen>
|
||||
@@ -222,13 +243,13 @@ const tabStyles = StyleSheet.create({
|
||||
paddingVertical: 8,
|
||||
fontSize: 14,
|
||||
fontWeight: "600",
|
||||
color: "#6b7280",
|
||||
color: "#a6adc8",
|
||||
borderBottomWidth: 2,
|
||||
borderBottomColor: "transparent",
|
||||
},
|
||||
activeTab: {
|
||||
color: "#111827",
|
||||
borderBottomColor: "#111827",
|
||||
color: "#cdd6f4",
|
||||
borderBottomColor: "#89b4fa",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -244,7 +265,7 @@ const styles = StyleSheet.create({
|
||||
tabs: {
|
||||
flexDirection: "row",
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: "#e5e7eb",
|
||||
borderBottomColor: "#45475a",
|
||||
},
|
||||
rankList: {
|
||||
gap: 6,
|
||||
@@ -254,7 +275,7 @@ const styles = StyleSheet.create({
|
||||
marginBottom: 0,
|
||||
},
|
||||
myCard: {
|
||||
borderColor: "#2563eb",
|
||||
borderColor: "#89b4fa",
|
||||
borderWidth: 2,
|
||||
},
|
||||
rankRow: {
|
||||
@@ -265,14 +286,14 @@ const styles = StyleSheet.create({
|
||||
rankPos: {
|
||||
fontSize: 16,
|
||||
fontWeight: "700",
|
||||
color: "#6b7280",
|
||||
color: "#a6adc8",
|
||||
width: 32,
|
||||
},
|
||||
rankName: {
|
||||
flex: 1,
|
||||
fontSize: 15,
|
||||
fontWeight: "600",
|
||||
color: "#111827",
|
||||
color: "#cdd6f4",
|
||||
},
|
||||
rankRight: {
|
||||
alignItems: "flex-end",
|
||||
@@ -280,15 +301,15 @@ const styles = StyleSheet.create({
|
||||
rankPoints: {
|
||||
fontSize: 16,
|
||||
fontWeight: "700",
|
||||
color: "#16a34a",
|
||||
color: "#a6e3a1",
|
||||
},
|
||||
rankFinds: {
|
||||
fontSize: 12,
|
||||
color: "#9ca3af",
|
||||
color: "#a6adc8",
|
||||
},
|
||||
empty: {
|
||||
textAlign: "center",
|
||||
color: "#9ca3af",
|
||||
color: "#a6adc8",
|
||||
marginTop: 30,
|
||||
fontSize: 15,
|
||||
},
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import {useCallback, useEffect, useMemo, useRef, useState} from "react";
|
||||
import {ActivityIndicator, StyleSheet, Text, View} from "react-native";
|
||||
import MapView, {Circle, Marker, Polygon} from "react-native-maps";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { ActivityIndicator, StyleSheet, Text, View } from "react-native";
|
||||
import MapView, { Circle, Marker, Polygon } from "react-native-maps";
|
||||
import * as Location from "expo-location";
|
||||
import Screen from "../../layout/Screen";
|
||||
import {Button, ButtonTray} from "../../UI/Button";
|
||||
import { Button, ButtonTray } from "../../UI/Button";
|
||||
import ClaimTimerView from "../../gameplay/ClaimTimerView";
|
||||
import CacheList from "../../../entity/cache/CacheList";
|
||||
import useGlobalHook from "../../../hooks/useGlobalHook";
|
||||
import usePlayerGame from "../../../hooks/usePlayerGame";
|
||||
import {getSession} from "../../../hooks/SessionStore";
|
||||
import {getFovCone} from "../../../utils/geoMath";
|
||||
import {GAME_MODE} from "../../../utils/gameConstants";
|
||||
import { getSession } from "../../../hooks/SessionStore";
|
||||
import { getFovCone } from "../../../utils/geoMath";
|
||||
import { GAME_MODE } from "../../../utils/gameConstants";
|
||||
|
||||
const DEFAULT_REGION = {
|
||||
latitude: 51.5074,
|
||||
@@ -77,23 +77,29 @@ const GlobalMapScreen = ({ navigation, route }) => {
|
||||
|
||||
// Handlers ----------------------------
|
||||
|
||||
const loadData = useCallback(async (options = {}) => {
|
||||
if (!eventId) return;
|
||||
const loadData = useCallback(
|
||||
async (options = {}) => {
|
||||
if (!eventId) return;
|
||||
|
||||
setIsLoading(true);
|
||||
setError("");
|
||||
setIsLoading(true);
|
||||
setError("");
|
||||
|
||||
const [cacheData, findsData] = await Promise.all([
|
||||
globalApiRef.current.getCachesByEvent(eventId, options),
|
||||
session.currentGlobalPlayerId
|
||||
? globalApiRef.current.getFindsByPlayer(session.currentGlobalPlayerId, options)
|
||||
: Promise.resolve([]),
|
||||
]);
|
||||
const [cacheData, findsData] = await Promise.all([
|
||||
globalApiRef.current.getCachesByEvent(eventId, options),
|
||||
session.currentGlobalPlayerId
|
||||
? globalApiRef.current.getFindsByPlayer(
|
||||
session.currentGlobalPlayerId,
|
||||
options,
|
||||
)
|
||||
: Promise.resolve([]),
|
||||
]);
|
||||
|
||||
setCaches(cacheData || []);
|
||||
setFoundCacheIds((findsData || []).map((f) => f.FindCacheID));
|
||||
setIsLoading(false);
|
||||
}, [eventId, session.currentGlobalPlayerId]);
|
||||
setCaches(cacheData || []);
|
||||
setFoundCacheIds((findsData || []).map((f) => f.FindCacheID));
|
||||
setIsLoading(false);
|
||||
},
|
||||
[eventId, session.currentGlobalPlayerId],
|
||||
);
|
||||
|
||||
const handleClaim = useCallback(
|
||||
async (cacheId) => {
|
||||
@@ -119,7 +125,7 @@ const GlobalMapScreen = ({ navigation, route }) => {
|
||||
if (result) {
|
||||
setClaimedPopupVisible(true);
|
||||
setTimeout(() => setClaimedPopupVisible(false), 3000);
|
||||
await loadData({forceRefresh: true});
|
||||
await loadData({ forceRefresh: true });
|
||||
}
|
||||
},
|
||||
[foundCacheIds, loadData, session.currentGlobalPlayerId, setIsClaiming],
|
||||
@@ -131,7 +137,9 @@ const GlobalMapScreen = ({ navigation, route }) => {
|
||||
};
|
||||
|
||||
const handleOpenSelectedCache = () => {
|
||||
const selected = (caches || []).find((cache) => cache.CacheID === selectedCacheId);
|
||||
const selected = (caches || []).find(
|
||||
(cache) => cache.CacheID === selectedCacheId,
|
||||
);
|
||||
if (!selected) return;
|
||||
navigation.navigate("GlobalCacheViewScreen", {
|
||||
cache: selected,
|
||||
@@ -166,12 +174,21 @@ const GlobalMapScreen = ({ navigation, route }) => {
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!eventId || session.currentGameMode !== GAME_MODE.GLOBAL || !session.currentGlobalPlayerId) {
|
||||
if (
|
||||
!eventId ||
|
||||
session.currentGameMode !== GAME_MODE.GLOBAL ||
|
||||
!session.currentGlobalPlayerId
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
loadData();
|
||||
}, [eventId, loadData, session.currentGameMode, session.currentGlobalPlayerId]);
|
||||
}, [
|
||||
eventId,
|
||||
loadData,
|
||||
session.currentGameMode,
|
||||
session.currentGlobalPlayerId,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
const routeSelected = route?.params?.selectedCacheId;
|
||||
@@ -180,7 +197,10 @@ const GlobalMapScreen = ({ navigation, route }) => {
|
||||
}, [route?.params?.selectedCacheId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedCacheId && claimableCaches.some((cache) => cache.id === selectedCacheId)) {
|
||||
if (
|
||||
selectedCacheId &&
|
||||
claimableCaches.some((cache) => cache.id === selectedCacheId)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
setSelectedCacheId(claimableCaches[0]?.id || null);
|
||||
@@ -291,7 +311,9 @@ const GlobalMapScreen = ({ navigation, route }) => {
|
||||
}}
|
||||
title={cache.CacheName}
|
||||
description={`${cache.CachePoints ?? 0} pts${found ? " · Found" : ""}`}
|
||||
pinColor={found ? "#22c55e" : selected ? "#f59e0b" : "#ef4444"}
|
||||
pinColor={
|
||||
found ? "#22c55e" : selected ? "#f59e0b" : "#ef4444"
|
||||
}
|
||||
onPress={() => setSelectedCacheId(cache.CacheID)}
|
||||
onCalloutPress={() =>
|
||||
navigation.navigate("GlobalCacheViewScreen", {
|
||||
@@ -337,9 +359,16 @@ const GlobalMapScreen = ({ navigation, route }) => {
|
||||
/>
|
||||
|
||||
<ButtonTray>
|
||||
<Button label="Details" onClick={handleOpenSelectedCache} disabled={!selectedCacheId} />
|
||||
<Button
|
||||
label="Details"
|
||||
onClick={handleOpenSelectedCache}
|
||||
disabled={!selectedCacheId}
|
||||
/>
|
||||
<Button label="Leaderboard" onClick={handleGotoLeaderboard} />
|
||||
<Button label="Refresh" onClick={() => loadData({forceRefresh: true})} />
|
||||
<Button
|
||||
label="Refresh"
|
||||
onClick={() => loadData({ forceRefresh: true })}
|
||||
/>
|
||||
</ButtonTray>
|
||||
</View>
|
||||
</Screen>
|
||||
@@ -362,13 +391,13 @@ const tabStyles = StyleSheet.create({
|
||||
paddingVertical: 8,
|
||||
fontSize: 14,
|
||||
fontWeight: "600",
|
||||
color: "#6b7280",
|
||||
color: "#a6adc8",
|
||||
borderBottomWidth: 2,
|
||||
borderBottomColor: "transparent",
|
||||
},
|
||||
activeTab: {
|
||||
color: "#111827",
|
||||
borderBottomColor: "#111827",
|
||||
color: "#cdd6f4",
|
||||
borderBottomColor: "#89b4fa",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -384,13 +413,13 @@ const styles = StyleSheet.create({
|
||||
tabs: {
|
||||
flexDirection: "row",
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: "#e5e7eb",
|
||||
borderBottomColor: "#45475a",
|
||||
},
|
||||
map: {
|
||||
flex: 1,
|
||||
},
|
||||
error: {
|
||||
color: "#dc2626",
|
||||
color: "#f38ba8",
|
||||
fontSize: 14,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -242,7 +242,7 @@ const styles = StyleSheet.create({
|
||||
justifyContent: "center",
|
||||
},
|
||||
error: {
|
||||
color: "#dc2626",
|
||||
color: "#f38ba8",
|
||||
fontSize: 14,
|
||||
},
|
||||
avatarWrap: {
|
||||
@@ -257,7 +257,7 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
label: {
|
||||
fontSize: 13,
|
||||
color: "#9ca3af",
|
||||
color: "#a6adc8",
|
||||
fontWeight: "600",
|
||||
},
|
||||
input: {
|
||||
|
||||
Reference in new issue
Block a user