mirror of
https://github.com/mudabbir-ahmad/MAD-Treasure-Hunt.git
synced 2026-10-08 03:00:20 +00:00
global claim fix attempt #1
This commit is contained in:
1 parent
768c4ec7e2
commit
05747933cf
4 files changed
+87
-27
No files matched your search
@@ -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>
|
||||||
|
|||||||
Reference in new issue
Block a user