mirror of
https://github.com/balzack/databag.git
synced 2025-02-11 19:19:16 +00:00
adding change login modal to new settings screen
This commit is contained in:
parent
894ac14a10
commit
e87a5b86fb
@ -21,6 +21,8 @@ const LightColors = {
|
||||
headerBar: '#eeeeee',
|
||||
primaryButton: '#448866',
|
||||
primaryButtonText: '#ffffff',
|
||||
cancelButton: '#888888',
|
||||
cancelButtonText: '#aaaaaa',
|
||||
disabledButton: '#dddddd',
|
||||
disabledButtonText: '#aaaaaa',
|
||||
dangerButton: '#ff5555',
|
||||
@ -65,6 +67,8 @@ const DarkColors = {
|
||||
headerBar: '#555555',
|
||||
primaryButton: '#448866',
|
||||
primaryButtonText: '#ffffff',
|
||||
cancelButton: '#888888',
|
||||
cancelButtonText: '#eeeeee',
|
||||
disabledButton: '#888888',
|
||||
disabledButtonText: '#eeeeee',
|
||||
dangerButton: '#ff5555',
|
||||
@ -113,6 +117,8 @@ export const Colors = {
|
||||
headerBar: getColor('headerBar'),
|
||||
primaryButton: getColor('primaryButton'),
|
||||
primaryButtonText: getColor('primaryButtonText'),
|
||||
cancelButton: getColor('cancelButton'),
|
||||
cancelButtonText: getColor('cancelButtonText'),
|
||||
disabledButton: getColor('disabledButton'),
|
||||
disabledButtonText: getColor('disabledButtonText'),
|
||||
dangerButton: getColor('dangerButton'),
|
||||
|
@ -2,6 +2,7 @@ import { NativeModules, Platform } from 'react-native'
|
||||
|
||||
const Strings = [
|
||||
{
|
||||
// settings screen
|
||||
visibleRegistry: 'Visible in Registry',
|
||||
edit: 'Edit',
|
||||
enableNotifications: 'Push Notifications',
|
||||
@ -26,6 +27,7 @@ const Strings = [
|
||||
monthStart: 'mm/dd',
|
||||
monthEnd: 'dd/mm',
|
||||
|
||||
// seal wizard
|
||||
sealUnset: 'Generate a key to enable end-to-end encrypted topics.',
|
||||
sealUnlocked: 'Disabling the sealing key will block access to all end-to-end encrypted topics from this device until the key is unlocked again.',
|
||||
sealLocked: 'Unlock the sealing key to support end-to-end encrypted topics on this device.',
|
||||
@ -47,6 +49,13 @@ const Strings = [
|
||||
update: 'Update',
|
||||
changeKey: 'Change Key Password',
|
||||
delayMessage: 'Key generation can take several minutes.',
|
||||
|
||||
// settings modals
|
||||
cancel: 'Cancel',
|
||||
confirmLogout: 'Logout',
|
||||
loggingOut: 'Logging Out',
|
||||
username: 'Username',
|
||||
save: 'Save',
|
||||
},
|
||||
{
|
||||
visibleRegistry: 'Visible dans le Registre',
|
||||
@ -57,8 +66,8 @@ const Strings = [
|
||||
hourMode: 'Heure',
|
||||
dateMode: 'Date',
|
||||
language: 'Langue',
|
||||
logout: 'Se Déconnecter',
|
||||
changeLogin: 'Changer le Mot de Passe',
|
||||
logout: 'Déconnecter',
|
||||
changeLogin: 'Modifier l\'Accès',
|
||||
deleteAccount: 'Supprimer le Compte',
|
||||
contacts: 'Contacts',
|
||||
topics: 'Sujets',
|
||||
@ -94,6 +103,12 @@ const Strings = [
|
||||
update: 'Mise à jour',
|
||||
changeKey: 'Changer le mot de passe clé',
|
||||
delayMessage: 'La génération de clé peut prendre plusieurs minutes.',
|
||||
|
||||
cancel: 'Annuler',
|
||||
confirmLogout: 'Déconnecter',
|
||||
loggingOut: 'Confirmation de la Déconnexion',
|
||||
username: 'Nom d\'Utilisateur',
|
||||
save: 'Engegistrer',
|
||||
},
|
||||
{
|
||||
visibleRegistry: 'Visible en el Registro',
|
||||
@ -141,6 +156,12 @@ const Strings = [
|
||||
update: 'Actualizar',
|
||||
changeKey: 'Cambiar clave Contraseña',
|
||||
delayMessage: 'La generación de claves puede tardar varios minutos.',
|
||||
|
||||
cancel: 'Cancelar',
|
||||
confirmLogout: 'Cerrar',
|
||||
loggingOut: 'Confirmando cierre de sesión',
|
||||
username: 'Nombre de Usuario',
|
||||
save: 'Guardar',
|
||||
},
|
||||
{
|
||||
visibleRegistry: 'Sichtbar in der Registrierung',
|
||||
@ -188,6 +209,12 @@ const Strings = [
|
||||
update: 'Aktualisieren',
|
||||
changeKey: 'Schlüsselpasswort ändern',
|
||||
delayMessage: 'Die Schlüsselgenerierung kann mehrere Minuten dauern.',
|
||||
|
||||
cancel: 'Stornieren',
|
||||
confirmlogout: 'Ausloggen',
|
||||
loggingOut: 'Abmelden bestätigen',
|
||||
username: 'Nutzername',
|
||||
save: 'Speichern',
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -42,6 +42,41 @@ export function Settings() {
|
||||
}
|
||||
}
|
||||
|
||||
const logout = async () => {
|
||||
if (!busy) {
|
||||
try {
|
||||
setBusy(true);
|
||||
await actions.logout();
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
Alert.alert(
|
||||
'Failed to Logout',
|
||||
'Please try again.',
|
||||
);
|
||||
}
|
||||
setBusy(false);
|
||||
}
|
||||
}
|
||||
|
||||
const changeLogin = async () => {
|
||||
if (!busy) {
|
||||
try {
|
||||
setBusy(true);
|
||||
await actions.changeLogin();
|
||||
actions.hideLogin();
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
Alert.alert(
|
||||
'Failed to Change Login',
|
||||
'Please try again.',
|
||||
);
|
||||
}
|
||||
setBusy(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ScrollView style={styles.content}>
|
||||
<SafeAreaView edges={['top']}>
|
||||
@ -134,7 +169,7 @@ export function Settings() {
|
||||
|
||||
<Text style={styles.label}>{ state.strings.account }</Text>
|
||||
<View style={styles.group}>
|
||||
<TouchableOpacity style={styles.entry} activeOpacity={1}>
|
||||
<TouchableOpacity style={styles.entry} activeOpacity={1} onPress={actions.showLogout}>
|
||||
<View style={styles.icon}>
|
||||
<MatIcons name="logout" size={20} color={Colors.linkText} />
|
||||
</View>
|
||||
@ -144,7 +179,7 @@ export function Settings() {
|
||||
<View style={styles.control} />
|
||||
</TouchableOpacity>
|
||||
<View style={styles.divider} />
|
||||
<TouchableOpacity style={styles.entry} activeOpacity={1}>
|
||||
<TouchableOpacity style={styles.entry} activeOpacity={1} onPress={actions.showLogin}>
|
||||
<View style={styles.icon}>
|
||||
<MatIcons name="login" size={20} color={Colors.linkText} />
|
||||
</View>
|
||||
@ -401,6 +436,113 @@ export function Settings() {
|
||||
</KeyboardAvoidingView>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
animationType="fade"
|
||||
transparent={true}
|
||||
visible={state.logout}
|
||||
supportedOrientations={['portrait', 'landscape']}
|
||||
onRequestClose={actions.hideLogout}
|
||||
>
|
||||
<View style={styles.modalOverlay}>
|
||||
<View style={styles.modalContainer}>
|
||||
<Text style={styles.modalHeader}>{ state.strings.loggingOut }</Text>
|
||||
<View style={styles.buttons}>
|
||||
<TouchableOpacity style={styles.cancelButton} activeOpacity={1} onPress={actions.hideLogout}>
|
||||
<Text style={styles.enabledButtonText}>{ state.strings.cancel }</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.promptButton} activeOpacity={1} onPress={logout}>
|
||||
<Text style={styles.enabledButtonText}>{ state.strings.confirmLogout }</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
animationType="fade"
|
||||
transparent={true}
|
||||
visible={state.login}
|
||||
supportedOrientations={['portrait', 'landscape']}
|
||||
onRequestClose={actions.hideLogin}
|
||||
>
|
||||
<View style={styles.modalOverlay}>
|
||||
<View style={styles.modalContainer}>
|
||||
<View style={styles.modalClose}>
|
||||
<TouchableOpacity style={styles.closeButton} activeOpacity={1} onPress={actions.hideLogin}>
|
||||
<MatIcons name="close" size={20} color={Colors.descriptionText} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<Text style={styles.modalHeader}>{ state.strings.changeLogin }</Text>
|
||||
<ActivityIndicator style={styles.modalBusy} animating={busy} color={Colors.primary} />
|
||||
|
||||
<View style={styles.modalInput}>
|
||||
<TextInput style={styles.inputText} value={state.username} onChangeText={actions.setUsername}
|
||||
autoCapitalize={'none'} placeholder={state.strings.username}
|
||||
placeholderTextColor={Colors.inputPlaceholder} />
|
||||
{ !state.validated && (
|
||||
<View style={styles.inputVisibility}>
|
||||
<MatIcons name="refresh" size={16} color={Colors.inputPlaceholder} />
|
||||
</View>
|
||||
)}
|
||||
{ state.validated && state.available && (
|
||||
<View style={styles.inputVisibility} activeOpacity={1} onPress={actions.hidePassword}>
|
||||
<MatIcons name="check" size={16} color={Colors.activeFill} />
|
||||
</View>
|
||||
)}
|
||||
{ state.validated && !state.available && (
|
||||
<View style={styles.inputVisibility} activeOpacity={1} onPress={actions.hidePassword}>
|
||||
<MatIcons name="block-helper" size={15} color={Colors.dangerText} />
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<View style={styles.modalInput}>
|
||||
<TextInput style={styles.inputText} value={state.password} onChangeText={actions.setPassword}
|
||||
autoCapitalize={'none'} secureTextEntry={state.hidePassword} placeholder={state.strings.password}
|
||||
placeholderTextColor={Colors.inputPlaceholder} />
|
||||
{ state.hidePassword && (
|
||||
<TouchableOpacity style={styles.inputVisibility} activeOpacity={1} onPress={actions.showPassword}>
|
||||
<MatIcons name="eye-outline" size={16} color={Colors.inputPlaceholder} />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
{ !state.hidePassword && (
|
||||
<TouchableOpacity style={styles.inputVisibility} activeOpacity={1} onPress={actions.hidePassword}>
|
||||
<MatIcons name="eye-off-outline" size={16} color={Colors.inputPlaceholder} />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
<View style={styles.modalInput}>
|
||||
<TextInput style={styles.inputText} value={state.confirm} onChangeText={actions.setConfirm}
|
||||
autoCapitalize={'none'} secureTextEntry={state.hideConfirm} placeholder={state.strings.confirmPassword}
|
||||
placeholderTextColor={Colors.inputPlaceholder} />
|
||||
{ state.hideConfirm && (
|
||||
<TouchableOpacity style={styles.inputVisibility} activeOpacity={1} onPress={actions.showConfirm}>
|
||||
<MatIcons name="eye-outline" size={16} color={Colors.inputPlaceholder} />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
{ !state.hideConfirm && (
|
||||
<TouchableOpacity style={styles.inputVisibility} activeOpacity={1} onPress={actions.showConfirm}>
|
||||
<MatIcons name="eye-off-outline" size={16} color={Colors.inputPlaceholder} />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<View style={styles.buttons}>
|
||||
{ (state.password !== state.confirm || !state.password || !state.validated || !state.username) && (
|
||||
<View style={styles.disabledButton}>
|
||||
<Text style={styles.disabledButtonText}>{ state.strings.update }</Text>
|
||||
</View>
|
||||
)}
|
||||
{ state.password === state.confirm && state.password && state.validated && state.username && (
|
||||
<TouchableOpacity style={styles.promptButton} activeOpacity={1} onPress={changeLogin}>
|
||||
<Text style={styles.enabledButtonText}>{ state.strings.update }</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
|
||||
</SafeAreaView>
|
||||
</ScrollView>
|
||||
);
|
||||
|
@ -203,8 +203,8 @@ export const styles = StyleSheet.create({
|
||||
fontFamily: 'Roboto',
|
||||
},
|
||||
disabledButton: {
|
||||
marginTop: 32,
|
||||
marginBottom: 16,
|
||||
marginTop: 8,
|
||||
marginBottom: 8,
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
paddingLeft: 32,
|
||||
@ -230,5 +230,28 @@ export const styles = StyleSheet.create({
|
||||
color: Colors.dangerButtonText,
|
||||
fontFamily: 'Roboto',
|
||||
},
|
||||
cancelButton: {
|
||||
margin: 8,
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
paddingLeft: 32,
|
||||
paddingRight: 32,
|
||||
borderRadius: 4,
|
||||
backgroundColor: Colors.cancelButton,
|
||||
},
|
||||
promptButton: {
|
||||
margin: 8,
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
paddingLeft: 32,
|
||||
paddingRight: 32,
|
||||
borderRadius: 4,
|
||||
backgroundColor: Colors.primaryButton,
|
||||
},
|
||||
buttons: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
padding: 8,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -2,12 +2,17 @@ import { useState, useEffect, useRef, useContext } from 'react';
|
||||
import { getLanguageStrings } from 'constants/Strings';
|
||||
import { ProfileContext } from 'context/ProfileContext';
|
||||
import { AccountContext } from 'context/AccountContext';
|
||||
import { AppContext } from 'context/AppContext';
|
||||
import { generateSeal, updateSeal, unlockSeal } from 'context/sealUtil';
|
||||
|
||||
export function useSettings() {
|
||||
|
||||
const profile = useContext(ProfileContext);
|
||||
const account = useContext(AccountContext);
|
||||
const app = useContext(AppContext);
|
||||
|
||||
const debounce = useRef(null);
|
||||
const checking = useRef(null);
|
||||
|
||||
const [state, setState] = useState({
|
||||
strings: getLanguageStrings(),
|
||||
@ -15,6 +20,14 @@ export function useSettings() {
|
||||
monthLast: false,
|
||||
pushEnabled: null,
|
||||
|
||||
login: false,
|
||||
username: null,
|
||||
validated: false,
|
||||
available: true,
|
||||
password: null,
|
||||
confirm: null,
|
||||
|
||||
logout: false,
|
||||
editSeal: false,
|
||||
sealEnabled: false,
|
||||
sealUnlocked: false,
|
||||
@ -33,8 +46,9 @@ export function useSettings() {
|
||||
|
||||
useEffect(() => {
|
||||
const { timeFull, monthLast } = profile.state;
|
||||
updateState({ timeFull, monthLast });
|
||||
}, [profile.state.timeFull, profile.state.monthLast]);
|
||||
const handle = profile.state.identity.handle;
|
||||
updateState({ timeFull, monthLast, handle });
|
||||
}, [profile.state]);
|
||||
|
||||
useEffect(() => {
|
||||
const { seal, sealable, pushEnabled } = account.state.status;
|
||||
@ -42,7 +56,6 @@ export function useSettings() {
|
||||
const sealEnabled = seal?.publicKey != null;
|
||||
const sealUnlocked = seal?.publicKey === sealKey?.public && sealKey?.private && sealKey?.public;
|
||||
updateState({ sealable, seal, sealKey, sealEnabled, sealUnlocked, pushEnabled });
|
||||
|
||||
}, [account.state]);
|
||||
|
||||
const unlockKey = async () => {
|
||||
@ -80,6 +93,42 @@ export function useSettings() {
|
||||
setNotifications: async (flag) => {
|
||||
await account.actions.setNotifications(flag);
|
||||
},
|
||||
showLogin: () => {
|
||||
updateState({ login: true, username: state.handle, password: null, confirm: null, validated: true });
|
||||
},
|
||||
hideLogin: () => {
|
||||
updateState({ login: false });
|
||||
},
|
||||
changeLogin: async () => {
|
||||
await account.actions.setLogin(state.username, state.password);
|
||||
},
|
||||
setUsername: (username) => {
|
||||
clearTimeout(debounce.current);
|
||||
checking.current = username;
|
||||
updateState({ username, validated: false });
|
||||
debounce.current = setTimeout(async () => {
|
||||
const cur = JSON.parse(JSON.stringify(username));
|
||||
const available = await profile.actions.getHandleStatus(cur);
|
||||
if (checking.current === cur) {
|
||||
updateState({ available, validated: true });
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
setPassword: (password) => {
|
||||
updateState({ password });
|
||||
},
|
||||
setConfirm: (confirm) => {
|
||||
updateState({ confirm });
|
||||
},
|
||||
logout: async () => {
|
||||
await app.actions.logout();
|
||||
},
|
||||
showLogout: () => {
|
||||
updateState({ logout: true });
|
||||
},
|
||||
hideLogout: () => {
|
||||
updateState({ logout: false });
|
||||
},
|
||||
showEditSeal: () => {
|
||||
updateState({ editSeal: true, sealPassword: null, sealConfirm: null, hidePassword: true, hideConfirm: true,
|
||||
sealDelete: null, sealRemove: false, sealUpdate: false });
|
||||
|
Loading…
Reference in New Issue
Block a user