global claim fix attempt #1

This commit is contained in:
bobbert committed 2026-04-09 22:32:45 +01:00
1 parent 768c4ec7e2
commit 05747933cf
4 files changed
+87 -27

No files matched your search

+39 -13
View File
@@ -2,36 +2,62 @@ import React, {useEffect, useRef, useState} from 'react';
import {StyleSheet, Text, View} from 'react-native'; import {StyleSheet, Text, View} from 'react-native';
import {CACHE_CLAIM_TIMER} from '../../utils/geoMath'; import {CACHE_CLAIM_TIMER} from '../../utils/geoMath';
const ClaimTimerView = ({ cache, onClaimSuccess, isClaiming, showClaimedPopup }) => { const ClaimTimerView = ({
const [timeLeft, setTimeLeft] = useState(CACHE_CLAIM_TIMER); cache,
// Use a ref for the callback so it does not appear in the dependency array onClaimSuccess,
isClaiming,
showClaimedPopup,
claimDurationSeconds = CACHE_CLAIM_TIMER,
claimedPopupMessage = 'Cache Claimed!',
}) => {
const [timeLeft, setTimeLeft] = useState(claimDurationSeconds);
const onClaimRef = useRef(onClaimSuccess); const onClaimRef = useRef(onClaimSuccess);
const hasClaimedRef = useRef(false);
onClaimRef.current = onClaimSuccess; onClaimRef.current = onClaimSuccess;
useEffect(() => {
setTimeLeft(claimDurationSeconds);
hasClaimedRef.current = false;
}, [cache?.id, claimDurationSeconds]);
useEffect(() => { useEffect(() => {
let timer; let timer;
if (isClaiming && cache && timeLeft > 0) {
timer = setTimeout(() => setTimeLeft((prev) => prev - 1), 1000); if (!isClaiming || !cache) {
} else if (isClaiming && timeLeft === 0 && cache) { if (!isClaiming) {
onClaimRef.current(cache.id); setTimeLeft(claimDurationSeconds);
} else if (!isClaiming) { hasClaimedRef.current = false;
setTimeLeft(CACHE_CLAIM_TIMER);
} }
return () => clearTimeout(timer); return () => clearTimeout(timer);
}, [isClaiming, timeLeft, cache]); }
if (claimDurationSeconds <= 0) {
if (!hasClaimedRef.current) {
hasClaimedRef.current = true;
onClaimRef.current(cache.id);
}
return () => clearTimeout(timer);
}
if (timeLeft > 0) {
timer = setTimeout(() => setTimeLeft((prev) => prev - 1), 1000);
} else if (!hasClaimedRef.current) {
hasClaimedRef.current = true;
onClaimRef.current(cache.id);
}
return () => clearTimeout(timer);
}, [claimDurationSeconds, cache, isClaiming, timeLeft]);
// Show "Cache Claimed!" popup after a successful claim
if (showClaimedPopup) { if (showClaimedPopup) {
return ( return (
<View style={styles.claimedOverlay}> <View style={styles.claimedOverlay}>
<Text style={styles.claimedText}>Cache Claimed!</Text> <Text style={styles.claimedText}>{claimedPopupMessage}</Text>
</View> </View>
); );
} }
if (!isClaiming || !cache) { if (!isClaiming || !cache || claimDurationSeconds <= 0) {
return null; return null;
} }
@@ -23,6 +23,8 @@ const GlobalCacheViewScreen = ({ navigation, route }) => {
const handleBackToMap = () => { const handleBackToMap = () => {
navigation.navigate("GlobalMapScreen", { navigation.navigate("GlobalMapScreen", {
eventId: cache.CacheEventID ?? session.currentGlobalEventId, eventId: cache.CacheEventID ?? session.currentGlobalEventId,
event: route.params?.event ?? null,
cache,
selectedCacheId: cache.CacheID, selectedCacheId: cache.CacheID,
}); });
}; };
@@ -93,7 +93,10 @@ const GlobalEventsScreen = ({ navigation }) => {
const existingPlayerId = pickPlayerId(existing); const existingPlayerId = pickPlayerId(existing);
if (existingPlayerId !== null) { if (existingPlayerId !== null) {
setGlobalSession(event.EventID, existingPlayerId); setGlobalSession(event.EventID, existingPlayerId);
navigation.navigate("GlobalMapScreen", { eventId: event.EventID }); navigation.navigate("GlobalMapScreen", {
eventId: event.EventID,
event,
});
setJoining(null); setJoining(null);
return; return;
} }
@@ -107,7 +110,10 @@ const GlobalEventsScreen = ({ navigation }) => {
const joinedPlayerId = pickPlayerId(player); const joinedPlayerId = pickPlayerId(player);
if (joinedPlayerId !== null) { if (joinedPlayerId !== null) {
setGlobalSession(event.EventID, joinedPlayerId); setGlobalSession(event.EventID, joinedPlayerId);
navigation.navigate("GlobalMapScreen", { eventId: event.EventID }); navigation.navigate("GlobalMapScreen", {
eventId: event.EventID,
event,
});
setJoining(null); setJoining(null);
return; return;
} }
@@ -123,7 +129,10 @@ const GlobalEventsScreen = ({ navigation }) => {
const recoveredPlayerId = pickPlayerId(recovered); const recoveredPlayerId = pickPlayerId(recovered);
if (recoveredPlayerId !== null) { if (recoveredPlayerId !== null) {
setGlobalSession(event.EventID, recoveredPlayerId); setGlobalSession(event.EventID, recoveredPlayerId);
navigation.navigate("GlobalMapScreen", { eventId: event.EventID }); navigation.navigate("GlobalMapScreen", {
eventId: event.EventID,
event,
});
} else { } else {
setError("Failed to join event. Please try again."); setError("Failed to join event. Please try again.");
} }
@@ -25,7 +25,9 @@ const GlobalMapScreen = ({ navigation, route }) => {
// Initialisations --------------------- // Initialisations ---------------------
const session = getSession(); const session = getSession();
const eventId = route?.params?.eventId ?? session.currentGlobalEventId; const routeEvent = route?.params?.event ?? null;
const eventId =
route?.params?.eventId ?? routeEvent?.EventID ?? session.currentGlobalEventId;
const { getCachesByEvent, getFindsByPlayer, logFind } = useGlobalHook(); const { getCachesByEvent, getFindsByPlayer, logFind } = useGlobalHook();
const globalApiRef = useRef({ const globalApiRef = useRef({
getCachesByEvent, getCachesByEvent,
@@ -47,8 +49,11 @@ const GlobalMapScreen = ({ navigation, route }) => {
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [activeTab, setActiveTab] = useState("map"); const [activeTab, setActiveTab] = useState("map");
const [error, setError] = useState(""); const [error, setError] = useState("");
const [selectedCacheId, setSelectedCacheId] = useState(null); const [selectedCacheId, setSelectedCacheId] = useState(
route?.params?.selectedCacheId ?? route?.params?.cache?.CacheID ?? null,
);
const [claimedPopupVisible, setClaimedPopupVisible] = useState(false); const [claimedPopupVisible, setClaimedPopupVisible] = useState(false);
const [claimedPopupMessage, setClaimedPopupMessage] = useState("Cache Claimed!");
const claimableCaches = useMemo( const claimableCaches = useMemo(
() => () =>
@@ -114,6 +119,10 @@ const GlobalMapScreen = ({ navigation, route }) => {
return; return;
} }
const claimedCache = (caches || []).find(
(cache) => String(cache.CacheID) === String(cacheId),
);
const result = await globalApiRef.current.logFind({ const result = await globalApiRef.current.logFind({
FindPlayerID: session.currentGlobalPlayerId, FindPlayerID: session.currentGlobalPlayerId,
FindCacheID: cacheId, FindCacheID: cacheId,
@@ -123,12 +132,19 @@ const GlobalMapScreen = ({ navigation, route }) => {
setIsClaiming(false); setIsClaiming(false);
if (result) { if (result) {
const points = Number(claimedCache?.CachePoints ?? 0);
const cacheName = claimedCache?.CacheName || "Cache";
setFoundCacheIds((prev) =>
prev.includes(cacheId) ? prev : [...prev, cacheId],
);
setClaimedPopupMessage(
`${cacheName} claimed! You received ${points} points.`,
);
setClaimedPopupVisible(true); setClaimedPopupVisible(true);
setTimeout(() => setClaimedPopupVisible(false), 3000); setTimeout(() => setClaimedPopupVisible(false), 3000);
await loadData({ forceRefresh: true });
} }
}, },
[foundCacheIds, loadData, session.currentGlobalPlayerId, setIsClaiming], [caches, foundCacheIds, session.currentGlobalPlayerId, setIsClaiming],
); );
const handleCacheSelect = (cache) => { const handleCacheSelect = (cache) => {
@@ -143,6 +159,8 @@ const GlobalMapScreen = ({ navigation, route }) => {
if (!selected) return; if (!selected) return;
navigation.navigate("GlobalCacheViewScreen", { navigation.navigate("GlobalCacheViewScreen", {
cache: selected, cache: selected,
event: routeEvent,
eventId,
isFound: foundCacheIds.includes(selected.CacheID), isFound: foundCacheIds.includes(selected.CacheID),
}); });
}; };
@@ -197,14 +215,15 @@ const GlobalMapScreen = ({ navigation, route }) => {
}, [route?.params?.selectedCacheId]); }, [route?.params?.selectedCacheId]);
useEffect(() => { useEffect(() => {
if ( if (route?.params?.cache?.CacheID) {
selectedCacheId && setSelectedCacheId(route.params.cache.CacheID);
claimableCaches.some((cache) => cache.id === selectedCacheId)
) {
return;
} }
setSelectedCacheId(claimableCaches[0]?.id || null); }, [route?.params?.cache?.CacheID]);
}, [claimableCaches, selectedCacheId]);
useEffect(() => {
if (selectedCacheId) return;
setSelectedCacheId(route?.params?.cache?.CacheID ?? claimableCaches[0]?.id ?? null);
}, [claimableCaches, route?.params?.cache?.CacheID, selectedCacheId]);
useEffect(() => { useEffect(() => {
let locationSub; let locationSub;
@@ -318,6 +337,8 @@ const GlobalMapScreen = ({ navigation, route }) => {
onCalloutPress={() => onCalloutPress={() =>
navigation.navigate("GlobalCacheViewScreen", { navigation.navigate("GlobalCacheViewScreen", {
cache, cache,
event: routeEvent,
eventId,
isFound: found, isFound: found,
}) })
} }
@@ -356,6 +377,8 @@ const GlobalMapScreen = ({ navigation, route }) => {
isClaiming={isClaiming} isClaiming={isClaiming}
onClaimSuccess={handleClaim} onClaimSuccess={handleClaim}
showClaimedPopup={claimedPopupVisible} showClaimedPopup={claimedPopupVisible}
claimDurationSeconds={0}
claimedPopupMessage={claimedPopupMessage}
/> />
<ButtonTray> <ButtonTray>