From c2642f534e001f083fa481fe46a05e1e8f594268 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Fri, 27 Sep 2024 09:48:36 -0700 Subject: [PATCH] formatting code --- app/client/mobile/src/LocalStore.ts | 21 +- app/client/mobile/src/NativeCrypto.ts | 101 +- app/client/mobile/src/access/Access.tsx | 42 +- app/client/mobile/src/constants/Colors.ts | 3 +- .../mobile/src/context/useAppContext.hook.ts | 21 +- .../mobile/src/identity/Identity.styled.ts | 5 +- app/client/mobile/src/identity/Identity.tsx | 122 ++- .../mobile/src/identity/useIdentity.hook.ts | 47 +- app/client/mobile/src/session/Session.tsx | 22 +- .../mobile/src/session/useSession.hook.ts | 30 +- .../mobile/src/settings/Settings.styled.ts | 9 +- app/client/mobile/src/settings/Settings.tsx | 930 ++++++++++++------ .../mobile/src/settings/useSettings.hook.ts | 208 ++-- app/client/mobile/src/utils/InputCode.tsx | 3 +- 14 files changed, 1029 insertions(+), 535 deletions(-) diff --git a/app/client/mobile/src/LocalStore.ts b/app/client/mobile/src/LocalStore.ts index 7893c2cf..7e94bf6b 100644 --- a/app/client/mobile/src/LocalStore.ts +++ b/app/client/mobile/src/LocalStore.ts @@ -11,28 +11,37 @@ export class LocalStore implements SqlStore { public async open(path: string) { this.db = await SQLite.openDatabase({name: path, location: 'default'}); - await this.localStoreSet("CREATE TABLE IF NOT EXISTS local_store (key text, value text, unique(key));"); + await this.localStoreSet( + 'CREATE TABLE IF NOT EXISTS local_store (key text, value text, unique(key));', + ); } public async get(key: string, value: string, unset: string): Promise { try { - const rows = await this.localStoreGet(`SELECT * FROM local_store WHERE key='${key}';`); + const rows = await this.localStoreGet( + `SELECT * FROM local_store WHERE key='${key}';`, + ); if (rows.length == 1 && rows[0].value != null) { return rows[0].value; } - } - catch(err) { + } catch (err) { console.log(err); } return unset; } public async set(key: string, value: string): Promise { - await this.localStoreSet('INSERT OR REPLACE INTO local_store (key, value) values (?, ?)', [key, value]); + await this.localStoreSet( + 'INSERT OR REPLACE INTO local_store (key, value) values (?, ?)', + [key, value], + ); } public async clear(key: string): Promise { - await this.localStoreSet('INSERT OR REPLACE INTO local_store (key, value) values (?, null)', [key]); + await this.localStoreSet( + 'INSERT OR REPLACE INTO local_store (key, value) values (?, null)', + [key], + ); } private async localStoreSet( diff --git a/app/client/mobile/src/NativeCrypto.ts b/app/client/mobile/src/NativeCrypto.ts index 974374ff..6734a2f0 100644 --- a/app/client/mobile/src/NativeCrypto.ts +++ b/app/client/mobile/src/NativeCrypto.ts @@ -1,109 +1,134 @@ -import { Crypto } from 'databag-client-sdk'; +import {Crypto} from 'databag-client-sdk'; import CryptoJS from 'crypto-js'; -import { JSEncrypt } from 'jsencrypt' -import { RSA } from 'react-native-rsa-native'; -import { generateSecureRandom } from 'react-native-securerandom'; +import {JSEncrypt} from 'jsencrypt'; +import {RSA} from 'react-native-rsa-native'; +import {generateSecureRandom} from 'react-native-securerandom'; export class NativeCrypto implements Crypto { - // generate salt for pbk function - public async pbkdfSalt(): Promise<{ saltHex: string }> { + public async pbkdfSalt(): Promise<{saltHex: string}> { const salt = await generateSecureRandom(16); const saltHex = this.uint8ToHexStr(salt); - return { saltHex }; + return {saltHex}; } // generate aes key with pbkdf2 - public async pbkdfKey(saltHex: string, password: string): Promise<{ aesKeyHex: string }> { + public async pbkdfKey( + saltHex: string, + password: string, + ): Promise<{aesKeyHex: string}> { const salt = CryptoJS.enc.Hex.parse(saltHex); - const aes = CryptoJS.PBKDF2(password, salt, { keySize: 256 / 32, iterations: 1024, hasher: CryptoJS.algo.SHA1, }); + const aes = CryptoJS.PBKDF2(password, salt, { + keySize: 256 / 32, + iterations: 1024, + hasher: CryptoJS.algo.SHA1, + }); const aesKeyHex = aes.toString(); - return { aesKeyHex }; + return {aesKeyHex}; } // generate random aes key - public async aesKey(): Promise<{ aesKeyHex: string }> { + public async aesKey(): Promise<{aesKeyHex: string}> { const aes = await generateSecureRandom(32); const aesHex = this.uint8ToHexStr(aes); - return { aesKeyHex }; + return {aesKeyHex}; } // generate iv to use to aes function - public async aesIv(): Promise<{ ivHex: string }> { + public async aesIv(): Promise<{ivHex: string}> { const iv = await generateSecureRandom(16); const ivHex = this.uint8ToHexStr(iv); - return { ivHex }; + return {ivHex}; } // encrypt data with aes key and iv - public async aesEncrypt(data: string, ivHex: string, aesKeyHex: string): Promise<{ encryptedDataB64: string }> { + public async aesEncrypt( + data: string, + ivHex: string, + aesKeyHex: string, + ): Promise<{encryptedDataB64: string}> { const iv = CryptoJS.enc.Hex.parse(ivHex); const key = CryptoJS.enc.Hex.parse(aesKeyHex); - const encrypted = CryptoJS.AES.encrypt(data, key, { iv }); + const encrypted = CryptoJS.AES.encrypt(data, key, {iv}); const encryptedDataB64 = encrypted.ciphertext.toString(CryptoJS.enc.Base64); - return { encryptedDataB64 }; + return {encryptedDataB64}; } // decrypt data with aes key and iv - public async aesDecrypt(encryptedDataB64: string, ivHex: string, aesKeyHex: string): Promise<{ data: string }> { + public async aesDecrypt( + encryptedDataB64: string, + ivHex: string, + aesKeyHex: string, + ): Promise<{data: string}> { const iv = CryptoJS.enc.Hex.parse(ivHex); const key = CryptoJS.enc.Hex.parse(aesKeyHex); const ciphertext = CryptoJS.enc.Base64.parse(encryptedDataB64); - const cipher = CryptoJS.lib.CipherParams.create({ ciphertext, iv }); - const decrypted = CryptoJS.AES.decrypt(cipher, key, { iv }); + const cipher = CryptoJS.lib.CipherParams.create({ciphertext, iv}); + const decrypted = CryptoJS.AES.decrypt(cipher, key, {iv}); const data = decrypted.toString(CryptoJS.enc.Utf8); - return { data }; + return {data}; } // generate rsa key - public async rsaKey(): Promise<{ publicKeyB64: string, privateKeyB64: string }> { - const crypto = new JSEncrypt({ default_key_size: '2048' }); + public async rsaKey(): Promise<{ + publicKeyB64: string; + privateKeyB64: string; + }> { + const crypto = new JSEncrypt({default_key_size: '2048'}); crypto.getKey(); const publicKey = crypto.getPublicKey(); const publicKeyB64 = this.convertPem(publicKey); const privateKey = crypto.getPrivateKey(); const privateKeyB64 = this.convertPem(privateKey); - return { publicKeyB64, privateKeyB64 }; + return {publicKeyB64, privateKeyB64}; } // encrypt data with public rsa key - public async rsaEncrypt(data: string, publicKeyB64: string): Promise<{ encryptedDataB64: string }> { + public async rsaEncrypt( + data: string, + publicKeyB64: string, + ): Promise<{encryptedDataB64: string}> { const crypto = new JSEncrypt(); crypto.setPublicKey(publicKeyB64); const encryptedDataB64 = crypto.encrypt(data); if (!encryptedDataB64) { throw new Error('rsaEncrypt failed'); } - return { encryptedDataB64 }; + return {encryptedDataB64}; } // decrypt data with private rsa key - public async rsaDecrypt(encryptedDataB64: string, privateKeyB64: string): Promise<{ data: string }> { + public async rsaDecrypt( + encryptedDataB64: string, + privateKeyB64: string, + ): Promise<{data: string}> { const crypto = new JSEncrypt(); crypto.setPrivateKey(privateKeyB64); const data = await RSA.decrypt(encryptedDataB64, privateKeyB64); if (!data) { throw new Error('rsaDecrypt failed'); } - return { data }; + return {data}; } private convertPem(pem: string): string { const lines = pem.split('\n'); let encoded = ''; - for(let i = 0;i < lines.length;i++){ - if (lines[i].trim().length > 0 && - lines[i].indexOf('-BEGIN RSA PRIVATE KEY-') < 0 && - lines[i].indexOf('-BEGIN RSA PUBLIC KEY-') < 0 && - lines[i].indexOf('-BEGIN PUBLIC KEY-') < 0 && - lines[i].indexOf('-END PUBLIC KEY-') < 0 && - lines[i].indexOf('-END RSA PRIVATE KEY-') < 0 && - lines[i].indexOf('-END RSA PUBLIC KEY-') < 0) { + for (let i = 0; i < lines.length; i++) { + if ( + lines[i].trim().length > 0 && + lines[i].indexOf('-BEGIN RSA PRIVATE KEY-') < 0 && + lines[i].indexOf('-BEGIN RSA PUBLIC KEY-') < 0 && + lines[i].indexOf('-BEGIN PUBLIC KEY-') < 0 && + lines[i].indexOf('-END PUBLIC KEY-') < 0 && + lines[i].indexOf('-END RSA PRIVATE KEY-') < 0 && + lines[i].indexOf('-END RSA PUBLIC KEY-') < 0 + ) { encoded += lines[i].trim(); } } - return encoded - }; + return encoded; + } private uint8ToHexStr(bin: Uint8Array) { let hex = ''; diff --git a/app/client/mobile/src/access/Access.tsx b/app/client/mobile/src/access/Access.tsx index 8557b0d3..c47ece77 100644 --- a/app/client/mobile/src/access/Access.tsx +++ b/app/client/mobile/src/access/Access.tsx @@ -1,10 +1,5 @@ import React, {useState} from 'react'; -import { - Platform, - KeyboardAvoidingView, - View, - Image, -} from 'react-native'; +import {Platform, KeyboardAvoidingView, View, Image} from 'react-native'; import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view'; import {useAccess} from './useAccess.hook'; import {styles} from './Access.styled'; @@ -135,12 +130,14 @@ export function Access() { left={} right={ showPassword ? ( - setShowPassword(false)} /> ) : ( - setShowPassword(true)} /> @@ -174,7 +171,9 @@ export function Access() { autoComplete="off" autoCorrect={false} label={state.strings.token} - left={} + left={ + + } onChangeText={value => actions.setToken(value)} /> } + left={ + + } onChangeText={value => actions.setToken(value)} /> )} @@ -257,12 +261,14 @@ export function Access() { left={} right={ showPassword ? ( - setShowPassword(false)} /> ) : ( - setShowPassword(true)} /> @@ -283,12 +289,14 @@ export function Access() { left={} right={ showPassword ? ( - setShowConfirm(false)} /> ) : ( - setShowConfirm(true)} /> @@ -343,12 +351,14 @@ export function Access() { left={} right={ showPassword ? ( - setShowPassword(false)} /> ) : ( - setShowPassword(true)} /> diff --git a/app/client/mobile/src/constants/Colors.ts b/app/client/mobile/src/constants/Colors.ts index 7e9c4a4d..cc106a85 100644 --- a/app/client/mobile/src/constants/Colors.ts +++ b/app/client/mobile/src/constants/Colors.ts @@ -1,5 +1,4 @@ export const Colors = { primary: '#66aa88', danger: '#ff8888', -} - +}; diff --git a/app/client/mobile/src/context/useAppContext.hook.ts b/app/client/mobile/src/context/useAppContext.hook.ts index a57e620c..90034827 100644 --- a/app/client/mobile/src/context/useAppContext.hook.ts +++ b/app/client/mobile/src/context/useAppContext.hook.ts @@ -8,7 +8,7 @@ const SETTINGS_DB = 'ls_v001.db'; export function useAppContext() { const local = useRef(new LocalStore()); - const sdk = useRef(new DatabagSDK(new NativeCrypto())) + const sdk = useRef(new DatabagSDK(new NativeCrypto())); const [state, setState] = useState({ session: null as null | Session, fullDayTime: false, @@ -22,9 +22,11 @@ export function useAppContext() { const setup = async () => { await local.current.open(SETTINGS_DB); - const fullDayTime = await local.current.get('time_format', '12h') === '24h'; - const monthFirstDate = await local.current.get('date_format', 'month_first') === 'month_first'; - + const fullDayTime = + (await local.current.get('time_format', '12h')) === '24h'; + const monthFirstDate = + (await local.current.get('date_format', 'month_first')) === 'month_first'; + const store = new SessionStore(); await store.open(DATABAG_DB); const session: Session | null = await sdk.current.initOfflineStore(store); @@ -39,11 +41,14 @@ export function useAppContext() { const actions = { setMonthFirstDate: async (monthFirstDate: boolean) => { - updateState({ monthFirstDate }); - await local.current.set('date_format', monthFirstDate ? 'month_first' : 'day_first'); + updateState({monthFirstDate}); + await local.current.set( + 'date_format', + monthFirstDate ? 'month_first' : 'day_first', + ); }, setFullDayTime: async (fullDayTime: boolean) => { - updateState({ fullDayTime }); + updateState({fullDayTime}); await local.current.set('time_format', fullDayTime ? '24h' : '12h'); }, accountLogin: async ( @@ -86,7 +91,7 @@ export function useAppContext() { accountRemove: async () => { if (state.session) { await sdk.current.remove(state.session); - updateState({ session: null }); + updateState({session: null}); } }, accountCreate: async ( diff --git a/app/client/mobile/src/identity/Identity.styled.ts b/app/client/mobile/src/identity/Identity.styled.ts index a4595e87..c23e99d6 100644 --- a/app/client/mobile/src/identity/Identity.styled.ts +++ b/app/client/mobile/src/identity/Identity.styled.ts @@ -123,9 +123,6 @@ export const styles = StyleSheet.create({ fontSize: 16, }, controlSwitch: { - transform: [ - { scaleX: 0.7 }, - {scaleY: 0.7 }, - ] + transform: [{scaleX: 0.7}, {scaleY: 0.7}], }, }); diff --git a/app/client/mobile/src/identity/Identity.tsx b/app/client/mobile/src/identity/Identity.tsx index 9788d66c..d19a45b1 100644 --- a/app/client/mobile/src/identity/Identity.tsx +++ b/app/client/mobile/src/identity/Identity.tsx @@ -1,21 +1,29 @@ -import { useState } from 'react'; -import { Modal, TouchableOpacity, SafeAreaView, View, Image } from 'react-native'; -import { Surface, IconButton, Button, Switch, Icon, Text, Menu } from 'react-native-paper'; -import { styles } from './Identity.styled'; -import { useIdentity } from './useIdentity.hook'; +import {useState} from 'react'; +import {Modal, TouchableOpacity, SafeAreaView, View, Image} from 'react-native'; +import { + Surface, + IconButton, + Button, + Switch, + Icon, + Text, + Menu, +} from 'react-native-paper'; +import {styles} from './Identity.styled'; +import {useIdentity} from './useIdentity.hook'; import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view'; import {BlurView} from '@react-native-community/blur'; -export function Identity({ openSettings }) { +export function Identity({openSettings}) { const [menu, setMenu] = useState(false); - const { state, actions } = useIdentity(); + const {state, actions} = useIdentity(); const [logout, setLogout] = useState(false); const [applyingLogout, setApplyingLogout] = useState(false); const showLogout = () => { setMenu(false); setLogout(true); - } + }; const applyLogout = async () => { if (!applyingLogout) { @@ -24,25 +32,46 @@ export function Identity({ openSettings }) { setLogout(false); setApplyingLogout(false); } - } + }; return ( <> - setMenu(true)}> + setMenu(true)}> {state.profile.imageSet && ( - + )} {!state.profile.imageSet && ( - + )} {state.profile.name && ( - {state.profile.name} + + {state.profile.name} + )} - {`${state.profile.handle}${state.profile.node ? '/' + state.profile.node : ''}`} + {`${state.profile.handle}${ + state.profile.node ? '/' + state.profile.node : '' + }`} @@ -50,10 +79,29 @@ export function Identity({ openSettings }) { visible={menu} onDismiss={() => setMenu(false)} anchorPosition="top" - anchor={ }> - {setMenu(false); openSettings()}} title={state.strings.settings} /> - {}} title={state.strings.contacts} /> - + anchor={ + + + + }> + { + setMenu(false); + openSettings(); + }} + title={state.strings.settings} + /> + {}} + title={state.strings.contacts} + /> + - + - { state.strings.loggingOut } - setLogout(false)} /> + {state.strings.loggingOut} + setLogout(false)} + /> - {state.strings.allDevices} - + + {state.strings.allDevices} + + - - + + - + - ) + ); } diff --git a/app/client/mobile/src/identity/useIdentity.hook.ts b/app/client/mobile/src/identity/useIdentity.hook.ts index 1eac2c18..3dde0472 100644 --- a/app/client/mobile/src/identity/useIdentity.hook.ts +++ b/app/client/mobile/src/identity/useIdentity.hook.ts @@ -1,11 +1,11 @@ -import { useEffect, useState, useContext, useRef } from 'react' -import { AppContext } from '../context/AppContext' -import { DisplayContext } from '../context/DisplayContext'; -import { ContextType } from '../context/ContextType' +import {useEffect, useState, useContext, useRef} from 'react'; +import {AppContext} from '../context/AppContext'; +import {DisplayContext} from '../context/DisplayContext'; +import {ContextType} from '../context/ContextType'; export function useIdentity() { - const display = useContext(DisplayContext) as ContextType - const app = useContext(AppContext) as ContextType + const display = useContext(DisplayContext) as ContextType; + const app = useContext(AppContext) as ContextType; const [state, setState] = useState({ all: false, @@ -14,41 +14,40 @@ export function useIdentity() { profileSet: false, imageUrl: null, strings: display.state.strings, - }) + }); // eslint-disable-next-line @typescript-eslint/no-explicit-any const updateState = (value: any) => { - setState((s) => ({ ...s, ...value })) - } + setState(s => ({...s, ...value})); + }; useEffect(() => { - const identity = app.state.session?.getIdentity() + const identity = app.state.session?.getIdentity(); if (!identity) { - console.log('session not set in identity hook') + console.log('session not set in identity hook'); } else { const setProfile = (profile: Profile) => { updateState({ profile, profileSet: true, - imageUrl: { uri: identity.getProfileImageUrl() }, - }) - - } - identity.addProfileListener(setProfile) + imageUrl: {uri: identity.getProfileImageUrl()}, + }); + }; + identity.addProfileListener(setProfile); return () => { - identity.removeProfileListener(setProfile) - } + identity.removeProfileListener(setProfile); + }; } - }, []) + }, []); const actions = { - setAll: (all) => { - updateState({ all }); + setAll: all => { + updateState({all}); }, logout: async () => { await app.actions.accountLogout(state.all); - } - } + }, + }; - return { state, actions } + return {state, actions}; } diff --git a/app/client/mobile/src/session/Session.tsx b/app/client/mobile/src/session/Session.tsx index 633a8292..f178ce80 100644 --- a/app/client/mobile/src/session/Session.tsx +++ b/app/client/mobile/src/session/Session.tsx @@ -1,7 +1,13 @@ import React, {useState, useContext} from 'react'; import {View, useColorScheme} from 'react-native'; import {styles} from './Session.styled'; -import {BottomNavigation, Surface, Menu, Button, Text} from 'react-native-paper'; +import { + BottomNavigation, + Surface, + Menu, + Button, + Text, +} from 'react-native-paper'; import {Settings} from '../settings/Settings'; import {Channels} from '../channels/Channels'; import {Contacts} from '../contacts/Contacts'; @@ -11,7 +17,11 @@ import {Details} from '../details/Details'; import {Identity} from '../identity/Identity'; import {useSession} from './useSession.hook'; -import {NavigationContainer, DefaultTheme, DarkTheme} from '@react-navigation/native'; +import { + NavigationContainer, + DefaultTheme, + DarkTheme, +} from '@react-navigation/native'; import {createDrawerNavigator} from '@react-navigation/drawer'; const ChannelsRoute = () => ; @@ -67,7 +77,8 @@ export function Session() { /> )} {state.layout === 'large' && ( - + )} @@ -157,7 +168,7 @@ function SettingsScreen({nav}) { id="SettingsDrawer" drawerContent={Settings} screenOptions={{ - drawerStyle: { width: '40%' }, + drawerStyle: {width: '40%'}, drawerPosition: 'right', drawerType: 'front', headerShown: false, @@ -178,8 +189,7 @@ function HomeScreen({nav}) { - - + CONVERSATION diff --git a/app/client/mobile/src/session/useSession.hook.ts b/app/client/mobile/src/session/useSession.hook.ts index ad8ecc8a..7d6dbdc3 100644 --- a/app/client/mobile/src/session/useSession.hook.ts +++ b/app/client/mobile/src/session/useSession.hook.ts @@ -1,34 +1,34 @@ -import { useEffect, useState, useContext, useRef } from 'react' -import { AppContext } from '../context/AppContext' -import { DisplayContext } from '../context/DisplayContext' -import { ContextType } from '../context/ContextType' +import {useEffect, useState, useContext, useRef} from 'react'; +import {AppContext} from '../context/AppContext'; +import {DisplayContext} from '../context/DisplayContext'; +import {ContextType} from '../context/ContextType'; -const DEBOUNCE_MS = 1000 +const DEBOUNCE_MS = 1000; export function useSession() { - const display = useContext(DisplayContext) as ContextType - const app = useContext(AppContext) as ContextType + const display = useContext(DisplayContext) as ContextType; + const app = useContext(AppContext) as ContextType; const [state, setState] = useState({ layout: null, strings: {}, - }) + }); // eslint-disable-next-line @typescript-eslint/no-explicit-any const updateState = (value: any) => { - setState((s) => ({ ...s, ...value })) - } + setState(s => ({...s, ...value})); + }; useEffect(() => { - const { layout, strings } = display.state; - updateState({ layout, strings }); + const {layout, strings} = display.state; + updateState({layout, strings}); }, [display.state.layout, display.state.strings]); const actions = { logout: async () => { await app.actions.accountLogout(); - } - } + }, + }; - return { state, actions } + return {state, actions}; } diff --git a/app/client/mobile/src/settings/Settings.styled.ts b/app/client/mobile/src/settings/Settings.styled.ts index a2ea1b45..0dbf2da7 100644 --- a/app/client/mobile/src/settings/Settings.styled.ts +++ b/app/client/mobile/src/settings/Settings.styled.ts @@ -1,5 +1,5 @@ import {StyleSheet} from 'react-native'; -import { Colors } from '../constants/Colors'; +import {Colors} from '../constants/Colors'; export const styles = StyleSheet.create({ modal: { @@ -260,10 +260,7 @@ export const styles = StyleSheet.create({ color: Colors.danger, }, controlSwitch: { - transform: [ - { scaleX: 0.7 }, - {scaleY: 0.7 }, - ] + transform: [{scaleX: 0.7}, {scaleY: 0.7}], }, input: { width: '100%', @@ -302,4 +299,4 @@ export const styles = StyleSheet.create({ fontSize: 16, color: Colors.danger, }, -}) +}); diff --git a/app/client/mobile/src/settings/Settings.tsx b/app/client/mobile/src/settings/Settings.tsx index ff40ac70..95c11f52 100644 --- a/app/client/mobile/src/settings/Settings.tsx +++ b/app/client/mobile/src/settings/Settings.tsx @@ -1,17 +1,34 @@ import React, {useState, useContext} from 'react'; -import {Surface, Button, Text, IconButton, Divider, Icon, TextInput, RadioButton, Switch} from 'react-native-paper'; -import {SafeAreaView, TouchableOpacity, Modal, View, Image, ScrollView} from 'react-native'; +import { + Surface, + Button, + Text, + IconButton, + Divider, + Icon, + TextInput, + RadioButton, + Switch, +} from 'react-native-paper'; +import { + SafeAreaView, + TouchableOpacity, + Modal, + View, + Image, + ScrollView, +} from 'react-native'; import {styles} from './Settings.styled'; import {useSettings} from './useSettings.hook'; import ImagePicker from 'react-native-image-crop-picker'; import {BlurView} from '@react-native-community/blur'; import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view'; -import { Colors } from '../constants/Colors'; +import {Colors} from '../constants/Colors'; import {InputCode} from '../utils/InputCode'; import Clipboard from '@react-native-clipboard/clipboard'; -export function Settings({ showLogout }: { showLogout: boolean }) { - const { state, actions } = useSettings(); +export function Settings({showLogout}: {showLogout: boolean}) { + const {state, actions} = useSettings(); const [alert, setAlert] = useState(false); const [details, setDetails] = useState(false); const [sealing, setSealing] = useState(false); @@ -41,38 +58,43 @@ export function Settings({ showLogout }: { showLogout: boolean }) { actions.setPassword(''); actions.setConfirm(''); setChange(true); - } + }; const saveChange = async () => { if (!savingChange) { - setSavingChange(true) + setSavingChange(true); try { - await actions.setLogin() + await actions.setLogin(); setChange(false); } catch (err) { - console.log(err) + console.log(err); setChange(false); setAlert(true); } - setSavingChange(false) - } - } + setSavingChange(false); + } + }; const selectImage = async () => { try { - const img = await ImagePicker.openPicker({ mediaType: 'photo', width: 256, height: 256, cropping: true, cropperCircleOverlay: true, includeBase64: true }); + const img = await ImagePicker.openPicker({ + mediaType: 'photo', + width: 256, + height: 256, + cropping: true, + cropperCircleOverlay: true, + includeBase64: true, + }); try { await actions.setProfileImage(img.data); - } - catch (err) { + } catch (err) { console.log(err); setAlert(true); } - } - catch (err) { + } catch (err) { console.log(err); } - } + }; const applyRemove = async () => { if (!applyingRemove) { @@ -80,15 +102,14 @@ export function Settings({ showLogout }: { showLogout: boolean }) { try { await actions.remove(); setRemove(false); - } - catch (err) { + } catch (err) { console.log(err); setRemove(false); setAlert(true); } setApplyingRemove(false); } - } + }; const applyLogout = async () => { if (!applyingLogout) { @@ -96,35 +117,34 @@ export function Settings({ showLogout }: { showLogout: boolean }) { try { await actions.logout(); setLogout(false); - } - catch (err) { + } catch (err) { console.log(err); setLogout(false); setAlert(true); } setApplyingLogout(false); } - } + }; const setMfa = async (flag: boolean) => { if (!savingAuth) { setSavingAuth(true); - try { + try { if (flag) { await actions.enableMFA(); setAuthMessage(''); actions.setCode(''); setAuth(true); - } else { + } else { setClear(true); - } + } } catch (err) { - console.log(err) + console.log(err); setAlert(true); } setSavingAuth(false); } - } + }; const clearAuth = async () => { if (!confirmingAuth) { @@ -132,14 +152,13 @@ export function Settings({ showLogout }: { showLogout: boolean }) { try { await actions.disableMFA(); setClear(false); - } - catch (err) { + } catch (err) { console.log(err); setAlert(true); } setConfirmingAuth(false); } - } + }; const confirmAuth = async () => { if (!confirmingAuth) { @@ -147,19 +166,18 @@ export function Settings({ showLogout }: { showLogout: boolean }) { try { await actions.confirmMFA(); setAuth(false); - } - catch(err) { + } catch (err) { if (err.message === '401') { setAuthMessage(state.strings.mfaError); } else if (err.message === '429') { setAuthMessage(state.strings.mfaDisabled); } else { - setAuthMessage(`${state.strings.error}: ${state.strings.tryAgain}`); + setAuthMessage(`${state.strings.error}: ${state.strings.tryAgain}`); } } setConfirmingAuth(false); } - } + }; const copySecret = async () => { if (!secretCopy) { @@ -169,7 +187,7 @@ export function Settings({ showLogout }: { showLogout: boolean }) { setSecretCopy(false); }, 2000); } - } + }; const setSeal = async () => { if (!savingSeal) { @@ -180,8 +198,8 @@ export function Settings({ showLogout }: { showLogout: boolean }) { actions.setSealConfirm(''); actions.setSealDelete(''); setSealing(true); - } - } + } + }; const sealUnlock = async () => { if (!savingSeal) { @@ -194,9 +212,9 @@ export function Settings({ showLogout }: { showLogout: boolean }) { setSealing(false); setAlert(true); } - setSavingSeal(false) + setSavingSeal(false); } - } + }; const sealForget = async () => { if (!savingSeal) { @@ -211,7 +229,7 @@ export function Settings({ showLogout }: { showLogout: boolean }) { } setSavingSeal(false); } - } + }; const sealRemove = async () => { if (!savingSeal) { @@ -226,7 +244,7 @@ export function Settings({ showLogout }: { showLogout: boolean }) { } setSavingSeal(false); } - } + }; const sealCreate = async () => { if (!savingSeal) { @@ -241,7 +259,7 @@ export function Settings({ showLogout }: { showLogout: boolean }) { } setSavingSeal(false); } - } + }; const sealUpdate = async () => { if (!savingSeal) { @@ -256,7 +274,7 @@ export function Settings({ showLogout }: { showLogout: boolean }) { } setSavingSeal(false); } - } + }; const saveDetails = async () => { if (!savingDetails) { @@ -264,15 +282,14 @@ export function Settings({ showLogout }: { showLogout: boolean }) { try { await actions.setDetails(); setDetails(false); - } - catch (err) { + } catch (err) { console.log(err); setDetails(false); setAlert(true); } setSavingDetails(false); } - } + }; const setRegistry = async (flag: boolean) => { if (!savingRegistry) { @@ -283,14 +300,13 @@ export function Settings({ showLogout }: { showLogout: boolean }) { } else { await actions.disableRegistry(); } - } - catch (err) { + } catch (err) { console.log(err); setAlert(true); } setSavingRegistry(false); } - } + }; const setNotifications = async (flag: boolean) => { if (!savingNotifications) { @@ -301,26 +317,38 @@ export function Settings({ showLogout }: { showLogout: boolean }) { } else { await actions.disableNotifications(); } - } - catch (err) { + } catch (err) { console.log(err); setAlert(true); } setSavingNotifications(false); } - } + }; return ( <> - {`${state.profile.handle}${state.profile.node ? '/' + state.profile.node : ''}`} + {`${state.profile.handle}${ + state.profile.node ? '/' + state.profile.node : '' + }`} {!state.profile.imageSet && ( - + )} {state.profile.imageSet && ( - + )} @@ -340,7 +368,12 @@ export function Settings({ showLogout }: { showLogout: boolean }) { {state.strings.name} )} {state.profile.name && ( - {state.profile.name} + + {state.profile.name} + )} @@ -358,15 +391,21 @@ export function Settings({ showLogout }: { showLogout: boolean }) { {!state.profile.description && ( - {state.strings.description} + + {state.strings.description} + )} {state.profile.description && ( {state.profile.description} )} - setDetails(true)}> + setDetails(true)}> - {state.strings.edit} + + {state.strings.edit} + @@ -380,10 +419,18 @@ export function Settings({ showLogout }: { showLogout: boolean }) { - setRegistry(!state.config.searchable)}> - {state.strings.visibleRegistry} + setRegistry(!state.config.searchable)}> + + {state.strings.visibleRegistry} + - + @@ -392,7 +439,9 @@ export function Settings({ showLogout }: { showLogout: boolean }) { - {state.strings.manageTopics} + + {state.strings.manageTopics} + @@ -401,10 +450,18 @@ export function Settings({ showLogout }: { showLogout: boolean }) { - setRegistry(!state.config.pushEnabled)}> - {state.strings.enableNotifications} + setRegistry(!state.config.pushEnabled)}> + + {state.strings.enableNotifications} + - + @@ -418,10 +475,18 @@ export function Settings({ showLogout }: { showLogout: boolean }) { - setRegistry(!state.config.searchable)}> - {state.strings.mfaTitle} + setRegistry(!state.config.searchable)}> + + {state.strings.mfaTitle} + - + @@ -430,18 +495,24 @@ export function Settings({ showLogout }: { showLogout: boolean }) { - {state.strings.changeLogin} + + {state.strings.changeLogin} + - { showLogout && ( + {showLogout && ( - setLogout(true)}> - {state.strings.logout} + setLogout(true)}> + + {state.strings.logout} + @@ -451,8 +522,12 @@ export function Settings({ showLogout }: { showLogout: boolean }) { - setRemove(true)}> - {state.strings.deleteAccount} + setRemove(true)}> + + {state.strings.deleteAccount} + @@ -468,7 +543,9 @@ export function Settings({ showLogout }: { showLogout: boolean }) { manageSeal}> - {state.strings.blockedContacts} + + {state.strings.blockedContacts} + @@ -478,22 +555,26 @@ export function Settings({ showLogout }: { showLogout: boolean }) { manageSeal}> - {state.strings.blockedTopics} + + {state.strings.blockedTopics} + - + manageSeal}> - {state.strings.blockedMessages} + + {state.strings.blockedMessages} + - + @@ -505,8 +586,24 @@ export function Settings({ showLogout }: { showLogout: boolean }) { {state.strings.timeFormat}: - {actions.setFullDayTime(false)}} /> - {actions.setFullDayTime(true)}} /> + { + actions.setFullDayTime(false); + }} + /> + { + actions.setFullDayTime(true); + }} + /> @@ -517,8 +614,24 @@ export function Settings({ showLogout }: { showLogout: boolean }) { {state.strings.dateFormat}: - {actions.setMonthFirstDate(true)}} /> - {actions.setMonthFirstDate(false)}} /> + { + actions.setMonthFirstDate(true); + }} + /> + { + actions.setMonthFirstDate(false); + }} + /> @@ -565,134 +678,243 @@ export function Settings({ showLogout }: { showLogout: boolean }) { blurAmount={2} reducedTransparencyFallbackColor="dark" /> - + - { state.strings.manageTopics } - setSealing(false)} /> - { !sealDelete && !sealReset && state.config.sealSet && state.config.sealUnlocked && ( - <> - { state.strings.sealUnlocked } - { !sealConfig && ( + + {state.strings.manageTopics} + + setSealing(false)} + /> + {!sealDelete && + !sealReset && + state.config.sealSet && + state.config.sealUnlocked && ( + <> + + {state.strings.sealUnlocked} + + {!sealConfig && ( + + { + setSealConfig(true); + }} + /> + + + + )} + {sealConfig && ( + + + + { + setSealConfig(false); + }} + /> + + )} + + )} + {!sealDelete && + sealReset && + state.config.sealSet && + state.config.sealUnlocked && ( + <> + + {state.strings.changePassword} + + } + right={ + showPassword ? ( + setShowPassword(false)} + /> + ) : ( + setShowPassword(true)} + /> + ) + } + onChangeText={value => actions.setSealPassword(value)} + /> + } + right={ + showPassword ? ( + setShowConfirm(false)} + /> + ) : ( + setShowConfirm(true)} + /> + ) + } + onChangeText={value => actions.setSealConfirm(value)} + /> - {setSealConfig(true)}} /> - - + + - )} - { sealConfig && ( - - - - {setSealConfig(false)}} /> - - )} - - )} - { !sealDelete && sealReset && state.config.sealSet && state.config.sealUnlocked && ( + + )} + {!sealDelete && + state.config.sealSet && + !state.config.sealUnlocked && ( + <> + + {state.strings.sealLocked} + + } + right={ + showPassword ? ( + setShowPassword(false)} + /> + ) : ( + setShowPassword(true)} + /> + ) + } + onChangeText={value => actions.setSealPassword(value)} + /> + {!sealConfig && ( + + { + setSealConfig(true); + }} + /> + + + + )} + {sealConfig && ( + + + { + setSealConfig(false); + }} + /> + + )} + + )} + {sealDelete && state.config.sealSet && ( <> - { state.strings.changePassword } - } - right={ - showPassword ? ( - setShowPassword(false)} - /> - ) : ( - setShowPassword(true)} - /> - ) - } - onChangeText={value => actions.setSealPassword(value)} - /> - } - right={ - showPassword ? ( - setShowConfirm(false)} - /> - ) : ( - setShowConfirm(true)} - /> - ) - } - onChangeText={value => actions.setSealConfirm(value)} - /> - - - - - - )} - { !sealDelete && state.config.sealSet && !state.config.sealUnlocked && ( - <> - { state.strings.sealLocked } - } - right={ - showPassword ? ( - setShowPassword(false)} - /> - ) : ( - setShowPassword(true)} - /> - ) - } - onChangeText={value => actions.setSealPassword(value)} - /> - { !sealConfig && ( - - {setSealConfig(true)}} /> - - - - )} - { sealConfig && ( - - - {setSealConfig(false)}} /> - - )} - - )} - { sealDelete && state.config.sealSet && ( - <> - { state.strings.sealDelete } + + {state.strings.sealDelete} + actions.setSealDelete(value)} /> - + )} - { !state.config.sealSet && ( + {!state.config.sealSet && ( <> - { state.strings.sealUnset } - { state.strings.delayMessage } + + {state.strings.sealUnset} + + + {state.strings.delayMessage} + } right={ showPassword ? ( - setShowPassword(false)} /> ) : ( - setShowPassword(true)} /> @@ -739,15 +974,23 @@ export function Settings({ showLogout }: { showLogout: boolean }) { onChangeText={value => actions.setSealPassword(value)} /> - - + + )} - + - + - { state.strings.editDetails } - setDetails(false)} /> + {state.strings.editDetails} + setDetails(false)} + /> } + left={ + + } onChangeText={value => actions.setName(value)} /> } + left={ + + } onChangeText={value => actions.setLocation(value)} /> } + left={ + + } onChangeText={value => actions.setDescription(value)} /> - - + + - + @@ -820,31 +1089,62 @@ export function Settings({ showLogout }: { showLogout: boolean }) { blurAmount={2} reducedTransparencyFallbackColor="dark" /> - + - { state.strings.mfaTitle } - setAuth(false)} /> - { state.strings.mfaSteps } - + {state.strings.mfaTitle} + setAuth(false)} + /> + + {state.strings.mfaSteps} + + - { state.secretText } + + {state.secretText} + - + - { authMessage } + {authMessage} - - + + - @@ -862,15 +1162,31 @@ export function Settings({ showLogout }: { showLogout: boolean }) { blurAmount={2} reducedTransparencyFallbackColor="dark" /> - + - { state.strings.mfaTitle } - setClear(false)} /> - { state.strings.disablePrompt } - + {state.strings.mfaTitle} + setClear(false)} + /> + + {state.strings.disablePrompt} + + - - + + @@ -889,10 +1205,17 @@ export function Settings({ showLogout }: { showLogout: boolean }) { blurAmount={2} reducedTransparencyFallbackColor="dark" /> - + - { state.strings.changeLogin } - setChange(false)} /> + {state.strings.changeLogin} + setChange(false)} + /> } + left={ + + } right={ !state.checked ? ( - + ) : state.taken ? ( - ) : ( <> ) } - onChangeText={value => actions.setHandle(value)} /> } right={ showPassword ? ( - setShowPassword(false)} /> ) : ( - setShowPassword(true)} /> @@ -955,12 +1281,14 @@ export function Settings({ showLogout }: { showLogout: boolean }) { left={} right={ showPassword ? ( - setShowConfirm(false)} /> ) : ( - setShowConfirm(true)} /> @@ -970,8 +1298,21 @@ export function Settings({ showLogout }: { showLogout: boolean }) { /> - - + + @@ -990,19 +1331,39 @@ export function Settings({ showLogout }: { showLogout: boolean }) { blurAmount={2} reducedTransparencyFallbackColor="dark" /> - + - { state.strings.loggingOut } - setLogout(false)} /> + {state.strings.loggingOut} + setLogout(false)} + /> - {state.strings.allDevices} - + + {state.strings.allDevices} + + - - + + @@ -1021,10 +1382,19 @@ export function Settings({ showLogout }: { showLogout: boolean }) { blurAmount={2} reducedTransparencyFallbackColor="dark" /> - + - { state.strings.deleteAccount } - setRemove(false)} /> + + {state.strings.deleteAccount} + + setRemove(false)} + /> } + left={ + + } onChangeText={value => actions.setRemove(value)} /> - - + + - ); } diff --git a/app/client/mobile/src/settings/useSettings.hook.ts b/app/client/mobile/src/settings/useSettings.hook.ts index c0307745..1eaf55ad 100644 --- a/app/client/mobile/src/settings/useSettings.hook.ts +++ b/app/client/mobile/src/settings/useSettings.hook.ts @@ -1,14 +1,14 @@ -import { useEffect, useState, useContext, useRef } from 'react' -import { AppContext } from '../context/AppContext' -import { DisplayContext } from '../context/DisplayContext' -import { ContextType } from '../context/ContextType' +import {useEffect, useState, useContext, useRef} from 'react'; +import {AppContext} from '../context/AppContext'; +import {DisplayContext} from '../context/DisplayContext'; +import {ContextType} from '../context/ContextType'; -const DEBOUNCE_MS = 1000 +const DEBOUNCE_MS = 1000; export function useSettings() { - const display = useContext(DisplayContext) as ContextType - const app = useContext(AppContext) as ContextType - const debounce = useRef(setTimeout(() => {}, 0)) + const display = useContext(DisplayContext) as ContextType; + const app = useContext(AppContext) as ContextType; + const debounce = useRef(setTimeout(() => {}, 0)); const [state, setState] = useState({ config: {} as Config, @@ -36,32 +36,32 @@ export function useSettings() { secretCopied: false, monthFirstDate: true, fullDayTime: false, - }) + }); // eslint-disable-next-line @typescript-eslint/no-explicit-any const updateState = (value: any) => { - setState((s) => ({ ...s, ...value })) - } + setState(s => ({...s, ...value})); + }; const getSession = () => { - const session = app.state?.session - const settings = session?.getSettings() - const identity = session?.getIdentity() + const session = app.state?.session; + const settings = session?.getSettings(); + const identity = session?.getIdentity(); if (!settings || !identity) { - console.log('session not set in settings hook') + console.log('session not set in settings hook'); } - return { settings, identity } - } + return {settings, identity}; + }; useEffect(() => { - const { settings, identity } = getSession() + const {settings, identity} = getSession(); const setConfig = (config: Config) => { - updateState({ config }) - } - settings.addConfigListener(setConfig) + updateState({config}); + }; + settings.addConfigListener(setConfig); const setProfile = (profile: Profile) => { - const { handle, name, location, description } = profile - const url = identity.getProfileImageUrl() + const {handle, name, location, description} = profile; + const url = identity.getProfileImageUrl(); updateState({ profile, handle, @@ -70,194 +70,188 @@ export function useSettings() { description, imageUrl: url, profileSet: true, - }) - } - identity.addProfileListener(setProfile) + }); + }; + identity.addProfileListener(setProfile); return () => { - settings.removeConfigListener(setConfig) - identity.removeProfileListener(setProfile) - } - }, []) + settings.removeConfigListener(setConfig); + identity.removeProfileListener(setProfile); + }; + }, []); useEffect(() => { - const { fullDayTime, monthFirstDate } = app.state; - updateState({ fullDayTime, monthFirstDate }); + const {fullDayTime, monthFirstDate} = app.state; + updateState({fullDayTime, monthFirstDate}); }, [app.state.fullDayTime, app.state.monthFirstDate]); useEffect(() => { - const { - strings, - dateFormat, - timeFormat, - } = display.state + const {strings, dateFormat, timeFormat} = display.state; updateState({ strings, dateFormat, timeFormat, - }) - }, [display.state]) + }); + }, [display.state]); const actions = { getUsernameStatus: async (username: string) => { - const { settings } = getSession() - return await settings.getUsernameStatus(username) + const {settings} = getSession(); + return await settings.getUsernameStatus(username); }, setLogin: async () => { - const { settings } = getSession() - await settings.setLogin(state.handle, state.password) + const {settings} = getSession(); + await settings.setLogin(state.handle, state.password); }, enableNotifications: async () => { - const { settings } = getSession() - await settings.enableNotifications() + const {settings} = getSession(); + await settings.enableNotifications(); }, disableNotifications: async () => { - const { settings } = getSession() - await settings.disableNotifications() + const {settings} = getSession(); + await settings.disableNotifications(); }, enableRegistry: async () => { - const { settings } = getSession() - await settings.enableRegistry() + const {settings} = getSession(); + await settings.enableRegistry(); }, disableRegistry: async () => { - const { settings } = getSession() - await settings.disableRegistry() + const {settings} = getSession(); + await settings.disableRegistry(); }, enableMFA: async () => { - const { settings } = getSession() - const { secretImage, secretText } = await settings.enableMFA() - updateState({ secretImage, secretText }); + const {settings} = getSession(); + const {secretImage, secretText} = await settings.enableMFA(); + updateState({secretImage, secretText}); }, disableMFA: async () => { - const { settings } = getSession() - await settings.disableMFA() + const {settings} = getSession(); + await settings.disableMFA(); }, confirmMFA: async () => { - const { settings } = getSession() - await settings.confirmMFA(state.code) + const {settings} = getSession(); + await settings.confirmMFA(state.code); }, setCode: (code: string) => { - updateState({ code }); + updateState({code}); }, copySecret: () => { navigator.clipboard.writeText(state.secretText); - updateState({ secretCopied: true }); + updateState({secretCopied: true}); setTimeout(() => { - updateState({ secretCopied: false }); + updateState({secretCopied: false}); }, 1000); }, setSeal: async () => { - const { settings } = getSession() - await settings.setSeal(state.sealPassword) + const {settings} = getSession(); + await settings.setSeal(state.sealPassword); }, clearSeal: async () => { - const { settings } = getSession() - await settings.clearSeal() + const {settings} = getSession(); + await settings.clearSeal(); }, unlockSeal: async () => { - const { settings } = getSession() - await settings.unlockSeal(state.sealPassword) + const {settings} = getSession(); + await settings.unlockSeal(state.sealPassword); }, forgetSeal: async () => { - const { settings } = getSession() - await settings.forgetSeal() + const {settings} = getSession(); + await settings.forgetSeal(); }, updateSeal: async () => { - const { settings } = getSession(); + const {settings} = getSession(); await settings.updateSeal(state.sealPassword); }, setProfileData: async ( name: string, location: string, - description: string + description: string, ) => { - const { identity } = getSession() - await identity.setProfileData(name, location, description) + const {identity} = getSession(); + await identity.setProfileData(name, location, description); }, setProfileImage: async (image: string) => { - const { identity } = getSession() - await identity.setProfileImage(image) + const {identity} = getSession(); + await identity.setProfileImage(image); }, getProfileImageUrl: () => { - const { identity } = getSession() - return identity.getProfileImageUrl() + const {identity} = getSession(); + return identity.getProfileImageUrl(); }, setDateFormat: (format: string) => { - display.actions.setDateFormat(format) + display.actions.setDateFormat(format); }, setTimeFormat: (format: string) => { - display.actions.setTimeFormat(format) + display.actions.setTimeFormat(format); }, setAll: (all: boolean) => { - updateState({ all }) + updateState({all}); }, logout: async () => { - await app.actions.accountLogout(state.all) + await app.actions.accountLogout(state.all); }, remove: async () => { - await app.actions.accountRemove() + await app.actions.accountRemove(); }, setHandle: (handle: string) => { - updateState({ handle, taken: false, checked: false }) - clearTimeout(debounce.current) + updateState({handle, taken: false, checked: false}); + clearTimeout(debounce.current); if (!handle || handle === state.profile.handle) { - updateState({ available: true, checked: true }) + updateState({available: true, checked: true}); } else { debounce.current = setTimeout(async () => { - const { settings } = getSession() + const {settings} = getSession(); try { - const available = await settings.getUsernameStatus(handle) - updateState({ taken: !available, checked: true }) - } - catch (err) { + const available = await settings.getUsernameStatus(handle); + updateState({taken: !available, checked: true}); + } catch (err) { console.log(err); } - }, DEBOUNCE_MS) + }, DEBOUNCE_MS); } }, setPassword: (password: string) => { - updateState({ password }) + updateState({password}); }, setConfirm: (confirm: string) => { - updateState({ confirm }) + updateState({confirm}); }, setRemove: (remove: string) => { - updateState({ remove }); + updateState({remove}); }, setName: (name: string) => { - updateState({ name }) + updateState({name}); }, setLocation: (location: string) => { - updateState({ location }) + updateState({location}); }, setDescription: (description: string) => { - updateState({ description }) + updateState({description}); }, setDetails: async () => { - const { identity } = getSession() - const { name, location, description } = state - await identity.setProfileData(name, location, description) + const {identity} = getSession(); + const {name, location, description} = state; + await identity.setProfileData(name, location, description); }, setSealDelete: (sealDelete: string) => { - updateState({ sealDelete }); + updateState({sealDelete}); }, setSealPassword: (sealPassword: string) => { - updateState({ sealPassword }); + updateState({sealPassword}); }, setSealConfirm: (sealConfirm: string) => { - updateState({ sealConfirm }); + updateState({sealConfirm}); }, setFullDayTime: async (flag: boolean) => { try { await app.actions.setFullDayTime(flag); - } - catch (err) { + } catch (err) { console.log(err); } }, setMonthFirstDate: async (flag: boolean) => { await app.actions.setMonthFirstDate(flag); }, - } + }; - return { state, actions } + return {state, actions}; } diff --git a/app/client/mobile/src/utils/InputCode.tsx b/app/client/mobile/src/utils/InputCode.tsx index d1d6f78d..3a69532c 100644 --- a/app/client/mobile/src/utils/InputCode.tsx +++ b/app/client/mobile/src/utils/InputCode.tsx @@ -41,7 +41,8 @@ export function InputCode({onChangeText, style}) { {code.charAt(5)} -