mergin back access screens
@ -1,7 +1,7 @@
|
||||
import 'react-native-gesture-handler';
|
||||
import React from 'react';
|
||||
import { NativeRouter } from "react-router-native";
|
||||
import { Routes, Route } from 'react-router-dom';
|
||||
import { Root } from 'src/root/Root';
|
||||
import { StoreContextProvider } from 'context/StoreContext';
|
||||
import { UploadContextProvider } from 'context/UploadContext';
|
||||
import { AppContextProvider } from 'context/AppContext';
|
||||
@ -13,6 +13,10 @@ import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { ConversationContextProvider } from 'context/ConversationContext';
|
||||
import { LogBox } from 'react-native';
|
||||
import { Root } from 'src/root/Root';
|
||||
import { Access } from 'src/access/Access';
|
||||
import { Dashboard } from 'src/dashboard/Dashboard';
|
||||
import { Session } from 'src/session/Session';
|
||||
|
||||
// silence warning: Sending `onAnimatedValueUpdate` with no listeners registered
|
||||
//LogBox.ignoreLogs(['Sending']);
|
||||
@ -32,6 +36,12 @@ export default function App() {
|
||||
<NativeRouter>
|
||||
<Routes>
|
||||
<Route path="/" element={ <Root /> } />
|
||||
<Route path="/admin" element={ <Access mode="admin" /> } />
|
||||
<Route path="/dashboard" element={ <Dashboard /> } />
|
||||
<Route path="/login" element={ <Access mode="login" /> } />
|
||||
<Route path="/reset" element={ <Access mode="reset" /> } />
|
||||
<Route path="/create" element={ <Access mode="create" /> } />
|
||||
<Route path="/session" element={ <NavigationContainer><Session/></NavigationContainer> } />
|
||||
</Routes>
|
||||
</NativeRouter>
|
||||
</SafeAreaProvider>
|
||||
|
@ -1,3 +1,6 @@
|
||||
module.exports = {
|
||||
presets: ['module:metro-react-native-babel-preset'],
|
||||
plugins: [
|
||||
'react-native-reanimated/plugin',
|
||||
],
|
||||
};
|
||||
|
BIN
app/mobile/images/appstore.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
app/mobile/images/audio.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
app/mobile/images/avatar.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
app/mobile/images/login.png
Normal file
After Width: | Height: | Size: 70 KiB |
3
app/mobile/images/package.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"name": "images"
|
||||
}
|
BIN
app/mobile/images/session.png
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
app/mobile/images/solution.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
app/mobile/images/team.png
Normal file
After Width: | Height: | Size: 16 KiB |
@ -1,3 +1,5 @@
|
||||
import 'react-native-gesture-handler';
|
||||
|
||||
/**
|
||||
* @format
|
||||
*/
|
||||
|
@ -51,5 +51,25 @@
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>AntDesign.ttf</string>
|
||||
<string>Entypo.ttf</string>
|
||||
<string>EvilIcons.ttf</string>
|
||||
<string>Feather.ttf</string>
|
||||
<string>FontAwesome.ttf</string>
|
||||
<string>FontAwesome5_Brands.ttf</string>
|
||||
<string>FontAwesome5_Regular.ttf</string>
|
||||
<string>FontAwesome5_Solid.ttf</string>
|
||||
<string>Fontisto.ttf</string>
|
||||
<string>Foundation.ttf</string>
|
||||
<string>Ionicons.ttf</string>
|
||||
<string>MaterialCommunityIcons.ttf</string>
|
||||
<string>MaterialIcons.ttf</string>
|
||||
<string>Octicons.ttf</string>
|
||||
<string>SimpleLineIcons.ttf</string>
|
||||
<string>Zocial.ttf</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -426,6 +426,35 @@ PODS:
|
||||
- RNFBApp
|
||||
- RNGestureHandler (2.9.0):
|
||||
- React-Core
|
||||
- RNReanimated (2.14.4):
|
||||
- DoubleConversion
|
||||
- FBLazyVector
|
||||
- FBReactNativeSpec
|
||||
- glog
|
||||
- RCT-Folly
|
||||
- RCTRequired
|
||||
- RCTTypeSafety
|
||||
- React-callinvoker
|
||||
- React-Core
|
||||
- React-Core/DevSupport
|
||||
- React-Core/RCTWebSocket
|
||||
- React-CoreModules
|
||||
- React-cxxreact
|
||||
- React-jsi
|
||||
- React-jsiexecutor
|
||||
- React-jsinspector
|
||||
- React-RCTActionSheet
|
||||
- React-RCTAnimation
|
||||
- React-RCTBlob
|
||||
- React-RCTImage
|
||||
- React-RCTLinking
|
||||
- React-RCTNetwork
|
||||
- React-RCTSettings
|
||||
- React-RCTText
|
||||
- ReactCommon/turbomodule/core
|
||||
- Yoga
|
||||
- RNVectorIcons (9.2.0):
|
||||
- React-Core
|
||||
- Yoga (1.14.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
@ -471,6 +500,8 @@ DEPENDENCIES:
|
||||
- "RNFBApp (from `../node_modules/@react-native-firebase/app`)"
|
||||
- "RNFBMessaging (from `../node_modules/@react-native-firebase/messaging`)"
|
||||
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
||||
- RNReanimated (from `../node_modules/react-native-reanimated`)
|
||||
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
|
||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
|
||||
SPEC REPOS:
|
||||
@ -569,6 +600,10 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/@react-native-firebase/messaging"
|
||||
RNGestureHandler:
|
||||
:path: "../node_modules/react-native-gesture-handler"
|
||||
RNReanimated:
|
||||
:path: "../node_modules/react-native-reanimated"
|
||||
RNVectorIcons:
|
||||
:path: "../node_modules/react-native-vector-icons"
|
||||
Yoga:
|
||||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
@ -625,6 +660,8 @@ SPEC CHECKSUMS:
|
||||
RNFBApp: 4f8ea53443d52c7db793234d2398a357fc6cfbf1
|
||||
RNFBMessaging: c686471358d20d54f716a8b7b7f10f8944c966ec
|
||||
RNGestureHandler: 071d7a9ad81e8b83fe7663b303d132406a7d8f39
|
||||
RNReanimated: cc5e3aa479cb9170bcccf8204291a6950a3be128
|
||||
RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8
|
||||
Yoga: 5ed1699acbba8863755998a4245daa200ff3817b
|
||||
|
||||
PODFILE CHECKSUM: 8a4cbf61c865c6e404d389f26395fa04926b8f43
|
||||
|
@ -12,7 +12,10 @@
|
||||
"dependencies": {
|
||||
"@react-native-firebase/app": "^17.2.0",
|
||||
"@react-native-firebase/messaging": "^17.2.0",
|
||||
"@react-navigation/bottom-tabs": "^6.5.5",
|
||||
"@react-navigation/drawer": "^6.6.0",
|
||||
"@react-navigation/native": "^6.1.4",
|
||||
"@react-navigation/native-stack": "^6.9.10",
|
||||
"axios": "^1.3.3",
|
||||
"crypto-js": "^4.1.1",
|
||||
"react": "18.2.0",
|
||||
@ -20,9 +23,11 @@
|
||||
"react-native-base64": "^0.2.1",
|
||||
"react-native-device-info": "^10.4.0",
|
||||
"react-native-gesture-handler": "^2.9.0",
|
||||
"react-native-reanimated": "^2.14.4",
|
||||
"react-native-rsa-native": "^2.0.5",
|
||||
"react-native-safe-area-context": "^4.5.0",
|
||||
"react-native-sqlite-storage": "^6.0.1",
|
||||
"react-native-vector-icons": "^9.2.0",
|
||||
"react-router-dom": "^6.8.1",
|
||||
"react-router-native": "^6.8.1"
|
||||
},
|
||||
|
58
app/mobile/src/access/Access.jsx
Normal file
@ -0,0 +1,58 @@
|
||||
import { SafeAreaView, Image, View } from 'react-native';
|
||||
import { styles } from './Access.styled';
|
||||
import { useAccess } from './useAccess.hook';
|
||||
import { Login } from './login/Login';
|
||||
import { Create } from './create/Create';
|
||||
import { Reset } from './reset/Reset';
|
||||
import { Admin } from './admin/Admin';
|
||||
import logo from 'images/login.png';
|
||||
|
||||
export function Access({ mode }) {
|
||||
|
||||
const { state, actions } = useAccess();
|
||||
|
||||
return (
|
||||
<View style={styles.wrapper}>
|
||||
<SafeAreaView>
|
||||
{ state.split === true && (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.paddedPane}>
|
||||
<Image style={styles.splash} source={logo} />
|
||||
</View>
|
||||
<View style={styles.pane}>
|
||||
{ mode === 'login' && (
|
||||
<Login />
|
||||
)}
|
||||
{ mode === 'create' && (
|
||||
<Create />
|
||||
)}
|
||||
{ mode === 'reset' && (
|
||||
<Reset />
|
||||
)}
|
||||
{ mode === 'admin' && (
|
||||
<Admin />
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
{ state.split === false && (
|
||||
<View style={styles.container}>
|
||||
{ mode === 'login' && (
|
||||
<Login />
|
||||
)}
|
||||
{ mode === 'create' && (
|
||||
<Create />
|
||||
)}
|
||||
{ mode === 'reset' && (
|
||||
<Reset />
|
||||
)}
|
||||
{ mode === 'admin' && (
|
||||
<Admin />
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
30
app/mobile/src/access/Access.styled.js
Normal file
@ -0,0 +1,30 @@
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { Colors } from 'constants/Colors';
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
wrapper: {
|
||||
backgroundColor: Colors.background,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
container: {
|
||||
padding: 16,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
},
|
||||
splash: {
|
||||
flex: 1,
|
||||
width: null,
|
||||
height: null,
|
||||
resizeMode: 'contain',
|
||||
},
|
||||
pane: {
|
||||
width: '50%',
|
||||
height: '100%',
|
||||
},
|
||||
paddedPane: {
|
||||
width: '50%',
|
||||
height: '100%',
|
||||
paddingRight: 16,
|
||||
},
|
||||
});
|
78
app/mobile/src/access/admin/Admin.jsx
Normal file
@ -0,0 +1,78 @@
|
||||
import { KeyboardAvoidingView, ActivityIndicator, Alert, Text, TextInput, View, TouchableOpacity } from 'react-native';
|
||||
import { styles } from './Admin.styled';
|
||||
import Ionicons from 'react-native-vector-icons/AntDesign';
|
||||
import { useAdmin } from './useAdmin.hook';
|
||||
import Colors from 'constants/Colors';
|
||||
|
||||
export function Admin() {
|
||||
|
||||
const { state, actions } = useAdmin();
|
||||
|
||||
const admin = async () => {
|
||||
try {
|
||||
await actions.access();
|
||||
}
|
||||
catch (err) {
|
||||
Alert.alert(
|
||||
"Access Failed",
|
||||
"Please check your server and token.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView style={styles.wrapper} behavior="padding" enabled={Platform.OS === 'ios' ? true : false}>
|
||||
<View style={styles.container}>
|
||||
<View style={styles.control}>
|
||||
<TouchableOpacity onPress={actions.login}>
|
||||
<Ionicons style={styles.config} name="user" size={24} color="#aaaaaa" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<Text style={styles.title}>Databag</Text>
|
||||
<View style={styles.spacemid}>
|
||||
<Text style={styles.header}>Admin Acess</Text>
|
||||
</View>
|
||||
<View style={styles.spacetop}>
|
||||
<View style={styles.inputwrapper}>
|
||||
<Ionicons style={styles.icon} name="database" size={18} color="#aaaaaa" />
|
||||
<TextInput style={styles.inputfield} value={state.server} onChangeText={actions.setServer}
|
||||
autoCorrect={false} autoCapitalize="none" placeholder="server" placeholderTextColor={Colors.grey} />
|
||||
<View style={styles.space} />
|
||||
</View>
|
||||
<View style={styles.inputwrapper}>
|
||||
<Ionicons style={styles.icon} name="key" size={18} color="#aaaaaa" />
|
||||
<TextInput style={styles.inputfield} value={state.token} onChangeText={actions.setToken}
|
||||
secureTextEntry={!state.plainText} autoCapitalize="none" placeholder="token"
|
||||
placeholderTextColor={Colors.grey} />
|
||||
<TouchableOpacity>
|
||||
{ state.plainText && (
|
||||
<Ionicons style={styles.icon} name="eye" size={18} color="#aaaaaa" onPress={actions.hidePass}/>
|
||||
)}
|
||||
{ !state.plainText && (
|
||||
<Ionicons style={styles.icon} name="eyeo" size={18} color="#aaaaaa" onPress={actions.showPass}/>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
{ state.enabled && (
|
||||
<TouchableOpacity style={styles.reset} onPress={admin}>
|
||||
{ state.busy && (
|
||||
<ActivityIndicator size="small" color="#ffffff" />
|
||||
)}
|
||||
{ !state.busy && (
|
||||
<Text style={styles.resettext}>Access</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
{ !state.enabled && (
|
||||
<View style={styles.noreset}>
|
||||
<Text style={styles.noresettext}>Access</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
<View style={styles.version}>
|
||||
<Text style={styles.versiontext}>v{ state.version }</Text>
|
||||
</View>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
}
|
120
app/mobile/src/access/admin/Admin.styled.js
Normal file
@ -0,0 +1,120 @@
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { Colors } from 'constants/Colors';
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
wrapper: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
config: {
|
||||
paddingTop: 8,
|
||||
},
|
||||
icon: {
|
||||
padding: 8,
|
||||
},
|
||||
space: {
|
||||
width: 32,
|
||||
},
|
||||
container: {
|
||||
flexDirection: 'column',
|
||||
backgroundColor: Colors.formBackground,
|
||||
borderRadius: 4,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
paddingLeft: 16,
|
||||
paddingRight: 16,
|
||||
},
|
||||
control: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
color: Colors.grey,
|
||||
},
|
||||
title: {
|
||||
width: '100%',
|
||||
textAlign: 'center',
|
||||
fontSize: 24,
|
||||
color: Colors.grey,
|
||||
},
|
||||
spacemid: {
|
||||
flexGrow: 1,
|
||||
flexDirection: 'column',
|
||||
textAlign: 'center',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: '100%',
|
||||
},
|
||||
spacetop: {
|
||||
flexGrow: 1,
|
||||
flexDirection: 'column',
|
||||
textAlign: 'center',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
width: '100%',
|
||||
},
|
||||
header: {
|
||||
fontSize: 32,
|
||||
color: Colors.text,
|
||||
},
|
||||
inputwrapper: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
borderRadius: 4,
|
||||
borderColor: Colors.divider,
|
||||
borderWidth: 1,
|
||||
marginBottom: 16,
|
||||
alignItems: 'center',
|
||||
},
|
||||
inputfield: {
|
||||
flex: 1,
|
||||
textAlign: 'center',
|
||||
padding: 8,
|
||||
},
|
||||
reset: {
|
||||
marginTop: 16,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: 128,
|
||||
height: 28,
|
||||
backgroundColor: Colors.primary,
|
||||
borderRadius: 4,
|
||||
},
|
||||
resettext: {
|
||||
color: Colors.formFocus,
|
||||
},
|
||||
noreset: {
|
||||
marginTop: 16,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: 128,
|
||||
height: 28,
|
||||
borderRadius: 4,
|
||||
borderColor: Colors.divider,
|
||||
borderWidth: 1,
|
||||
},
|
||||
noresettext: {
|
||||
color: Colors.grey,
|
||||
},
|
||||
login: {
|
||||
marginTop: 16,
|
||||
},
|
||||
logintext: {
|
||||
color: 'yellow',
|
||||
},
|
||||
nologintext: {
|
||||
color: Colors.disabled,
|
||||
},
|
||||
version: {
|
||||
display: 'flex',
|
||||
alignItems: 'flex-end',
|
||||
},
|
||||
versiontext: {
|
||||
color: Colors.grey,
|
||||
fontSize: 14,
|
||||
},
|
||||
})
|
||||
|
90
app/mobile/src/access/admin/useAdmin.hook.js
Normal file
@ -0,0 +1,90 @@
|
||||
import { useState, useEffect, useContext } from 'react';
|
||||
import { useWindowDimensions } from 'react-native';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { AppContext } from 'context/AppContext';
|
||||
import { getNodeStatus } from 'api/getNodeStatus';
|
||||
import { setNodeStatus } from 'api/setNodeStatus';
|
||||
import { getNodeConfig } from 'api/getNodeConfig';
|
||||
|
||||
export function useAdmin() {
|
||||
|
||||
const navigate = useNavigate();
|
||||
const app = useContext(AppContext);
|
||||
|
||||
const [state, setState] = useState({
|
||||
busy: false,
|
||||
enabled: false,
|
||||
server: null,
|
||||
token: null,
|
||||
plainText: false,
|
||||
version: null,
|
||||
});
|
||||
|
||||
const updateState = (value) => {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
updateState({ version: app.state.version });
|
||||
}, [app]);
|
||||
|
||||
const checkStatus = async () => {
|
||||
try {
|
||||
updateState({ unclaimed: status });
|
||||
}
|
||||
catch (err) {
|
||||
console.log("failed to check node status");
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (state.token && state.server && !state.enabled) {
|
||||
updateState({ enabled: true });
|
||||
}
|
||||
if ((!state.token || !state.server) && state.enabled) {
|
||||
updateState({ enabled: false });
|
||||
}
|
||||
}, [state.server, state.token]);
|
||||
|
||||
const actions = {
|
||||
setServer: (server) => {
|
||||
updateState({ server });
|
||||
},
|
||||
setToken: (token) => {
|
||||
updateState({ token });
|
||||
},
|
||||
login: () => {
|
||||
navigate('/login');
|
||||
},
|
||||
showPass: () => {
|
||||
updateState({ plainText: true });
|
||||
},
|
||||
hidePass: () => {
|
||||
updateState({ plainText: false });
|
||||
},
|
||||
access: async () => {
|
||||
if (!state.busy) {
|
||||
try {
|
||||
updateState({ busy: true });
|
||||
const node = state.server.trim();
|
||||
const token = state.token;
|
||||
const unclaimed = await getNodeStatus(node);
|
||||
if (unclaimed) {
|
||||
await setNodeStatus(node, token);
|
||||
}
|
||||
const config = await getNodeConfig(node, token);
|
||||
updateState({ server: node, busy: false });
|
||||
navigate('/dashboard', { state: { config, server: node, token }});
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
updateState({ busy: false });
|
||||
throw new Error("access failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return { state, actions };
|
||||
}
|
||||
|
164
app/mobile/src/access/create/Create.jsx
Normal file
@ -0,0 +1,164 @@
|
||||
import { KeyboardAvoidingView, ScrollView, ActivityIndicator, Alert, Text, TextInput, View, TouchableOpacity } from 'react-native';
|
||||
import { styles } from './Create.styled';
|
||||
import Ionicons from 'react-native-vector-icons/AntDesign';
|
||||
import { useCreate } from './useCreate.hook';
|
||||
import Colors from 'constants/Colors';
|
||||
|
||||
export function Create() {
|
||||
|
||||
const { state, actions } = useCreate();
|
||||
|
||||
const create = async () => {
|
||||
try {
|
||||
await actions.create();
|
||||
}
|
||||
catch (err) {
|
||||
Alert.alert(
|
||||
"Create Failed",
|
||||
"Please check your server and token.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const validServer = (state.server && state.serverChecked && state.serverValid);
|
||||
const validToken = (!state.tokenRequired || (state.token && state.tokenChecked && state.tokenValid));
|
||||
const validUsername = (state.username && state.usernameChecked && state.usernameValid);
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView style={styles.wrapper} behavior="padding" enabled={Platform.OS === 'ios' ? true : false}>
|
||||
<View style={styles.container}>
|
||||
<View style={styles.control}>
|
||||
<TouchableOpacity onPress={actions.config}>
|
||||
<Ionicons style={styles.config} name="setting" size={24} color="#aaaaaa" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<Text style={styles.title}>Databag</Text>
|
||||
<View style={styles.spacemid}>
|
||||
<Text style={styles.header}>Create Account</Text>
|
||||
</View>
|
||||
<ScrollView style={styles.spacetop}>
|
||||
<View style={styles.inputwrapper}>
|
||||
<Ionicons style={styles.icon} name="database" size={18} color="#888888" />
|
||||
<TextInput style={styles.inputfield} value={state.server} onChangeText={actions.setServer}
|
||||
autoCorrect={false} autoCapitalize="none" placeholder="server" placeholderTextColor={Colors.grey} />
|
||||
<View style={styles.space}>
|
||||
{ (!state.server || !state.serverChecked) && (
|
||||
<Text style={styles.required}>✻</Text>
|
||||
)}
|
||||
{ state.server && state.serverChecked && !state.serverValid && (
|
||||
<Ionicons style={styles.icon} name="exclamationcircleo" size={18} color="#ff8888" />
|
||||
)}
|
||||
{ state.server && state.serverChecked && state.serverValid && (
|
||||
<Ionicons style={styles.icon} name="checkcircleo" size={18} color="#448866" />
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.token}>
|
||||
{ state.tokenRequired && (
|
||||
<View style={styles.inputwrapper}>
|
||||
<Ionicons style={styles.icon} name="key" size={18} color="#888888" />
|
||||
<TextInput style={styles.inputfield} value={state.token} onChangeText={actions.setToken}
|
||||
autoCorrect={false} autoCapitalize="none" placeholder="token" placeholderTextColor={Colors.grey} />
|
||||
<View style={styles.space}>
|
||||
{ (!validServer || !state.token || !state.tokenChecked) && (
|
||||
<Text style={styles.required}>✻</Text>
|
||||
)}
|
||||
{ validServer && state.token && state.tokenChecked && !state.tokenValid && (
|
||||
<Ionicons style={styles.icon} name="exclamationcircleo" size={18} color="#ff8888" />
|
||||
)}
|
||||
{ validServer && state.token && state.tokenChecked && state.tokenValid && (
|
||||
<Ionicons style={styles.icon} name="checkcircleo" size={18} color="#448866" />
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
{ !state.tokenRequired && state.server === 'databag.coredb.org' && (
|
||||
<View style={styles.demo}>
|
||||
<Text style={styles.demoText}>The default public server is to test out the system. Use a private server othersize.</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
<View style={styles.inputwrapper}>
|
||||
<Ionicons style={styles.icon} name="user" size={18} color="#888888" />
|
||||
<TextInput style={styles.inputfield} value={state.username} onChangeText={actions.setUsername}
|
||||
autoCorrect={false} autoCapitalize="none" placeholder="username" placeholderTextColor={Colors.grey} />
|
||||
<View style={styles.space}>
|
||||
{ (!validServer || !validToken || !state.username || !state.usernameChecked) && (
|
||||
<Text style={styles.required}>✻</Text>
|
||||
)}
|
||||
{ validServer && validToken && state.username && state.usernameChecked && !state.usernameValid && (
|
||||
<Ionicons style={styles.icon} name="exclamationcircleo" size={18} color="#ff8888" />
|
||||
)}
|
||||
{ validServer && validToken && state.username && state.usernameChecked && state.usernameValid && (
|
||||
<Ionicons style={styles.icon} name="checkcircleo" size={18} color="#448866" />
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
{ state.showPassword && (
|
||||
<View style={styles.inputwrapper}>
|
||||
<Ionicons style={styles.icon} name="lock" size={18} color="#888888" />
|
||||
<TextInput style={styles.inputfield} value={state.password} onChangeText={actions.setPassword}
|
||||
autoCorrect={false} autoCapitalize="none" placeholder="password" placeholderTextColor={Colors.grey} />
|
||||
<TouchableOpacity onPress={actions.hidePassword}>
|
||||
<Ionicons style={styles.icon} name="eye" size={18} color="#888888" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)}
|
||||
{ !state.showPassword && (
|
||||
<View style={styles.inputwrapper}>
|
||||
<Ionicons style={styles.icon} name="lock" size={18} color="#888888" />
|
||||
<TextInput style={styles.inputfield} value={state.password} onChangeText={actions.setPassword}
|
||||
autoCorrect={false} secureTextEntry={true} autoCapitalize="none" placeholder="password"
|
||||
placeholderTextColor={Colors.grey} />
|
||||
<TouchableOpacity onPress={actions.showPassword}>
|
||||
<Ionicons style={styles.icon} name="eyeo" size={18} color="#888888" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)}
|
||||
{ state.showConfirm && (
|
||||
<View style={styles.inputwrapper}>
|
||||
<Ionicons style={styles.icon} name="lock" size={18} color="#888888" />
|
||||
<TextInput style={styles.inputfield} value={state.confirm} onChangeText={actions.setConfirm}
|
||||
autoCorrect={false} autoCapitalize="none" placeholder="confirm password"
|
||||
placeholderTextColor={Colors.grey} />
|
||||
<TouchableOpacity onPress={actions.hideConfirm}>
|
||||
<Ionicons style={styles.icon} name="eye" size={18} color="#888888" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)}
|
||||
{ !state.showConfirm && (
|
||||
<View style={styles.inputwrapper}>
|
||||
<Ionicons style={styles.icon} name="lock" size={18} color="#888888" />
|
||||
<TextInput style={styles.inputfield} value={state.confirm} onChangeText={actions.setConfirm}
|
||||
autoCorrect={false} secureTextEntry={true} autoCapitalize="none" placeholder="confirm password"
|
||||
placeholderTextColor={Colors.grey} />
|
||||
<TouchableOpacity onPress={actions.showConfirm}>
|
||||
<Ionicons style={styles.icon} name="eyeo" size={18} color="#888888" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)}
|
||||
<View style={styles.buttons}>
|
||||
{ state.enabled && (
|
||||
<TouchableOpacity style={styles.create} onPress={create}>
|
||||
{ state.busy && (
|
||||
<ActivityIndicator size="small" color="#ffffff" />
|
||||
)}
|
||||
{ !state.busy && (
|
||||
<Text style={styles.createtext}>Create Account</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
{ !state.enabled && (
|
||||
<View style={styles.nocreate}>
|
||||
<Text style={styles.nocreatetext}>Create</Text>
|
||||
</View>
|
||||
)}
|
||||
<TouchableOpacity style={styles.login} onPress={actions.login}>
|
||||
<Text style={styles.logintext}>Account Login</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
}
|
148
app/mobile/src/access/create/Create.styled.js
Normal file
@ -0,0 +1,148 @@
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { Colors } from 'constants/Colors';
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
wrapper: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
config: {
|
||||
paddingTop: 8,
|
||||
},
|
||||
demo: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
paddingLeft: 16,
|
||||
paddingRight: 16,
|
||||
},
|
||||
demoText: {
|
||||
color: Colors.grey,
|
||||
textAlign: 'center',
|
||||
},
|
||||
space: {
|
||||
width: 32,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
required: {
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
textAlignVertical: 'center',
|
||||
},
|
||||
container: {
|
||||
flexDirection: 'column',
|
||||
backgroundColor: Colors.formBackground,
|
||||
borderRadius: 4,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
},
|
||||
token: {
|
||||
height: 52,
|
||||
},
|
||||
control: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
color: Colors.grey,
|
||||
marginRight: 16,
|
||||
},
|
||||
title: {
|
||||
width: '100%',
|
||||
textAlign: 'center',
|
||||
fontSize: 24,
|
||||
color: Colors.grey,
|
||||
},
|
||||
spacemid: {
|
||||
flexGrow: 1,
|
||||
flexDirection: 'column',
|
||||
textAlign: 'center',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: '100%',
|
||||
},
|
||||
spacetop: {
|
||||
width: '100%',
|
||||
paddingLeft: 16,
|
||||
paddingRight: 16,
|
||||
},
|
||||
buttons: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
header: {
|
||||
fontSize: 32,
|
||||
color: Colors.text,
|
||||
},
|
||||
inputwrapper: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
borderRadius: 4,
|
||||
borderColor: Colors.divider,
|
||||
borderWidth: 1,
|
||||
marginBottom: 16,
|
||||
alignItems: 'center',
|
||||
},
|
||||
inputwrapperpad: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
borderRadius: 4,
|
||||
borderColor: Colors.divider,
|
||||
borderWidth: 1,
|
||||
marginTop: 16,
|
||||
marginBottom: 16,
|
||||
alignItems: 'center',
|
||||
},
|
||||
inputfield: {
|
||||
flex: 1,
|
||||
textAlign: 'center',
|
||||
padding: 8,
|
||||
},
|
||||
create: {
|
||||
marginTop: 16,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: 128,
|
||||
height: 28,
|
||||
backgroundColor: Colors.primary,
|
||||
borderRadius: 4,
|
||||
marginBottom: 16,
|
||||
},
|
||||
createtext: {
|
||||
color: Colors.formFocus,
|
||||
},
|
||||
nocreate: {
|
||||
marginTop: 16,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: 128,
|
||||
height: 28,
|
||||
borderRadius: 4,
|
||||
borderColor: Colors.divider,
|
||||
borderWidth: 1,
|
||||
marginBottom: 16,
|
||||
},
|
||||
nocreatetext: {
|
||||
color: Colors.grey,
|
||||
},
|
||||
login: {
|
||||
marginTop: 16,
|
||||
marginBottom: 16,
|
||||
},
|
||||
logintext: {
|
||||
color: 'yellow',
|
||||
},
|
||||
nologintext: {
|
||||
color: Colors.disabled,
|
||||
},
|
||||
|
||||
})
|
||||
|
193
app/mobile/src/access/create/useCreate.hook.js
Normal file
@ -0,0 +1,193 @@
|
||||
import { useState, useEffect, useContext, useRef } from 'react';
|
||||
import { useWindowDimensions } from 'react-native';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { AppContext } from 'context/AppContext';
|
||||
import { getAvailable } from 'api/getAvailable';
|
||||
import { getUsername } from 'api/getUsername';
|
||||
|
||||
export function useCreate() {
|
||||
|
||||
const [count, setCount] = useState(0);
|
||||
const navigate = useNavigate();
|
||||
const app = useContext(AppContext);
|
||||
|
||||
const [state, setState] = useState({
|
||||
busy: false,
|
||||
enabled: false,
|
||||
server: "databag.coredb.org",
|
||||
token: null,
|
||||
username: null,
|
||||
password: null,
|
||||
confirm: null,
|
||||
showPassword: false,
|
||||
showConfirm: false,
|
||||
serverChecked: true,
|
||||
serverValid: true,
|
||||
tokenRequired: false,
|
||||
tokenChecked: true,
|
||||
tokenValid: false,
|
||||
usernameChecked: true,
|
||||
usernameValid: false,
|
||||
});
|
||||
|
||||
const backoff = useRef(false);
|
||||
const checking = useRef(false);
|
||||
const debounce = useRef(null);
|
||||
|
||||
const updateState = (value) => {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (app.state.session) {
|
||||
navigate('/session');
|
||||
}
|
||||
}, [app.state.session]);
|
||||
|
||||
useEffect(() => {
|
||||
if (state.usernameChecked && state.serverChecked && state.tokenChecked &&
|
||||
state.password && state.username && state.server && state.confirm &&
|
||||
(!state.tokenRequired || state.tokenValid) &&
|
||||
state.serverValid && state.usernameValid && state.password === state.confirm) {
|
||||
if (!state.enabled) {
|
||||
updateState({ enabled: true });
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (state.enabled) {
|
||||
updateState({ enabled: false });
|
||||
}
|
||||
}
|
||||
}, [state]);
|
||||
|
||||
useEffect(() => {
|
||||
if (checking.current) {
|
||||
backoff.current = true;
|
||||
}
|
||||
if (debounce.current) {
|
||||
clearTimeout(debounce.current);
|
||||
}
|
||||
debounce.current = setTimeout(async () => {
|
||||
checking.current = true;
|
||||
debounce.current = null;
|
||||
if (state.server) {
|
||||
try {
|
||||
const available = await getAvailable(state.server);
|
||||
if (available) {
|
||||
if (state.username) {
|
||||
try {
|
||||
const claimable = await getUsername(state.username, state.server, null);
|
||||
updateState({ tokenRequired: false, usernameValid: claimable, serverValid: true });
|
||||
}
|
||||
catch (err) {
|
||||
updateState({ tokenRequired: false, usernameValid: false, serverValid: true });
|
||||
}
|
||||
}
|
||||
else {
|
||||
updateState({ tokenRequired: false, serverValid: true });
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (state.token) {
|
||||
try {
|
||||
const accessible = await getUsername(null, state.server, state.token);
|
||||
if (accessible) {
|
||||
if (state.username) {
|
||||
try {
|
||||
const claimable = await getUsername(state.username, state.server, state.token);
|
||||
updateState({ tokenRequired: true, usernameValid: claimable, tokenValid: true, serverValid: true });
|
||||
}
|
||||
catch (err) {
|
||||
updateState({ tokenRequired: true, usernameValid: false, tokenValid: true, serverValid: true });
|
||||
}
|
||||
}
|
||||
else {
|
||||
updateState({ tokenRequired: true, tokenValid: true, serverValid: true });
|
||||
}
|
||||
}
|
||||
else {
|
||||
updateState({ tokenRequired: true, tokenValid: false, serverValid: true });
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
updateState({ tokenRequired: true, tokenValid: false, serverValid: true });
|
||||
}
|
||||
}
|
||||
else {
|
||||
updateState({ tokenRequired: true, serverValid: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
updateState({ serverValid: false });
|
||||
}
|
||||
}
|
||||
let retry = backoff.current;
|
||||
backoff.current = false;
|
||||
checking.current = false;
|
||||
if (retry) {
|
||||
setCount(count+1);
|
||||
}
|
||||
else {
|
||||
updateState({ usernameChecked: true, tokenChecked: true, serverChecked: true });
|
||||
}
|
||||
}, 1000);
|
||||
}, [count]);
|
||||
|
||||
const actions = {
|
||||
config: () => {
|
||||
navigate('/admin');
|
||||
},
|
||||
setServer: (server) => {
|
||||
updateState({ server, serverChecked: false });
|
||||
setCount(count+1);
|
||||
},
|
||||
setToken: (token) => {
|
||||
updateState({ token, tokenChecked: false });
|
||||
setCount(count+1);
|
||||
},
|
||||
setUsername: (username) => {
|
||||
updateState({ username, usernameChecked: false });
|
||||
setCount(count+1);
|
||||
},
|
||||
setPassword: (password) => {
|
||||
updateState({ password });
|
||||
},
|
||||
setConfirm: (confirm) => {
|
||||
updateState({ confirm });
|
||||
},
|
||||
login: () => {
|
||||
navigate('/login');
|
||||
},
|
||||
showPassword: () => {
|
||||
updateState({ showPassword: true });
|
||||
},
|
||||
hidePassword: () => {
|
||||
updateState({ showPassword: false });
|
||||
},
|
||||
showConfirm: () => {
|
||||
updateState({ showConfirm: true });
|
||||
},
|
||||
hideConfirm: () => {
|
||||
updateState({ showConfirm: false });
|
||||
},
|
||||
create: async () => {
|
||||
if (!state.busy) {
|
||||
try {
|
||||
updateState({ busy: true });
|
||||
await app.actions.create(state.server, state.username, state.password, state.token);
|
||||
updateState({ busy: false });
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
updateState({ busy: false });
|
||||
throw new Error('create failed');
|
||||
}
|
||||
updateState({ busy: false });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return { state, actions };
|
||||
}
|
||||
|
90
app/mobile/src/access/login/Login.jsx
Normal file
@ -0,0 +1,90 @@
|
||||
import { KeyboardAvoidingView, ActivityIndicator, Alert, Text, TextInput, View, TouchableOpacity } from 'react-native';
|
||||
import { styles } from './Login.styled';
|
||||
import Ionicons from 'react-native-vector-icons/AntDesign';
|
||||
import { useLogin } from './useLogin.hook';
|
||||
import { Colors } from 'constants/Colors';
|
||||
|
||||
export function Login() {
|
||||
|
||||
const { state, actions } = useLogin();
|
||||
|
||||
const login = async () => {
|
||||
try {
|
||||
await actions.login();
|
||||
}
|
||||
catch (err) {
|
||||
Alert.alert(
|
||||
"Login Failed",
|
||||
"Please check your login and password.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView style={styles.wrapper} behavior="padding" enabled={Platform.OS === 'ios' ? true : false}>
|
||||
<View style={styles.container}>
|
||||
<View style={styles.control}>
|
||||
<TouchableOpacity onPress={actions.config}>
|
||||
<Ionicons style={styles.config} name="setting" size={24} color="#aaaaaa" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<Text style={styles.title}>Databag</Text>
|
||||
<View style={styles.spacemid}>
|
||||
<Text style={styles.header}>Login</Text>
|
||||
</View>
|
||||
<View style={styles.spacetop}>
|
||||
<View style={styles.inputwrapper}>
|
||||
<Ionicons style={styles.icon} name="user" size={18} color="#aaaaaa" />
|
||||
<TextInput style={styles.inputfield} value={state.login} onChangeText={actions.setLogin}
|
||||
autoCorrect={false} autoCapitalize="none" placeholder="username@server" placeholderTextColor={Colors.grey} />
|
||||
<View style={styles.space} />
|
||||
</View>
|
||||
{ state.showPassword && (
|
||||
<View style={styles.inputwrapper}>
|
||||
<Ionicons style={styles.icon} name="lock" size={18} color="#aaaaaa" />
|
||||
<TextInput style={styles.inputfield} value={state.password} onChangeText={actions.setPassword}
|
||||
autoCorrect={false} autoCapitalize="none" placeholder="password" placeholderTextColor={Colors.grey} />
|
||||
<TouchableOpacity onPress={actions.hidePassword}>
|
||||
<Ionicons style={styles.icon} name="eye" size={18} color="#aaaaaa" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)}
|
||||
{ !state.showPassword && (
|
||||
<View style={styles.inputwrapper}>
|
||||
<Ionicons style={styles.icon} name="lock" size={18} color="#aaaaaa" />
|
||||
<TextInput style={styles.inputfield} value={state.password} onChangeText={actions.setPassword}
|
||||
autoCorrect={false} secureTextEntry={true} autoCapitalize="none" placeholder="password"
|
||||
placeholderTextColor={Colors.grey} />
|
||||
<TouchableOpacity onPress={actions.showPassword}>
|
||||
<Ionicons style={styles.icon} name="eyeo" size={18} color="#aaaaaa" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)}
|
||||
{ state.enabled && (
|
||||
<TouchableOpacity style={styles.login} onPress={login}>
|
||||
{ state.busy && (
|
||||
<ActivityIndicator size="small" color="#ffffff" />
|
||||
)}
|
||||
{ !state.busy && (
|
||||
<Text style={styles.logintext}>Login</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
{ !state.enabled && (
|
||||
<View style={styles.nologin}>
|
||||
<Text style={styles.nologintext}>Login</Text>
|
||||
</View>
|
||||
)}
|
||||
<TouchableOpacity style={styles.create} onPress={actions.create}>
|
||||
<Text style={styles.createtext}>Create Account</Text>
|
||||
</TouchableOpacity>
|
||||
<View style={styles.bottom}>
|
||||
<TouchableOpacity style={styles.create} onPress={actions.reset}>
|
||||
<Text style={styles.createtext}>Forgot Password</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
}
|
119
app/mobile/src/access/login/Login.styled.js
Normal file
@ -0,0 +1,119 @@
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { Colors } from 'constants/Colors';
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
wrapper: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
config: {
|
||||
paddingTop: 8,
|
||||
},
|
||||
icon: {
|
||||
padding: 8,
|
||||
},
|
||||
space: {
|
||||
width: 32,
|
||||
},
|
||||
container: {
|
||||
flexDirection: 'column',
|
||||
backgroundColor: Colors.formBackground,
|
||||
borderRadius: 4,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
paddingLeft: 16,
|
||||
paddingRight: 16,
|
||||
},
|
||||
control: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
color: Colors.grey,
|
||||
},
|
||||
title: {
|
||||
width: '100%',
|
||||
textAlign: 'center',
|
||||
fontSize: 24,
|
||||
color: Colors.grey,
|
||||
},
|
||||
spacemid: {
|
||||
flexGrow: 1,
|
||||
flexDirection: 'column',
|
||||
textAlign: 'center',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: '100%',
|
||||
},
|
||||
spacetop: {
|
||||
flexGrow: 1,
|
||||
flexDirection: 'column',
|
||||
textAlign: 'center',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
width: '100%',
|
||||
},
|
||||
header: {
|
||||
fontSize: 32,
|
||||
color: Colors.text,
|
||||
},
|
||||
inputwrapper: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
borderRadius: 4,
|
||||
borderColor: Colors.divider,
|
||||
borderWidth: 1,
|
||||
marginBottom: 16,
|
||||
alignItems: 'center',
|
||||
},
|
||||
inputfield: {
|
||||
flex: 1,
|
||||
textAlign: 'center',
|
||||
padding: 8,
|
||||
},
|
||||
login: {
|
||||
marginTop: 16,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: 128,
|
||||
height: 28,
|
||||
backgroundColor: Colors.primary,
|
||||
borderRadius: 4,
|
||||
},
|
||||
logintext: {
|
||||
color: Colors.formFocus,
|
||||
},
|
||||
nologin: {
|
||||
marginTop: 16,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: 128,
|
||||
height: 28,
|
||||
borderRadius: 4,
|
||||
borderColor: Colors.divider,
|
||||
borderWidth: 1,
|
||||
},
|
||||
nologintext: {
|
||||
color: Colors.grey,
|
||||
},
|
||||
create: {
|
||||
marginTop: 16,
|
||||
},
|
||||
createtext: {
|
||||
color: 'yellow',
|
||||
},
|
||||
nocreatetext: {
|
||||
color: Colors.disabled,
|
||||
},
|
||||
bottom: {
|
||||
display: 'flex',
|
||||
flexGrow: 1,
|
||||
alignItems: 'flex-end',
|
||||
justifyContent: 'flex-end',
|
||||
paddingBottom: 16,
|
||||
},
|
||||
})
|
||||
|
78
app/mobile/src/access/login/useLogin.hook.js
Normal file
@ -0,0 +1,78 @@
|
||||
import { useState, useEffect, useContext } from 'react';
|
||||
import { useWindowDimensions } from 'react-native';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { AppContext } from 'context/AppContext';
|
||||
|
||||
export function useLogin() {
|
||||
|
||||
const navigate = useNavigate();
|
||||
const app = useContext(AppContext);
|
||||
|
||||
const [state, setState] = useState({
|
||||
busy: false,
|
||||
enabled: false,
|
||||
login: null,
|
||||
password: null,
|
||||
showPassword: false,
|
||||
});
|
||||
|
||||
const updateState = (value) => {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (app.state.session) {
|
||||
navigate('/session');
|
||||
}
|
||||
}, [app.state.session]);
|
||||
|
||||
useEffect(() => {
|
||||
if (state.password && state.login && !state.enabled && state.login.includes('@')) {
|
||||
updateState({ enabled: true });
|
||||
}
|
||||
if ((!state.password || !state.login || !state.login.includes('@')) && state.enabled) {
|
||||
updateState({ enabled: false });
|
||||
}
|
||||
}, [state.login, state.password]);
|
||||
|
||||
const actions = {
|
||||
config: () => {
|
||||
navigate('/admin');
|
||||
},
|
||||
setLogin: (login) => {
|
||||
updateState({ login });
|
||||
},
|
||||
setPassword: (password) => {
|
||||
updateState({ password });
|
||||
},
|
||||
create: () => {
|
||||
navigate('/create');
|
||||
},
|
||||
reset: () => {
|
||||
navigate('/reset');
|
||||
},
|
||||
showPassword: () => {
|
||||
updateState({ showPassword: true });
|
||||
},
|
||||
hidePassword: () => {
|
||||
updateState({ showPassword: false });
|
||||
},
|
||||
login: async () => {
|
||||
if (!state.busy) {
|
||||
updateState({ busy: true });
|
||||
try {
|
||||
await app.actions.login(state.login.trim(), state.password);
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
updateState({ busy: false, showAlert: true });
|
||||
throw new Error('login failed');
|
||||
}
|
||||
updateState({ busy: false });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return { state, actions };
|
||||
}
|
||||
|
70
app/mobile/src/access/reset/Reset.jsx
Normal file
@ -0,0 +1,70 @@
|
||||
import { KeyboardAvoidingView, ActivityIndicator, Alert, Text, TextInput, View, TouchableOpacity } from 'react-native';
|
||||
import { styles } from './Reset.styled';
|
||||
import Ionicons from 'react-native-vector-icons/AntDesign';
|
||||
import { useReset } from './useReset.hook';
|
||||
import Colors from 'constants/Colors';
|
||||
|
||||
export function Reset() {
|
||||
|
||||
const { state, actions } = useReset();
|
||||
|
||||
const reset = async () => {
|
||||
try {
|
||||
await actions.access();
|
||||
}
|
||||
catch (err) {
|
||||
Alert.alert(
|
||||
"Access Failed",
|
||||
"Please check your server and token.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView style={styles.wrapper} behavior="padding" enabled={Platform.OS === 'ios' ? true : false}>
|
||||
<View style={styles.container}>
|
||||
<View style={styles.control}>
|
||||
<TouchableOpacity onPress={actions.config}>
|
||||
<Ionicons style={styles.config} name="setting" size={24} color="#aaaaaa" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<Text style={styles.title}>Databag</Text>
|
||||
<View style={styles.spacemid}>
|
||||
<Text style={styles.header}>Access Account</Text>
|
||||
</View>
|
||||
<View style={styles.spacetop}>
|
||||
<View style={styles.inputwrapper}>
|
||||
<Ionicons style={styles.icon} name="database" size={18} color="#aaaaaa" />
|
||||
<TextInput style={styles.inputfield} value={state.server} onChangeText={actions.setServer}
|
||||
autoCapitalize="none" placeholder="server" placeholderTextColor={Colors.grey} />
|
||||
<View style={styles.space} />
|
||||
</View>
|
||||
<View style={styles.inputwrapper}>
|
||||
<Ionicons style={styles.icon} name="key" size={18} color="#aaaaaa" />
|
||||
<TextInput style={styles.inputfield} value={state.token} onChangeText={actions.setToken}
|
||||
autoCapitalize="none" placeholder="token" placeholderTextColor={Colors.grey} />
|
||||
<View style={styles.space} />
|
||||
</View>
|
||||
{ state.enabled && (
|
||||
<TouchableOpacity style={styles.reset} onPress={reset}>
|
||||
{ state.busy && (
|
||||
<ActivityIndicator size="small" color="#ffffff" />
|
||||
)}
|
||||
{ !state.busy && (
|
||||
<Text style={styles.resettext}>Access</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
{ !state.enabled && (
|
||||
<View style={styles.noreset}>
|
||||
<Text style={styles.noresettext}>Access</Text>
|
||||
</View>
|
||||
)}
|
||||
<TouchableOpacity style={styles.login} onPress={actions.login}>
|
||||
<Text style={styles.createtext}>Account Login</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
}
|
113
app/mobile/src/access/reset/Reset.styled.js
Normal file
@ -0,0 +1,113 @@
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { Colors } from 'constants/Colors';
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
wrapper: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
config: {
|
||||
paddingTop: 8,
|
||||
},
|
||||
icon: {
|
||||
padding: 8,
|
||||
},
|
||||
space: {
|
||||
width: 32,
|
||||
},
|
||||
container: {
|
||||
flexDirection: 'column',
|
||||
backgroundColor: Colors.formBackground,
|
||||
borderRadius: 4,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
paddingLeft: 16,
|
||||
paddingRight: 16,
|
||||
},
|
||||
control: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
color: Colors.grey,
|
||||
},
|
||||
title: {
|
||||
width: '100%',
|
||||
textAlign: 'center',
|
||||
fontSize: 24,
|
||||
color: Colors.grey,
|
||||
},
|
||||
spacemid: {
|
||||
flexGrow: 1,
|
||||
flexDirection: 'column',
|
||||
textAlign: 'center',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: '100%',
|
||||
},
|
||||
spacetop: {
|
||||
flexGrow: 1,
|
||||
flexDirection: 'column',
|
||||
textAlign: 'center',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
width: '100%',
|
||||
},
|
||||
header: {
|
||||
fontSize: 32,
|
||||
color: Colors.text,
|
||||
},
|
||||
inputwrapper: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
borderRadius: 4,
|
||||
borderColor: Colors.divider,
|
||||
borderWidth: 1,
|
||||
marginBottom: 16,
|
||||
alignItems: 'center',
|
||||
},
|
||||
inputfield: {
|
||||
flex: 1,
|
||||
textAlign: 'center',
|
||||
padding: 8,
|
||||
},
|
||||
reset: {
|
||||
marginTop: 16,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: 128,
|
||||
height: 28,
|
||||
backgroundColor: Colors.primary,
|
||||
borderRadius: 4,
|
||||
},
|
||||
resettext: {
|
||||
color: Colors.formFocus,
|
||||
},
|
||||
noreset: {
|
||||
marginTop: 16,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: 128,
|
||||
height: 28,
|
||||
borderRadius: 4,
|
||||
borderColor: Colors.divider,
|
||||
borderWidth: 1,
|
||||
},
|
||||
noresettext: {
|
||||
color: Colors.grey,
|
||||
},
|
||||
login: {
|
||||
marginTop: 16,
|
||||
},
|
||||
logintext: {
|
||||
color: 'yellow',
|
||||
},
|
||||
nologintext: {
|
||||
color: Colors.disabled,
|
||||
},
|
||||
|
||||
})
|
||||
|
68
app/mobile/src/access/reset/useReset.hook.js
Normal file
@ -0,0 +1,68 @@
|
||||
import { useState, useEffect, useContext } from 'react';
|
||||
import { useWindowDimensions } from 'react-native';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { AppContext } from 'context/AppContext';
|
||||
|
||||
export function useReset() {
|
||||
|
||||
const navigate = useNavigate();
|
||||
const app = useContext(AppContext);
|
||||
|
||||
const [state, setState] = useState({
|
||||
busy: false,
|
||||
enabled: false,
|
||||
server: null,
|
||||
token: null,
|
||||
});
|
||||
|
||||
const updateState = (value) => {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (app.state.session) {
|
||||
navigate('/session');
|
||||
}
|
||||
}, [app.state.session]);
|
||||
|
||||
useEffect(() => {
|
||||
if (state.token && state.server && !state.enabled) {
|
||||
updateState({ enabled: true });
|
||||
}
|
||||
if ((!state.token || !state.server) && state.enabled) {
|
||||
updateState({ enabled: false });
|
||||
}
|
||||
}, [state.server, state.token]);
|
||||
|
||||
const actions = {
|
||||
config: () => {
|
||||
navigate('/admin');
|
||||
},
|
||||
setServer: (server) => {
|
||||
updateState({ server });
|
||||
},
|
||||
setToken: (token) => {
|
||||
updateState({ token });
|
||||
},
|
||||
login: () => {
|
||||
navigate('/login');
|
||||
},
|
||||
access: async () => {
|
||||
if (!state.busy) {
|
||||
try {
|
||||
updateState({ busy: true });
|
||||
await app.actions.access(state.server.trim(), state.token);
|
||||
updateState({ busy: false });
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
updateState({ busy: false });
|
||||
throw new Error("access failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return { state, actions };
|
||||
}
|
||||
|
30
app/mobile/src/access/useAccess.hook.js
Normal file
@ -0,0 +1,30 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useWindowDimensions } from 'react-native';
|
||||
import config from 'constants/Config';
|
||||
|
||||
export function useAccess() {
|
||||
|
||||
const [state, setState] = useState({
|
||||
split: null,
|
||||
});
|
||||
const dimensions = useWindowDimensions();
|
||||
|
||||
const updateState = (value) => {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (dimensions.width > config.tabbedWidth) {
|
||||
updateState({ split: true });
|
||||
}
|
||||
else {
|
||||
updateState({ split: false });
|
||||
}
|
||||
}, [dimensions]);
|
||||
|
||||
const actions = {
|
||||
};
|
||||
|
||||
return { state, actions };
|
||||
}
|
||||
|
11
app/mobile/src/dashboard/Dashboard.jsx
Normal file
@ -0,0 +1,11 @@
|
||||
import { Text } from 'react-native';
|
||||
import { styles } from './Dashboard.styled';
|
||||
import { useDashboard } from './useDashboard.hook';
|
||||
|
||||
export function Dashboard(props) {
|
||||
|
||||
const { state, actions } = useDashboard(config, server, token);
|
||||
|
||||
return <Text>DASHBOARD</Text>;
|
||||
}
|
||||
|
227
app/mobile/src/dashboard/Dashboard.styled.js
Normal file
@ -0,0 +1,227 @@
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { Colors } from 'constants/Colors';
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
container: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
backgroundColor: Colors.formBackground,
|
||||
},
|
||||
header: {
|
||||
paddingTop: 24,
|
||||
paddingBottom: 4,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
borderBottomWidth: 1,
|
||||
borderColor: Colors.grey,
|
||||
},
|
||||
headerLabel: {
|
||||
paddingLeft: 16,
|
||||
fontSize: 20,
|
||||
color: Colors.text,
|
||||
},
|
||||
icon: {
|
||||
color: Colors.primary,
|
||||
paddingLeft: 16,
|
||||
},
|
||||
end: {
|
||||
flexGrow: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
paddingRight: 32,
|
||||
},
|
||||
accounts: {
|
||||
borderBottomWidth: 1,
|
||||
borderColor: Colors.grey,
|
||||
flexGrow: 1,
|
||||
flexShrink: 1,
|
||||
minHeight: 0,
|
||||
},
|
||||
account: {
|
||||
width: '100%',
|
||||
height: 48,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
paddingLeft: 24,
|
||||
paddingRight: 24,
|
||||
alignItems: 'center',
|
||||
borderBottomWidth: 1,
|
||||
borderColor: Colors.divider,
|
||||
},
|
||||
details: {
|
||||
paddingLeft: 16,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
},
|
||||
list: {
|
||||
paddingTop: 8,
|
||||
},
|
||||
name: {
|
||||
fontSize: 14,
|
||||
color: Colors.text,
|
||||
},
|
||||
handle: {
|
||||
fontSize: 14,
|
||||
color: Colors.text,
|
||||
},
|
||||
control: {
|
||||
flexGrow: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
delete: {
|
||||
color: Colors.alert,
|
||||
paddingLeft: 16,
|
||||
},
|
||||
unlock: {
|
||||
color: Colors.alert,
|
||||
paddingLeft: 16,
|
||||
},
|
||||
disable: {
|
||||
color: Colors.pending,
|
||||
paddingLeft: 16,
|
||||
},
|
||||
saveText: {
|
||||
color: Colors.white,
|
||||
},
|
||||
save: {
|
||||
backgroundColor: Colors.primary,
|
||||
borderRadius: 4,
|
||||
padding: 6,
|
||||
marginRight: 8,
|
||||
width: 72,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
},
|
||||
cancel: {
|
||||
borderWidth: 1,
|
||||
borderColor: Colors.lightgrey,
|
||||
borderRadius: 4,
|
||||
padding: 6,
|
||||
marginRight: 8,
|
||||
width: 72,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
},
|
||||
modalBackground: {
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: 'rgba(52, 52, 52, 0.8)'
|
||||
},
|
||||
modalControls: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
paddingTop: 16,
|
||||
borderTopWidth: 1,
|
||||
borderColor: Colors.divider,
|
||||
},
|
||||
modalContainer: {
|
||||
backgroundColor: Colors.formBackground,
|
||||
padding: 16,
|
||||
width: '80%',
|
||||
maxWidth: 400,
|
||||
},
|
||||
modalHeader: {
|
||||
paddingBottom: 4,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: Colors.divider,
|
||||
paddingLeft: 8,
|
||||
},
|
||||
modalHeaderText: {
|
||||
fontSize: 18,
|
||||
},
|
||||
modalBody: {
|
||||
padding: 8,
|
||||
},
|
||||
accessToken: {
|
||||
padding: 16,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
modalLabel: {
|
||||
paddingTop: 8,
|
||||
color: Colors.text,
|
||||
},
|
||||
keyType: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
padding: 8,
|
||||
},
|
||||
option: {
|
||||
color: Colors.text,
|
||||
},
|
||||
optionLeft: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
},
|
||||
optionRight: {
|
||||
flexGrow: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
radio: {
|
||||
width: 16,
|
||||
height: 16,
|
||||
borderRadius: 8,
|
||||
borderColor: Colors.primary,
|
||||
borderWidth: 1,
|
||||
marginRight: 8,
|
||||
},
|
||||
selected: {
|
||||
width: 16,
|
||||
height: 16,
|
||||
borderRadius: 8,
|
||||
borderColor: Colors.primary,
|
||||
borderWidth: 1,
|
||||
marginRight: 8,
|
||||
backgroundColor: Colors.background,
|
||||
},
|
||||
input: {
|
||||
marginTop: 4,
|
||||
backgroundColor: Colors.white,
|
||||
padding: 4,
|
||||
borderRadius: 4,
|
||||
marginBottom: 16,
|
||||
fontSize: 16,
|
||||
color: Colors.text,
|
||||
},
|
||||
switch: {
|
||||
transform: [{ scaleX: .7 }, { scaleY: .7 }],
|
||||
},
|
||||
track: {
|
||||
false: Colors.grey,
|
||||
true: Colors.background,
|
||||
},
|
||||
media: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
marginTop: 8,
|
||||
alignItems: 'center',
|
||||
},
|
||||
tokenLabel: {
|
||||
fontSize: 16,
|
||||
color: Colors.text,
|
||||
},
|
||||
copy: {
|
||||
marginLeft: 8,
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
padding: 8,
|
||||
borderWidth: 1,
|
||||
borderRadius: 4,
|
||||
borderColor: Colors.divider,
|
||||
},
|
||||
});
|
131
app/mobile/src/dashboard/useDashboard.hook.js
Normal file
@ -0,0 +1,131 @@
|
||||
import { useState, useEffect, useContext } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { AppContext } from 'context/AppContext';
|
||||
import { getNodeStatus } from 'api/getNodeStatus';
|
||||
import { setNodeStatus } from 'api/setNodeStatus';
|
||||
import { getNodeConfig } from 'api/getNodeConfig';
|
||||
import { setNodeConfig } from 'api/setNodeConfig';
|
||||
import { getNodeAccounts } from 'api/getNodeAccounts';
|
||||
import { getAccountImageUrl } from 'api/getAccountImageUrl';
|
||||
import { removeAccount } from 'api/removeAccount';
|
||||
import { addAccountCreate } from 'api/addAccountCreate';
|
||||
import { setAccountStatus } from 'api/setAccountStatus';
|
||||
import { addAccountAccess } from 'api/addAccountAccess';
|
||||
|
||||
export function useDashboard(config, server, token) {
|
||||
|
||||
const [state, setState] = useState({
|
||||
config: null,
|
||||
accounts: [],
|
||||
editConfig: false,
|
||||
addUser: false,
|
||||
accessUser: false,
|
||||
accessId: null,
|
||||
domain: null,
|
||||
storage: null,
|
||||
keyType: null,
|
||||
enableImage: true,
|
||||
enableAudio: true,
|
||||
enableVideo: true,
|
||||
createToken: null,
|
||||
});
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const updateState = (value) => {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
const setAccountItem = (item) => {
|
||||
const { name, handle, imageSet, accountId, disabled } = item;
|
||||
|
||||
let logo;
|
||||
if (imageSet) {
|
||||
logo = getAccountImageUrl(server, token, accountId);
|
||||
}
|
||||
else {
|
||||
logo = 'avatar';
|
||||
}
|
||||
return { logo, name, handle, accountId, disabled };
|
||||
}
|
||||
|
||||
const refreshAccounts = async () => {
|
||||
const accounts = await getNodeAccounts(server, token);
|
||||
updateState({ accounts: accounts.map(setAccountItem) });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const { keyType, accountStorage, domain, enableImage, enableAudio, enableVideo, pushSupported } = config;
|
||||
updateState({ keyType, storage: accountStorage.toString(), domain, enableImage, enableAudio, enableVideo, pushSupported });
|
||||
}, [config]);
|
||||
|
||||
useEffect(() => {
|
||||
refreshAccounts();
|
||||
}, []);
|
||||
|
||||
const actions = {
|
||||
logout: () => {
|
||||
navigate('/admin');
|
||||
},
|
||||
refresh: () => {
|
||||
refreshAccounts();
|
||||
},
|
||||
showEditConfig: () => {
|
||||
updateState({ editConfig: true });
|
||||
},
|
||||
hideEditConfig: () => {
|
||||
updateState({ editConfig: false });
|
||||
},
|
||||
addUser: async () => {
|
||||
const createToken = await addAccountCreate(server, token);
|
||||
updateState({ addUser: true, createToken });
|
||||
},
|
||||
hideAddUser: () => {
|
||||
updateState({ addUser: false });
|
||||
},
|
||||
accessUser: async (accountId) => {
|
||||
const accessToken = await addAccountAccess(server, token, accountId);
|
||||
updateState({ accessUser: true, accessToken });
|
||||
},
|
||||
hideAccessUser: () => {
|
||||
updateState({ accessUser: false });
|
||||
},
|
||||
setDomain: (domain) => {
|
||||
updateState({ domain });
|
||||
},
|
||||
setStorage: (storage) => {
|
||||
updateState({ storage: Number(storage.replace(/[^0-9]/g, '')) });
|
||||
},
|
||||
setPushSupported: (pushSupported) => {
|
||||
updateState({ pushSupported });
|
||||
},
|
||||
setEnableImage: (enableImage) => {
|
||||
updateState({ enableImage });
|
||||
},
|
||||
setEnableAudio: (enableAudio) => {
|
||||
updateState({ enableAudio });
|
||||
},
|
||||
setEnableVideo: (enableVideo) => {
|
||||
updateState({ enableVideo });
|
||||
},
|
||||
setKeyType: (keyType) => {
|
||||
updateState({ keyType });
|
||||
},
|
||||
saveConfig: async () => {
|
||||
const { storage, domain, keyType, enableImage, enableAudio, enableVideo } = state;
|
||||
const config = { accountStorage: Number(storage), domain, keyType, enableImage, enableAudio, enableVideo };
|
||||
await setNodeConfig(server, token, config);
|
||||
},
|
||||
enableUser: async (accountId, enabled) => {
|
||||
await setAccountStatus(server, token, accountId, !enabled);
|
||||
await refreshAccounts();
|
||||
},
|
||||
removeUser: async (accountId) => {
|
||||
await removeAccount(server, token, accountId);
|
||||
await refreshAccounts();
|
||||
},
|
||||
};
|
||||
|
||||
return { state, actions };
|
||||
}
|
||||
|
@ -12,6 +12,15 @@ export function useRoot() {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (app.state.session === true) {
|
||||
navigate('/session');
|
||||
}
|
||||
if (app.state.session === false) {
|
||||
navigate('/login');
|
||||
}
|
||||
}, [app.state]);
|
||||
|
||||
const actions = {
|
||||
};
|
||||
|
||||
|
12
app/mobile/src/session/Session.jsx
Normal file
@ -0,0 +1,12 @@
|
||||
import { Text } from 'react-native';
|
||||
import { styles } from './Session.styled';
|
||||
import { useSession } from './useSession.hook';
|
||||
|
||||
export function Session() {
|
||||
|
||||
const { state, actions } = useSession();
|
||||
|
||||
return <Text>SESSION</Text>
|
||||
}
|
||||
|
||||
|
132
app/mobile/src/session/Session.styled.js
Normal file
@ -0,0 +1,132 @@
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { Colors } from 'constants/Colors';
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
body: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: Colors.formBackground,
|
||||
},
|
||||
container: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
firstRun: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: Colors.background,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
splash: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
maxWidth: '80%',
|
||||
maxHeight: '50%',
|
||||
},
|
||||
steps: {
|
||||
flexGrow: 1,
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
step: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingBottom: 12,
|
||||
},
|
||||
titleText: {
|
||||
color: Colors.white,
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
tagText: {
|
||||
paddingTop: 8,
|
||||
color: Colors.white,
|
||||
fontSize: 16,
|
||||
},
|
||||
title: {
|
||||
flexGrow: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
stepText: {
|
||||
color: Colors.white,
|
||||
paddingLeft: 16,
|
||||
fontSize: 16,
|
||||
},
|
||||
start: {
|
||||
marginTop: 16,
|
||||
padding: 8,
|
||||
backgroundColor: Colors.primary,
|
||||
borderRadius: 4,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
},
|
||||
startText: {
|
||||
color: Colors.white,
|
||||
},
|
||||
tabBar: {
|
||||
backgroundColor: Colors.primary,
|
||||
},
|
||||
home: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
height: '100%',
|
||||
},
|
||||
sidebar: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
height: '100%',
|
||||
width: '33%',
|
||||
maxWidth: 500,
|
||||
},
|
||||
conversation: {
|
||||
width: '67%',
|
||||
},
|
||||
drawer: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
paddingLeft: 8,
|
||||
backgroundColor: Colors.formBackground,
|
||||
},
|
||||
options: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
paddingTop: 8,
|
||||
paddingBottom: 4,
|
||||
paddingRight: 8,
|
||||
},
|
||||
option: {
|
||||
width: '50%',
|
||||
height: 32,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
},
|
||||
icon: {
|
||||
paddingRight: 8,
|
||||
},
|
||||
channels: {
|
||||
flexGrow: 1,
|
||||
flexShrink: 1,
|
||||
position: 'relative',
|
||||
},
|
||||
tabframe: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
disconnected: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: 4,
|
||||
backgroundColor: Colors.alert,
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
},
|
||||
profileLabel: {
|
||||
paddingLeft: 8,
|
||||
},
|
||||
});
|
13
app/mobile/src/session/useSession.hook.js
Normal file
@ -0,0 +1,13 @@
|
||||
import { useRef, useState, useEffect, useContext } from 'react';
|
||||
|
||||
export function useSession() {
|
||||
|
||||
const [state, setState] = useState({
|
||||
});
|
||||
|
||||
const actions = {
|
||||
};
|
||||
|
||||
return { state, actions };
|
||||
}
|
||||
|
@ -757,6 +757,13 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.18.6"
|
||||
|
||||
"@babel/plugin-transform-object-assign@^7.16.7":
|
||||
version "7.18.6"
|
||||
resolved "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.18.6.tgz"
|
||||
integrity sha512-mQisZ3JfqWh2gVXvfqYCAAyRs6+7oev+myBsTwW5RnPhYXOTuCEw2oe3YgxlXMViXUS53lG8koulI7mJ+8JE+A==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.18.6"
|
||||
|
||||
"@babel/plugin-transform-object-super@^7.0.0", "@babel/plugin-transform-object-super@^7.18.6":
|
||||
version "7.18.6"
|
||||
resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz"
|
||||
@ -999,7 +1006,7 @@
|
||||
"@babel/types" "^7.4.4"
|
||||
esutils "^2.0.2"
|
||||
|
||||
"@babel/preset-typescript@^7.13.0":
|
||||
"@babel/preset-typescript@^7.13.0", "@babel/preset-typescript@^7.16.7":
|
||||
version "7.18.6"
|
||||
resolved "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz"
|
||||
integrity sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==
|
||||
@ -1072,7 +1079,7 @@
|
||||
|
||||
"@egjs/hammerjs@^2.0.17":
|
||||
version "2.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@egjs/hammerjs/-/hammerjs-2.0.17.tgz#5dc02af75a6a06e4c2db0202cae38c9263895124"
|
||||
resolved "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz"
|
||||
integrity sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==
|
||||
dependencies:
|
||||
"@types/hammerjs" "^2.0.36"
|
||||
@ -1672,7 +1679,7 @@
|
||||
|
||||
"@react-native-firebase/app@^17.2.0":
|
||||
version "17.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-firebase/app/-/app-17.2.0.tgz#1c08fec73e7d8bd2fde71843aa1812a16257ff1e"
|
||||
resolved "https://registry.npmjs.org/@react-native-firebase/app/-/app-17.2.0.tgz"
|
||||
integrity sha512-eZESR0O9RFlC12hQUGD/VmCDwdo36RBv3Uldce1xplewEyQoWgxsVJiBXbrW6BdYnVCqfFx3CPwsxL1CAPB8CQ==
|
||||
dependencies:
|
||||
"@expo/config-plugins" "^5.0.4"
|
||||
@ -1681,7 +1688,7 @@
|
||||
|
||||
"@react-native-firebase/messaging@^17.2.0":
|
||||
version "17.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-firebase/messaging/-/messaging-17.2.0.tgz#87d3de8a4481d55c680edeae2a6c0527e6e1b6de"
|
||||
resolved "https://registry.npmjs.org/@react-native-firebase/messaging/-/messaging-17.2.0.tgz"
|
||||
integrity sha512-uIPrZqiE8EmlyKhAL9WJyq4gaLmUFeAbAL3zpxdeZ2S1vGIh5pnloLh+inffXEE1qHId/wdfdIsetU9tBSsP/w==
|
||||
|
||||
"@react-native/assets@1.0.0":
|
||||
@ -1699,9 +1706,18 @@
|
||||
resolved "https://registry.npmjs.org/@react-native/polyfills/-/polyfills-2.0.0.tgz"
|
||||
integrity sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ==
|
||||
|
||||
"@react-navigation/bottom-tabs@^6.5.5":
|
||||
version "6.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.5.tgz#901e213560b669ed4a58cfa12880beb65d3b819f"
|
||||
integrity sha512-NKnbniyw7eEx1ubXHQ1Rx2rwj33cYQ4ffX0ZN8/UCncCY2Y1ruCjh3x3eEWVeZY8rPicLUaX3h0742CAh5mjEw==
|
||||
dependencies:
|
||||
"@react-navigation/elements" "^1.3.15"
|
||||
color "^4.2.3"
|
||||
warn-once "^0.1.0"
|
||||
|
||||
"@react-navigation/core@^6.4.6":
|
||||
version "6.4.6"
|
||||
resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-6.4.6.tgz#b0738667dec5927b01c4c496c2f4c73ef8a5e4dd"
|
||||
resolved "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.6.tgz"
|
||||
integrity sha512-6zaAgUT5k4vhJlddUk2l52RZyMkMelHdrRv1cL57ALi2RZzERdgmbiMKhJerxFLn9S8E3PUe8vwxHzjHOZKG4w==
|
||||
dependencies:
|
||||
"@react-navigation/routers" "^6.1.6"
|
||||
@ -1711,9 +1727,31 @@
|
||||
react-is "^16.13.0"
|
||||
use-latest-callback "^0.1.5"
|
||||
|
||||
"@react-navigation/drawer@^6.6.0":
|
||||
version "6.6.0"
|
||||
resolved "https://registry.npmjs.org/@react-navigation/drawer/-/drawer-6.6.0.tgz"
|
||||
integrity sha512-/GJZrFOwgsd2vfIYYSG382iHIwufYURYtIs9y3gWkBBJVu9RcAZ6BbUtxeF8CC1PqpC4WHlqzxz+6L922Tw54g==
|
||||
dependencies:
|
||||
"@react-navigation/elements" "^1.3.15"
|
||||
color "^4.2.3"
|
||||
warn-once "^0.1.0"
|
||||
|
||||
"@react-navigation/elements@^1.3.15":
|
||||
version "1.3.15"
|
||||
resolved "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.15.tgz"
|
||||
integrity sha512-CR4CEYJVY0OLyeLQi9N3Z2o4K47gXctvFxfZizDuW1xFtCJbA0eGvpjSLXEWHoY0hFjrlC6KinpdepGHVxhYIg==
|
||||
|
||||
"@react-navigation/native-stack@^6.9.10":
|
||||
version "6.9.10"
|
||||
resolved "https://registry.yarnpkg.com/@react-navigation/native-stack/-/native-stack-6.9.10.tgz#5a5d5de9f49b72e603d0cdca9771e0324f65c1c7"
|
||||
integrity sha512-dSazcWNxHg4qkid/AxFRvbhRtNXy/RqE00h/Qp+d7aBN0TwrOJn8mH/Inkkf4pHAntMbj0+mVAlKfxKmyLEGlA==
|
||||
dependencies:
|
||||
"@react-navigation/elements" "^1.3.15"
|
||||
warn-once "^0.1.0"
|
||||
|
||||
"@react-navigation/native@^6.1.4":
|
||||
version "6.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-6.1.4.tgz#49666596c9df16e22284f35f482d05d6b5d47d60"
|
||||
resolved "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.4.tgz"
|
||||
integrity sha512-8IGpMFvD21XINpSf9gyU19yv4O+NyF9FQAxEzwbJSef19W5XEJKXPN/0RINc43Tt+YnQyFGQ2+qJM1uoB9pKcA==
|
||||
dependencies:
|
||||
"@react-navigation/core" "^6.4.6"
|
||||
@ -1723,14 +1761,14 @@
|
||||
|
||||
"@react-navigation/routers@^6.1.6":
|
||||
version "6.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@react-navigation/routers/-/routers-6.1.6.tgz#f57f2a73855d329255aa225fdad75ae8e7700c6d"
|
||||
resolved "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.6.tgz"
|
||||
integrity sha512-Z5DeCW3pUvMafbU9Cjy1qJYC2Bvl8iy3+PfsB0DsAwQ6zZ3WAXW5FTMX4Gb9H+Jg6qHWGbMFFwlYpS3UJ3tlVQ==
|
||||
dependencies:
|
||||
nanoid "^3.1.23"
|
||||
|
||||
"@remix-run/router@1.3.2":
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.3.2.tgz#58cd2bd25df2acc16c628e1b6f6150ea6c7455bc"
|
||||
resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.3.2.tgz"
|
||||
integrity sha512-t54ONhl/h75X94SWsHGQ4G/ZrCEguKSRQr7DrjTciJXW0YU1QhlwYeycvK5JgkzlxmvrK7wq1NB/PLtHxoiDcA==
|
||||
|
||||
"@sideway/address@^4.1.3":
|
||||
@ -1771,7 +1809,7 @@
|
||||
|
||||
"@testing-library/dom@^8.20.0":
|
||||
version "8.20.0"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.20.0.tgz#914aa862cef0f5e89b98cc48e3445c4c921010f6"
|
||||
resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.0.tgz"
|
||||
integrity sha512-d9ULIT+a4EXLX3UU8FBjauG9NnsZHkHztXoIcTsOKoOw030fyjheN9svkTULjJxtYag9DZz5Jz5qkWZDPxTFwA==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.10.4"
|
||||
@ -1785,7 +1823,7 @@
|
||||
|
||||
"@testing-library/react-native@^11.5.2":
|
||||
version "11.5.2"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/react-native/-/react-native-11.5.2.tgz#64238431de1ce4e128810bf8277a7cc118f1c812"
|
||||
resolved "https://registry.npmjs.org/@testing-library/react-native/-/react-native-11.5.2.tgz"
|
||||
integrity sha512-haa/82Sy4ngAbXF6VTw5U306ZQHWfv7OKxALA4AkMKnX+6frhSd9aAe9rp50CyI2XJsNna0Rh6G+CSw+SPztYg==
|
||||
dependencies:
|
||||
pretty-format "^29.4.0"
|
||||
@ -1797,7 +1835,7 @@
|
||||
|
||||
"@types/aria-query@^5.0.1":
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.1.tgz#3286741fb8f1e1580ac28784add4c7a1d49bdfbc"
|
||||
resolved "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz"
|
||||
integrity sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==
|
||||
|
||||
"@types/babel__core@^7.1.14":
|
||||
@ -1842,7 +1880,7 @@
|
||||
|
||||
"@types/hammerjs@^2.0.36":
|
||||
version "2.0.41"
|
||||
resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.41.tgz#f6ecf57d1b12d2befcce00e928a6a097c22980aa"
|
||||
resolved "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz"
|
||||
integrity sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA==
|
||||
|
||||
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
|
||||
@ -2035,7 +2073,7 @@
|
||||
|
||||
"@ungap/url-search-params@^0.1.4":
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@ungap/url-search-params/-/url-search-params-0.1.4.tgz#727e9b4c811beaa6be6d7e4cc0516663c884cfd0"
|
||||
resolved "https://registry.npmjs.org/@ungap/url-search-params/-/url-search-params-0.1.4.tgz"
|
||||
integrity sha512-RLwrxCTDNiNev9hpr9rDq8NyeQ8Nn0X1we4Wu7Tlf368I8r+7hBj3uObhifhuLk74egaYaSX5nUsBlWz6kjj+A==
|
||||
|
||||
"@xmldom/xmldom@~0.7.0":
|
||||
@ -2160,7 +2198,7 @@ argparse@^2.0.1:
|
||||
|
||||
aria-query@^5.0.0:
|
||||
version "5.1.3"
|
||||
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e"
|
||||
resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz"
|
||||
integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==
|
||||
dependencies:
|
||||
deep-equal "^2.0.5"
|
||||
@ -2256,7 +2294,7 @@ async@^3.2.2:
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
|
||||
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
|
||||
|
||||
atob@^2.1.2:
|
||||
@ -2271,7 +2309,7 @@ available-typed-arrays@^1.0.5:
|
||||
|
||||
axios@^1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.3.tgz#e7011384ba839b885007c9c9fae1ff23dceb295b"
|
||||
resolved "https://registry.npmjs.org/axios/-/axios-1.3.3.tgz"
|
||||
integrity sha512-eYq77dYIFS77AQlhzEL937yUBSepBfPIe8FcgEDN35vMNZKMrs81pgnyrQpwfy4NF4b4XWX1Zgx7yX+25w8QJA==
|
||||
dependencies:
|
||||
follow-redirects "^1.15.0"
|
||||
@ -2652,6 +2690,15 @@ cliui@^6.0.0:
|
||||
strip-ansi "^6.0.0"
|
||||
wrap-ansi "^6.2.0"
|
||||
|
||||
cliui@^7.0.2:
|
||||
version "7.0.4"
|
||||
resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz"
|
||||
integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
|
||||
dependencies:
|
||||
string-width "^4.2.0"
|
||||
strip-ansi "^6.0.0"
|
||||
wrap-ansi "^7.0.0"
|
||||
|
||||
cliui@^8.0.1:
|
||||
version "8.0.1"
|
||||
resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz"
|
||||
@ -2722,11 +2769,27 @@ color-name@1.1.3:
|
||||
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
|
||||
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
|
||||
|
||||
color-name@~1.1.4:
|
||||
color-name@^1.0.0, color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
color-string@^1.9.0:
|
||||
version "1.9.1"
|
||||
resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz"
|
||||
integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==
|
||||
dependencies:
|
||||
color-name "^1.0.0"
|
||||
simple-swizzle "^0.2.2"
|
||||
|
||||
color@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.npmjs.org/color/-/color-4.2.3.tgz"
|
||||
integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==
|
||||
dependencies:
|
||||
color-convert "^2.0.1"
|
||||
color-string "^1.9.0"
|
||||
|
||||
colorette@^1.0.7:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz"
|
||||
@ -2734,7 +2797,7 @@ colorette@^1.0.7:
|
||||
|
||||
combined-stream@^1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||
resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz"
|
||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
@ -2863,7 +2926,7 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3:
|
||||
|
||||
crypto-js@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf"
|
||||
resolved "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz"
|
||||
integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==
|
||||
|
||||
csstype@^3.0.2:
|
||||
@ -2907,7 +2970,7 @@ dedent@^0.7.0:
|
||||
|
||||
deep-equal@^2.0.5:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.0.tgz#5caeace9c781028b9ff459f33b779346637c43e6"
|
||||
resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.0.tgz"
|
||||
integrity sha512-RdpzE0Hv4lhowpIUKKMJfeH6C1pXdtT1/it80ubgWqwI3qpuxUBpC1S4hnHg+zjnuOoDkzUtUCEEkG+XG5l3Mw==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
@ -2982,7 +3045,7 @@ define-property@^2.0.2:
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
|
||||
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
|
||||
|
||||
denodeify@^1.2.1:
|
||||
@ -3042,7 +3105,7 @@ doctrine@^3.0.0:
|
||||
|
||||
dom-accessibility-api@^0.5.9:
|
||||
version "0.5.16"
|
||||
resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453"
|
||||
resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz"
|
||||
integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==
|
||||
|
||||
ee-first@1.1.1:
|
||||
@ -3145,7 +3208,7 @@ es-abstract@^1.19.0, es-abstract@^1.20.4:
|
||||
|
||||
es-get-iterator@^1.1.2:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6"
|
||||
resolved "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz"
|
||||
integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
@ -3570,7 +3633,7 @@ fill-range@^7.0.1:
|
||||
|
||||
filter-obj@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b"
|
||||
resolved "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz"
|
||||
integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==
|
||||
|
||||
finalhandler@1.1.2:
|
||||
@ -3643,7 +3706,7 @@ flow-parser@^0.185.0:
|
||||
|
||||
follow-redirects@^1.15.0:
|
||||
version "1.15.2"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
|
||||
resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz"
|
||||
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
|
||||
|
||||
for-each@^0.3.3:
|
||||
@ -3672,7 +3735,7 @@ for-own@^1.0.0:
|
||||
|
||||
form-data@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
|
||||
resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz"
|
||||
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
@ -3968,7 +4031,7 @@ hermes-profile-transformer@^0.0.6:
|
||||
|
||||
hoist-non-react-statics@^3.3.0:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
|
||||
resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz"
|
||||
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
|
||||
dependencies:
|
||||
react-is "^16.7.0"
|
||||
@ -4088,7 +4151,7 @@ is-accessor-descriptor@^1.0.0:
|
||||
|
||||
is-arguments@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b"
|
||||
resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz"
|
||||
integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
@ -4108,6 +4171,11 @@ is-arrayish@^0.2.1:
|
||||
resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz"
|
||||
integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==
|
||||
|
||||
is-arrayish@^0.3.1:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz"
|
||||
integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
|
||||
|
||||
is-bigint@^1.0.1:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz"
|
||||
@ -4230,7 +4298,7 @@ is-interactive@^1.0.0:
|
||||
|
||||
is-map@^2.0.1, is-map@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127"
|
||||
resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz"
|
||||
integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==
|
||||
|
||||
is-negative-zero@^2.0.2:
|
||||
@ -4279,7 +4347,7 @@ is-regex@^1.1.4:
|
||||
|
||||
is-set@^2.0.1, is-set@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec"
|
||||
resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz"
|
||||
integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==
|
||||
|
||||
is-shared-array-buffer@^1.0.2:
|
||||
@ -4331,7 +4399,7 @@ is-unicode-supported@^0.1.0:
|
||||
|
||||
is-weakmap@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2"
|
||||
resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz"
|
||||
integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==
|
||||
|
||||
is-weakref@^1.0.2:
|
||||
@ -4343,7 +4411,7 @@ is-weakref@^1.0.2:
|
||||
|
||||
is-weakset@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d"
|
||||
resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz"
|
||||
integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
@ -4366,7 +4434,7 @@ isarray@1.0.0, isarray@~1.0.0:
|
||||
|
||||
isarray@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
|
||||
resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz"
|
||||
integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
|
||||
|
||||
isexe@^2.0.0:
|
||||
@ -5037,6 +5105,11 @@ lodash.debounce@^4.0.8:
|
||||
resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz"
|
||||
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
|
||||
|
||||
lodash.isequal@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz"
|
||||
integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==
|
||||
|
||||
lodash.merge@^4.6.2:
|
||||
version "4.6.2"
|
||||
resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
|
||||
@ -5092,7 +5165,7 @@ lru-cache@^6.0.0:
|
||||
|
||||
lz-string@^1.4.4:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26"
|
||||
resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz"
|
||||
integrity sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==
|
||||
|
||||
make-dir@^2.0.0, make-dir@^2.1.0:
|
||||
@ -5527,7 +5600,7 @@ ms@2.1.3:
|
||||
|
||||
nanoid@^3.1.23:
|
||||
version "3.3.4"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
|
||||
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz"
|
||||
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
|
||||
|
||||
nanomatch@^1.2.9:
|
||||
@ -5656,7 +5729,7 @@ object-inspect@^1.12.2, object-inspect@^1.9.0:
|
||||
|
||||
object-is@^1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac"
|
||||
resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz"
|
||||
integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
@ -5994,7 +6067,7 @@ pretty-format@^26.5.2, pretty-format@^26.6.2:
|
||||
|
||||
pretty-format@^27.0.2:
|
||||
version "27.5.1"
|
||||
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e"
|
||||
resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz"
|
||||
integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
@ -6041,7 +6114,7 @@ prop-types@*, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||
|
||||
proxy-from-env@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
||||
resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
|
||||
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
|
||||
|
||||
pump@^3.0.0:
|
||||
@ -6059,7 +6132,7 @@ punycode@^2.1.0:
|
||||
|
||||
query-string@^7.1.3:
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328"
|
||||
resolved "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz"
|
||||
integrity sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==
|
||||
dependencies:
|
||||
decode-uri-component "^0.2.2"
|
||||
@ -6102,7 +6175,7 @@ react-is@^17.0.1:
|
||||
|
||||
react-native-base64@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/react-native-base64/-/react-native-base64-0.2.1.tgz#3d0e73a649c4c0129f7b7695d3912456aebae847"
|
||||
resolved "https://registry.npmjs.org/react-native-base64/-/react-native-base64-0.2.1.tgz"
|
||||
integrity sha512-eHgt/MA8y5ZF0aHfZ1aTPcIkDWxza9AaEk4GcpIX+ZYfZ04RcaNahO+527KR7J44/mD3efYfM23O2C1N44ByWA==
|
||||
|
||||
react-native-codegen@^0.71.5:
|
||||
@ -6117,7 +6190,7 @@ react-native-codegen@^0.71.5:
|
||||
|
||||
react-native-device-info@^10.4.0:
|
||||
version "10.4.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-10.4.0.tgz#9d90706641941d7da8ab7b316a37d3111eb231e4"
|
||||
resolved "https://registry.npmjs.org/react-native-device-info/-/react-native-device-info-10.4.0.tgz"
|
||||
integrity sha512-Z37e0HtpBvfkPRgv4xN7lXpvmJyzjwCXSFTXEkw6m2UgnnIsWlOD02Avu4hJXBlIMMazaW3ZLKal3o9h3AYvCw==
|
||||
|
||||
react-native-gesture-handler@^2.9.0:
|
||||
@ -6136,21 +6209,42 @@ react-native-gradle-plugin@^0.71.15:
|
||||
resolved "https://registry.npmjs.org/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.15.tgz"
|
||||
integrity sha512-7S3pAuPaQJlhax6EZ4JMsDNpj05TfuzX9gPgWLrFfAIWIFLuJ6aDQYAZy2TEI9QJALPoWrj8LWaqP/DGYh14pw==
|
||||
|
||||
react-native-reanimated@^2.14.4:
|
||||
version "2.14.4"
|
||||
resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-2.14.4.tgz#3fa3da4e7b99f5dfb28f86bcf24d9d1024d38836"
|
||||
integrity sha512-DquSbl7P8j4SAmc+kRdd75Ianm8G+IYQ9T4AQ6lrpLVeDkhZmjWI0wkutKWnp6L7c5XNVUrFDUf69dwETLCItQ==
|
||||
dependencies:
|
||||
"@babel/plugin-transform-object-assign" "^7.16.7"
|
||||
"@babel/preset-typescript" "^7.16.7"
|
||||
convert-source-map "^1.7.0"
|
||||
invariant "^2.2.4"
|
||||
lodash.isequal "^4.5.0"
|
||||
setimmediate "^1.0.5"
|
||||
string-hash-64 "^1.0.3"
|
||||
|
||||
react-native-rsa-native@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/react-native-rsa-native/-/react-native-rsa-native-2.0.5.tgz#7db4aef49405bb5b5bcaea12b9dfd1b251c690ab"
|
||||
resolved "https://registry.npmjs.org/react-native-rsa-native/-/react-native-rsa-native-2.0.5.tgz"
|
||||
integrity sha512-gwwvFSwGW5WKrpDyBQ/eTf1UrVABeAvMcT4YWemzPSUo6aHZs1kbBm2rXmwN5okhUzJsry5zjjz/qdx5GXRugQ==
|
||||
|
||||
react-native-safe-area-context@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.5.0.tgz#9208313236e8f49e1920ac1e2a2c975f03aed284"
|
||||
resolved "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.5.0.tgz"
|
||||
integrity sha512-0WORnk9SkREGUg2V7jHZbuN5x4vcxj/1B0QOcXJjdYWrzZHgLcUzYWWIUecUPJh747Mwjt/42RZDOaFn3L8kPQ==
|
||||
|
||||
react-native-sqlite-storage@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-native-sqlite-storage/-/react-native-sqlite-storage-6.0.1.tgz#ce6a6b852f07abbea68658d5363818c8bef45dfb"
|
||||
resolved "https://registry.npmjs.org/react-native-sqlite-storage/-/react-native-sqlite-storage-6.0.1.tgz"
|
||||
integrity sha512-1tDFjrint6X6qSYKf3gDyz+XB+X79jfiL6xTugKHPRtF0WvqMtVgdLuNqZunIXjNEvNtNVEbXaeZ6MsguFu00A==
|
||||
|
||||
react-native-vector-icons@^9.2.0:
|
||||
version "9.2.0"
|
||||
resolved "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-9.2.0.tgz"
|
||||
integrity sha512-wKYLaFuQST/chH3AJRjmOLoLy3JEs1JR6zMNgTaemFpNoXs0ztRnTxcxFD9xhX7cJe1/zoN5BpQYe7kL0m5yyA==
|
||||
dependencies:
|
||||
prop-types "^15.7.2"
|
||||
yargs "^16.1.1"
|
||||
|
||||
react-native@0.71.3:
|
||||
version "0.71.3"
|
||||
resolved "https://registry.npmjs.org/react-native/-/react-native-0.71.3.tgz"
|
||||
@ -6198,7 +6292,7 @@ react-refresh@^0.4.0:
|
||||
|
||||
react-router-dom@^6.8.1:
|
||||
version "6.8.1"
|
||||
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.8.1.tgz#7e136b67d9866f55999e9a8482c7008e3c575ac9"
|
||||
resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.8.1.tgz"
|
||||
integrity sha512-67EXNfkQgf34P7+PSb6VlBuaacGhkKn3kpE51+P6zYSG2kiRoumXEL6e27zTa9+PGF2MNXbgIUHTVlleLbIcHQ==
|
||||
dependencies:
|
||||
"@remix-run/router" "1.3.2"
|
||||
@ -6206,7 +6300,7 @@ react-router-dom@^6.8.1:
|
||||
|
||||
react-router-native@^6.8.1:
|
||||
version "6.8.1"
|
||||
resolved "https://registry.yarnpkg.com/react-router-native/-/react-router-native-6.8.1.tgz#e51e08a812db51eca684dfe37a08058faf60a96e"
|
||||
resolved "https://registry.npmjs.org/react-router-native/-/react-router-native-6.8.1.tgz"
|
||||
integrity sha512-IfcVe/iZTK/JyxCsQbZRhuwnTIOM7GzxFgrU/iffDhW4x3Vfd16WsFFG6tPI+Kj1QFcSxT5LJkxJguKCJhl6Vg==
|
||||
dependencies:
|
||||
"@ungap/url-search-params" "^0.1.4"
|
||||
@ -6214,7 +6308,7 @@ react-router-native@^6.8.1:
|
||||
|
||||
react-router@6.8.1:
|
||||
version "6.8.1"
|
||||
resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.8.1.tgz#e362caf93958a747c649be1b47cd505cf28ca63e"
|
||||
resolved "https://registry.npmjs.org/react-router/-/react-router-6.8.1.tgz"
|
||||
integrity sha512-Jgi8BzAJQ8MkPt8ipXnR73rnD7EmZ0HFFb7jdQU24TynGW1Ooqin2KVDN9voSC+7xhqbbCd2cjGUepb6RObnyg==
|
||||
dependencies:
|
||||
"@remix-run/router" "1.3.2"
|
||||
@ -6563,6 +6657,11 @@ set-value@^2.0.0, set-value@^2.0.1:
|
||||
is-plain-object "^2.0.3"
|
||||
split-string "^3.0.1"
|
||||
|
||||
setimmediate@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz"
|
||||
integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==
|
||||
|
||||
setprototypeof@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz"
|
||||
@ -6636,6 +6735,13 @@ simple-plist@^1.1.0:
|
||||
bplist-parser "0.3.1"
|
||||
plist "^3.0.5"
|
||||
|
||||
simple-swizzle@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz"
|
||||
integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==
|
||||
dependencies:
|
||||
is-arrayish "^0.3.1"
|
||||
|
||||
sisteransi@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz"
|
||||
@ -6734,7 +6840,7 @@ source-map@^0.7.3:
|
||||
|
||||
split-on-first@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f"
|
||||
resolved "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz"
|
||||
integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==
|
||||
|
||||
split-string@^3.0.1, split-string@^3.0.2:
|
||||
@ -6788,7 +6894,7 @@ statuses@~1.5.0:
|
||||
|
||||
stop-iteration-iterator@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4"
|
||||
resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz"
|
||||
integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==
|
||||
dependencies:
|
||||
internal-slot "^1.0.4"
|
||||
@ -6800,9 +6906,14 @@ stream-buffers@2.2.x:
|
||||
|
||||
strict-uri-encode@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546"
|
||||
resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz"
|
||||
integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==
|
||||
|
||||
string-hash-64@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/string-hash-64/-/string-hash-64-1.0.3.tgz"
|
||||
integrity sha512-D5OKWKvDhyVWWn2x5Y9b+37NUllks34q1dCDhk/vYcso9fmhs+Tl3KR/gE4v5UNj2UA35cnX4KdVVGkG1deKqw==
|
||||
|
||||
string-length@^4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz"
|
||||
@ -7197,7 +7308,7 @@ urix@^0.1.0:
|
||||
|
||||
use-latest-callback@^0.1.5:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/use-latest-callback/-/use-latest-callback-0.1.5.tgz#a4a836c08fa72f6608730b5b8f4bbd9c57c04f51"
|
||||
resolved "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.5.tgz"
|
||||
integrity sha512-HtHatS2U4/h32NlkhupDsPlrbiD27gSH5swBdtXbCAlc6pfOFzaj0FehW/FO12rx8j2Vy4/lJScCiJyM01E+bQ==
|
||||
|
||||
use-sync-external-store@^1.0.0:
|
||||
@ -7251,6 +7362,11 @@ walker@^1.0.7, walker@^1.0.8:
|
||||
dependencies:
|
||||
makeerror "1.0.12"
|
||||
|
||||
warn-once@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.npmjs.org/warn-once/-/warn-once-0.1.1.tgz"
|
||||
integrity sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q==
|
||||
|
||||
wcwidth@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz"
|
||||
@ -7289,7 +7405,7 @@ which-boxed-primitive@^1.0.2:
|
||||
|
||||
which-collection@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906"
|
||||
resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz"
|
||||
integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==
|
||||
dependencies:
|
||||
is-map "^2.0.1"
|
||||
@ -7449,6 +7565,11 @@ yargs-parser@^18.1.2:
|
||||
camelcase "^5.0.0"
|
||||
decamelize "^1.2.0"
|
||||
|
||||
yargs-parser@^20.2.2:
|
||||
version "20.2.9"
|
||||
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz"
|
||||
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
|
||||
|
||||
yargs-parser@^21.1.1:
|
||||
version "21.1.1"
|
||||
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz"
|
||||
@ -7471,6 +7592,19 @@ yargs@^15.1.0:
|
||||
y18n "^4.0.0"
|
||||
yargs-parser "^18.1.2"
|
||||
|
||||
yargs@^16.1.1:
|
||||
version "16.2.0"
|
||||
resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz"
|
||||
integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
|
||||
dependencies:
|
||||
cliui "^7.0.2"
|
||||
escalade "^3.1.1"
|
||||
get-caller-file "^2.0.5"
|
||||
require-directory "^2.1.1"
|
||||
string-width "^4.2.0"
|
||||
y18n "^5.0.5"
|
||||
yargs-parser "^20.2.2"
|
||||
|
||||
yargs@^17.3.1, yargs@^17.5.1:
|
||||
version "17.6.2"
|
||||
resolved "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz"
|
||||
|