mirror of
https://gitea.tendokyu.moe/ppc/amnet.git
synced 2026-10-04 20:57:55 +03:00
apply updates to native app
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
import {generateCardNumber} from "amnet-shared";
|
||||
import {useModalStyles} from "../utils/ModalStyles";
|
||||
import {useCallback, useLayoutEffect, useState} from "react";
|
||||
import {TextInput, TouchableOpacity, View} from "react-native";
|
||||
import {Button, Card, Divider, Paragraph, useTheme} from "react-native-paper";
|
||||
import {useModalStyles} from "../utils/ModalStyles";
|
||||
|
||||
import {AMCard} from "../models/AMCard";
|
||||
import RealmContext from "../models/RealmContext";
|
||||
import {generateCardNumber} from "../models/AM-API";
|
||||
|
||||
const {useRealm} = RealmContext;
|
||||
|
||||
@@ -48,7 +48,8 @@ export default function CardAddModal({navigation}) {
|
||||
const themeOptions = canSave ? modalStyles.headerText : {color: theme.colors.outline};
|
||||
|
||||
navigation.setOptions({
|
||||
headerRight: () => <TouchableOpacity disabled={!canSave} onPress={() => cardAddCallback(cardNumber, cardName)}>
|
||||
headerRight: () => <TouchableOpacity disabled={!canSave}
|
||||
onPress={() => cardAddCallback(cardNumber, cardName)}>
|
||||
<Paragraph style={{...themeOptions, fontWeight: "600"}}>Save</Paragraph>
|
||||
</TouchableOpacity>
|
||||
})
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import * as Clipboard from 'expo-clipboard';
|
||||
import * as Clipboard from "expo-clipboard";
|
||||
import {FlatList, View} from "react-native";
|
||||
import React, {useCallback, useMemo} from "react";
|
||||
import {Button, useTheme} from "react-native-paper";
|
||||
import {CreditCard, Plus} from "lucide-react-native";
|
||||
import ContextMenu from "react-native-context-menu-view";
|
||||
|
||||
import {AMCard} from "../models/AMCard";
|
||||
import {AimeCard} from "../components/AimeCard";
|
||||
import RealmContext from "../models/RealmContext";
|
||||
import ContextMenu from "react-native-context-menu-view";
|
||||
import {EmptyStatePlaceholder} from "../components/EmptyStatePlaceholder";
|
||||
import {CreditCard, Plus} from "lucide-react-native";
|
||||
import {Button, useTheme} from "react-native-paper";
|
||||
|
||||
const {useQuery, useRealm} = RealmContext;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {Plus} from "lucide-react-native";
|
||||
import {TouchableOpacity} from "react-native";
|
||||
import {useTheme} from "@react-navigation/native";
|
||||
import {createNativeStackNavigator} from "@react-navigation/native-stack";
|
||||
|
||||
import CardManager from "./CardManager";
|
||||
import {TouchableOpacity} from "react-native";
|
||||
|
||||
const Stack = createNativeStackNavigator();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {useModalStyles} from "../utils/ModalStyles";
|
||||
import {Card, Paragraph, useTheme} from "react-native-paper";
|
||||
import {TextInput, TouchableOpacity, View} from "react-native";
|
||||
import {useCallback, useEffect, useLayoutEffect, useState} from "react";
|
||||
import {useModalStyles} from "../utils/ModalStyles";
|
||||
|
||||
import RealmContext from "../models/RealmContext";
|
||||
import {AMServer} from "../models/AMServer";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {BSON} from "realm";
|
||||
import React, {useCallback, useEffect, useLayoutEffect, useMemo, useState} from "react";
|
||||
import {Alert, RefreshControl, ScrollView, Share, StyleSheet, TouchableOpacity, View} from "react-native";
|
||||
import {ActivityIndicator, Button, Card, Paragraph, Title, useTheme} from "react-native-paper";
|
||||
import {Alert, RefreshControl, ScrollView, Share, StyleSheet, TouchableOpacity, View} from "react-native";
|
||||
import {CircleCheck, CircleDot, CreditCard, Nfc, Plus, SmartphoneNfcIcon, WifiOff, Share as ShareIcon} from "lucide-react-native";
|
||||
import {EmptyStatePlaceholder} from "../components/EmptyStatePlaceholder";
|
||||
import {AimeCard} from "../components/AimeCard";
|
||||
@@ -10,6 +10,7 @@ import RealmContext from "../models/RealmContext";
|
||||
import {AMServer} from "../models/AMServer";
|
||||
import {AMCard} from "../models/AMCard";
|
||||
import ObjectId = BSON.ObjectId;
|
||||
import {fetchServerInfo, performCardIn} from "../../amnet-shared/src";
|
||||
|
||||
const {useRealm, useQuery, useObject} = RealmContext;
|
||||
|
||||
@@ -86,7 +87,7 @@ export default function ServerCardIn({route, navigation}) {
|
||||
}
|
||||
|
||||
const abortController = new AbortController();
|
||||
server.getInfo(abortController.signal).then(r => {
|
||||
fetchServerInfo(server.serverAddress, abortController.signal).then(r => {
|
||||
if (r) {
|
||||
setConnectionTestResult(true);
|
||||
realm.write(() => {
|
||||
@@ -107,11 +108,11 @@ export default function ServerCardIn({route, navigation}) {
|
||||
}, [serverId, serverReloadCounter, realm]);
|
||||
|
||||
// card in callback
|
||||
const performCardIn = useCallback(() => {
|
||||
const cardInCallback = useCallback(() => {
|
||||
setCardInCompleted(false);
|
||||
|
||||
const abortController = new AbortController();
|
||||
server.submitCard(selectedCard.code, abortController.signal).then(async r => {
|
||||
performCardIn(server.serverAddress, {cardId: selectedCard.code}, abortController.signal).then(async r => {
|
||||
const now = new Date();
|
||||
|
||||
setCardInCompleted(r);
|
||||
@@ -174,7 +175,7 @@ export default function ServerCardIn({route, navigation}) {
|
||||
card={selectedCard}
|
||||
actionIcon={<CircleCheck color="green" size={24}/>}/>
|
||||
<Button textColor="white"
|
||||
onPress={performCardIn}
|
||||
onPress={cardInCallback}
|
||||
disabled={disableCardIn}
|
||||
contentStyle={{flexDirection: 'row-reverse'}}
|
||||
mode={connectionTestResult ? "contained" : "outlined"}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
export interface AMServerInfoResponse {
|
||||
serverName: string;
|
||||
apiVersion: number;
|
||||
}
|
||||
|
||||
export interface AMCardInRequest {
|
||||
cardId: string;
|
||||
}
|
||||
|
||||
export function generateCardNumber(): string {
|
||||
let cardId = '';
|
||||
|
||||
while (true) {
|
||||
// don't start with a 3
|
||||
const firstDigit = Math.floor(Math.random() * 10);
|
||||
|
||||
if (firstDigit !== 3) {
|
||||
cardId = firstDigit.toString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < 19; i++) {
|
||||
cardId += Math.floor(Math.random() * 10).toString();
|
||||
}
|
||||
|
||||
return cardId;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import {Realm} from 'realm';
|
||||
import {AMServerInfoResponse} from "./AM-API";
|
||||
import {AMServerInfoResponse} from "amnet-shared";
|
||||
|
||||
export class AMServer extends Realm.Object<AMServer> implements AMServerInfoResponse {
|
||||
_id!: Realm.BSON.ObjectId;
|
||||
@@ -11,37 +11,6 @@ export class AMServer extends Realm.Object<AMServer> implements AMServerInfoResp
|
||||
createdAt: Date;
|
||||
apiVersion: number;
|
||||
|
||||
async getInfo(abort?: AbortSignal): Promise<AMServerInfoResponse> {
|
||||
try {
|
||||
const response = await fetch(this.serverAddress, {
|
||||
signal: abort
|
||||
});
|
||||
|
||||
return await response.json();
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async submitCard(cardId: string, abort?: AbortSignal): Promise<boolean> {
|
||||
try {
|
||||
const response = await fetch(`${this.serverAddress}/card`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({
|
||||
cardId: cardId
|
||||
}),
|
||||
signal: abort
|
||||
});
|
||||
|
||||
return response.ok;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static generate(serverAddress: string) {
|
||||
return {
|
||||
_id: new Realm.BSON.ObjectId(),
|
||||
|
||||
Generated
+12
@@ -15,6 +15,7 @@
|
||||
"@react-navigation/native-stack": "^6.11.0",
|
||||
"@realm/react": "^0.9.0",
|
||||
"@types/react": "~18.2.79",
|
||||
"amnet-shared": "file:../amnet-shared",
|
||||
"date-fns": "^3.6.0",
|
||||
"expo": "^51.0.0",
|
||||
"expo-blur": "~13.0.2",
|
||||
@@ -41,6 +42,13 @@
|
||||
"typescript": "~5.3.3"
|
||||
}
|
||||
},
|
||||
"../amnet-shared": {
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"tsup": "^8.2.4",
|
||||
"typescript": "^5.5.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@ampproject/remapping": {
|
||||
"version": "2.3.0",
|
||||
"license": "Apache-2.0",
|
||||
@@ -4735,6 +4743,10 @@
|
||||
"url": "https://github.com/sponsors/epoberezkin"
|
||||
}
|
||||
},
|
||||
"node_modules/amnet-shared": {
|
||||
"resolved": "../amnet-shared",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/anser": {
|
||||
"version": "1.4.10",
|
||||
"license": "MIT"
|
||||
|
||||
@@ -15,12 +15,14 @@
|
||||
"@react-navigation/native-stack": "^6.11.0",
|
||||
"@realm/react": "^0.9.0",
|
||||
"@types/react": "~18.2.79",
|
||||
"amnet-shared": "file:../amnet-shared",
|
||||
"date-fns": "^3.6.0",
|
||||
"expo": "^51.0.0",
|
||||
"expo-blur": "~13.0.2",
|
||||
"expo-clipboard": "~6.0.3",
|
||||
"expo-constants": "~16.0.2",
|
||||
"expo-dev-client": "~4.0.10",
|
||||
"expo-linking": "~6.3.1",
|
||||
"expo-status-bar": "~1.12.1",
|
||||
"expo-system-ui": "~3.0.7",
|
||||
"lucide-react-native": "^0.427.0",
|
||||
@@ -37,7 +39,6 @@
|
||||
"react-native-svg": "^15.5.0",
|
||||
"react-native-url-polyfill": "^2.0.0",
|
||||
"realm": "^12.12.1",
|
||||
"typescript": "~5.3.3",
|
||||
"expo-linking": "~6.3.1"
|
||||
"typescript": "~5.3.3"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user