mirror of
https://gitea.tendokyu.moe/ppc/amnet.git
synced 2026-09-27 17:27:55 +03:00
update card selection, automatically check for server startup to end
This commit is contained in:
@@ -3,8 +3,16 @@ import React, {useCallback, useEffect, useLayoutEffect, useMemo, useState} from
|
||||
import {ActivityIndicator, Button, Paragraph, Title, useTheme} from "react-native-paper";
|
||||
import {Alert, RefreshControl, ScrollView, Share, StyleSheet, Text, TouchableOpacity, View} from "react-native";
|
||||
import {
|
||||
CircleCheck, CircleDot, CreditCard, Nfc, Plus, SmartphoneNfcIcon,
|
||||
Share as ShareIcon, WifiOff, TvMinimalPlay, Star
|
||||
CircleCheck,
|
||||
CircleDot,
|
||||
CreditCard,
|
||||
Nfc,
|
||||
Plus,
|
||||
SmartphoneNfcIcon,
|
||||
Share as ShareIcon,
|
||||
WifiOff,
|
||||
TvMinimalPlay,
|
||||
Star
|
||||
} from "lucide-react-native";
|
||||
|
||||
import {EmptyStatePlaceholder} from "../components/EmptyStatePlaceholder";
|
||||
@@ -30,40 +38,24 @@ export default function ServerCardIn({route, navigation}) {
|
||||
const realm = useRealm();
|
||||
const theme = useTheme();
|
||||
|
||||
// card listing state
|
||||
let {serverId} = route.params;
|
||||
const server = useObject(AMServer, ObjectId.createFromHexString(serverId));
|
||||
const cards = useQuery({
|
||||
type: AMCard,
|
||||
query: q => q.sorted("lastUsed", true)
|
||||
});
|
||||
|
||||
const [defaultCard, setDefaultCard] = useState<AMCard>(null);
|
||||
const [selectedCard, setSelectedCard] = useState<AMCard>(null);
|
||||
const [cardInCompleted, setCardInCompleted] = useState<boolean>(null);
|
||||
|
||||
const unselectedCards = useMemo(() => {
|
||||
// protect against selected card being removed
|
||||
switch (selectedCard?.isValid()) {
|
||||
case true:
|
||||
return cards.filter(x => !x._id.equals(selectedCard._id));
|
||||
|
||||
// clear out invalid
|
||||
case false:
|
||||
setSelectedCard(null);
|
||||
return cards;
|
||||
|
||||
default:
|
||||
return cards;
|
||||
}
|
||||
}, [cards, selectedCard]);
|
||||
|
||||
// server state
|
||||
const [serverRefreshing, setServerRefreshing] = useState<boolean>(false);
|
||||
const [serverReloadCounter, setServerReloadCounter] = useState<number>(0);
|
||||
const [serverPreviousGameId, setServerPreviousGameId] = useState<string | null>(null);
|
||||
const [connectionTestResult, setConnectionTestResult] = useState<boolean | null>(null);
|
||||
|
||||
let {serverId} = route.params;
|
||||
const server = useObject(AMServer, ObjectId.createFromHexString(serverId));
|
||||
const [userSelectedCard, setUserSelectedCard] = useState<AMCard>(null);
|
||||
const [cardInCompleted, setCardInCompleted] = useState<boolean>(null);
|
||||
|
||||
const defaultCard = useMemo(() => cards.find(x => x.lastUsedGameId === server.gameId), [cards, server.gameId]);
|
||||
const selectedCard = useMemo(() => userSelectedCard ?? defaultCard ?? cards.at(1) ?? null, [userSelectedCard, defaultCard]);
|
||||
const unselectedCards = useMemo(() => cards.filter(x => x._id.toHexString() !== selectedCard?._id.toHexString()), [cards, selectedCard]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (server?.isValid() !== true) {
|
||||
@@ -80,7 +72,27 @@ export default function ServerCardIn({route, navigation}) {
|
||||
});
|
||||
}, [navigation, server]);
|
||||
|
||||
// card selection, server connection checks
|
||||
// invalid card selection
|
||||
useEffect(() => {
|
||||
if (userSelectedCard?.isValid() === false) {
|
||||
setUserSelectedCard(null);
|
||||
}
|
||||
}, [userSelectedCard]);
|
||||
|
||||
// auto-refresh
|
||||
useEffect(() => {
|
||||
if (!connectionTestResult) {
|
||||
return;
|
||||
}
|
||||
|
||||
const metrics = server as AMServerInstanceMetrics;
|
||||
if (metrics.sessionUptime > 0 && metrics.timeSinceLastPoll === null) {
|
||||
const timeout = setTimeout(() => setServerReloadCounter(serverReloadCounter + 1), 5000);
|
||||
return () => clearTimeout(timeout);
|
||||
}
|
||||
}, [connectionTestResult, server]);
|
||||
|
||||
// server info update
|
||||
useEffect(() => {
|
||||
if (server?.isValid() !== true) {
|
||||
navigation.goBack();
|
||||
@@ -92,15 +104,6 @@ export default function ServerCardIn({route, navigation}) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (defaultCard?.isValid() === false) {
|
||||
setDefaultCard(null);
|
||||
}
|
||||
|
||||
// select a card if there's none selected
|
||||
if (selectedCard?.isValid() !== true) {
|
||||
setSelectedCard(cards.length ? cards[0] : null);
|
||||
}
|
||||
|
||||
const abortController = new AbortController();
|
||||
fetchServerInfo(server.serverAddress, abortController.signal).then(r => {
|
||||
if (!r) {
|
||||
@@ -109,20 +112,11 @@ export default function ServerCardIn({route, navigation}) {
|
||||
}
|
||||
|
||||
setConnectionTestResult(true);
|
||||
|
||||
realm.write(() => {
|
||||
server.lastUsed = new Date();
|
||||
Object.keys(r).forEach(x => server[x] = r[x]);
|
||||
});
|
||||
|
||||
const matchingGameCard = cards.find(x => x.lastUsedGameId === server.gameId);
|
||||
if (matchingGameCard) {
|
||||
setDefaultCard(matchingGameCard);
|
||||
}
|
||||
|
||||
if (server.gameId !== serverPreviousGameId) {
|
||||
setServerPreviousGameId(server.gameId);
|
||||
setSelectedCard(matchingGameCard || cards[0]);
|
||||
}
|
||||
}).catch(() => {
|
||||
setConnectionTestResult(false);
|
||||
}).finally(() => {
|
||||
@@ -136,7 +130,6 @@ export default function ServerCardIn({route, navigation}) {
|
||||
}
|
||||
}, [serverId, serverReloadCounter, realm]);
|
||||
|
||||
// card in callback
|
||||
const cardInCallback = useCallback(() => {
|
||||
setCardInCompleted(false);
|
||||
|
||||
@@ -149,11 +142,6 @@ export default function ServerCardIn({route, navigation}) {
|
||||
selectedCard.lastUsedGameId = server.gameId;
|
||||
});
|
||||
|
||||
// set default card if there's a game id provided by the server
|
||||
if (server.gameId) {
|
||||
setDefaultCard(selectedCard);
|
||||
}
|
||||
|
||||
setCardInCompleted(r);
|
||||
}).catch(() => {
|
||||
setCardInCompleted(false);
|
||||
@@ -168,7 +156,7 @@ export default function ServerCardIn({route, navigation}) {
|
||||
const performRefresh = () => {
|
||||
setServerRefreshing(true);
|
||||
setServerReloadCounter(serverReloadCounter + 1);
|
||||
}
|
||||
};
|
||||
|
||||
const gameName = useMemo(() => getGameName(server.gameId), [server.gameId]);
|
||||
const disableCardIn = useMemo(() => cardInCompleted !== null || !connectionTestResult, [cardInCompleted, connectionTestResult]);
|
||||
@@ -232,11 +220,12 @@ export default function ServerCardIn({route, navigation}) {
|
||||
<AimeCard card={card}
|
||||
key={card._id.toHexString()}
|
||||
actionIcon={<CircleDot color={theme.colors.tertiary} size={24}/>}
|
||||
onPress={() => setSelectedCard(card)}>
|
||||
onPress={() => setUserSelectedCard(card)}>
|
||||
{defaultCard?.code == card.code && <DefaultCardDetail/>}
|
||||
</AimeCard>))
|
||||
: <View style={styles.emptyPlaceholderView}>
|
||||
<EmptyStatePlaceholder message="No additional cards" icon={<SmartphoneNfcIcon color="gray"/>}/>
|
||||
<EmptyStatePlaceholder message="No additional cards"
|
||||
icon={<SmartphoneNfcIcon color="gray"/>}/>
|
||||
</View>}
|
||||
</View>)}
|
||||
</ScrollView>
|
||||
|
||||
Reference in New Issue
Block a user