adding sticky headers where missing

This commit is contained in:
balzack 2024-11-09 10:22:53 -08:00
parent b8abef126a
commit 136fbf4b5f
12 changed files with 799 additions and 733 deletions

View File

@ -66,7 +66,7 @@ export function Access() {
autoCapitalize="none" autoCapitalize="none"
autoComplete="off" autoComplete="off"
autoCorrect={false} autoCorrect={false}
label={state.strings.node} label={state.strings.server}
value={state.node} value={state.node}
left={<TextInput.Icon style={styles.icon} icon="server" />} left={<TextInput.Icon style={styles.icon} icon="server" />}
onChangeText={value => actions.setNode(value)} onChangeText={value => actions.setNode(value)}
@ -131,7 +131,7 @@ export function Access() {
autoCapitalize="none" autoCapitalize="none"
autoComplete="off" autoComplete="off"
autoCorrect={false} autoCorrect={false}
label={state.strings.node} label={state.strings.server}
value={state.node} value={state.node}
left={<TextInput.Icon style={styles.icon} icon="server" />} left={<TextInput.Icon style={styles.icon} icon="server" />}
onChangeText={value => actions.setNode(value)} onChangeText={value => actions.setNode(value)}
@ -170,7 +170,7 @@ export function Access() {
autoCapitalize="none" autoCapitalize="none"
autoComplete="off" autoComplete="off"
autoCorrect={false} autoCorrect={false}
label={state.strings.node} label={state.strings.server}
value={state.node} value={state.node}
left={<TextInput.Icon style={styles.icon} icon="server" />} left={<TextInput.Icon style={styles.icon} icon="server" />}
onChangeText={value => actions.setNode(value)} onChangeText={value => actions.setNode(value)}
@ -247,7 +247,7 @@ export function Access() {
autoCapitalize="none" autoCapitalize="none"
autoComplete="off" autoComplete="off"
autoCorrect={false} autoCorrect={false}
label={state.strings.node} label={state.strings.server}
value={state.node} value={state.node}
left={<TextInput.Icon style={styles.icon} icon="server" />} left={<TextInput.Icon style={styles.icon} icon="server" />}
onChangeText={value => actions.setNode(value)} onChangeText={value => actions.setNode(value)}

View File

@ -4,6 +4,7 @@ export const en = {
unknown: 'Unknown', unknown: 'Unknown',
sealed: 'Sealed', sealed: 'Sealed',
notes: 'Notes', notes: 'Notes',
server: 'Server',
code: 'en', code: 'en',
settings: 'Settings', settings: 'Settings',
@ -254,6 +255,8 @@ export const fr = {
unknown: 'Inconnu', unknown: 'Inconnu',
sealed: 'Scellé', sealed: 'Scellé',
notes: 'Notes', notes: 'Notes',
server: 'Serveur',
code: 'fr', code: 'fr',
settings: 'Paramètres', settings: 'Paramètres',
contacts: 'Contacts', contacts: 'Contacts',
@ -504,7 +507,8 @@ export const sp = {
unknown: 'Desconocido', unknown: 'Desconocido',
sealed: 'Sellado', sealed: 'Sellado',
notes: 'Notas', notes: 'Notas',
server: 'Server',
code: 'sp', code: 'sp',
settings: 'Configuración', settings: 'Configuración',
contacts: 'Contactos', contacts: 'Contactos',
@ -754,6 +758,7 @@ export const pt = {
unknown: 'Desconhecido', unknown: 'Desconhecido',
sealed: 'Selado', sealed: 'Selado',
notes: 'Notas', notes: 'Notas',
server: 'Servidor',
code: 'pt', code: 'pt',
settings: 'Configurações', settings: 'Configurações',
@ -1004,6 +1009,7 @@ export const de = {
unknown: 'Unbekannt', unknown: 'Unbekannt',
sealed: 'Versiegelt', sealed: 'Versiegelt',
notes: 'Notizen', notes: 'Notizen',
server: 'Servierer',
code: 'de', code: 'de',
settings: 'Einstellungen', settings: 'Einstellungen',
@ -1254,6 +1260,7 @@ export const ru = {
unknown: 'Неизвестно', unknown: 'Неизвестно',
sealed: 'Запечатано', sealed: 'Запечатано',
notes: 'Заметки', notes: 'Заметки',
server: 'Сервер',
code: 'ru', code: 'ru',
settings: 'Настройки', settings: 'Настройки',

View File

@ -61,7 +61,7 @@ export function Contacts({openRegistry, openContact}: {openRegistry: () => void;
style={styles.cards} style={styles.cards}
data={state.filtered} data={state.filtered}
initialNumToRender={32} initialNumToRender={32}
contentContainerStyle={styles.cardsContainer} contentContainerStyle={state.layout === 'large' ? styles.cardsContainer : {}}
showsVerticalScrollIndicator={false} showsVerticalScrollIndicator={false}
renderItem={({item}) => { renderItem={({item}) => {
const syncStatus = item.offsync ? 'offsync' : item.status; const syncStatus = item.offsync ? 'offsync' : item.status;

View File

@ -8,6 +8,7 @@ export function useContacts() {
const app = useContext(AppContext) as ContextType; const app = useContext(AppContext) as ContextType;
const display = useContext(DisplayContext) as ContextType; const display = useContext(DisplayContext) as ContextType;
const [state, setState] = useState({ const [state, setState] = useState({
layout: '',
strings: display.state.strings, strings: display.state.strings,
cards: [] as Card[], cards: [] as Card[],
filtered: [] as Card[], filtered: [] as Card[],
@ -46,6 +47,11 @@ export function useContacts() {
return false; return false;
}; };
useEffect(() => {
const { layout } = display.state;
updateState({ layout });
}, [display.state]);
useEffect(() => { useEffect(() => {
const contact = app.state.session?.getContact(); const contact = app.state.session?.getContact();
const setCards = (cards: Card[]) => { const setCards = (cards: Card[]) => {

View File

@ -3,7 +3,7 @@ import {DatabagSDK, Session} from 'databag-client-sdk';
import {SessionStore} from '../SessionStore'; import {SessionStore} from '../SessionStore';
import {NativeCrypto} from '../NativeCrypto'; import {NativeCrypto} from '../NativeCrypto';
import {LocalStore} from '../LocalStore'; import {LocalStore} from '../LocalStore';
const DATABAG_DB = 'db_v223.db'; const DATABAG_DB = 'db_v230.db';
const SETTINGS_DB = 'ls_v001.db'; const SETTINGS_DB = 'ls_v001.db';
const databag = new DatabagSDK( const databag = new DatabagSDK(

View File

@ -3,6 +3,15 @@ import {Colors} from '../constants/Colors';
export const styles = StyleSheet.create({ export const styles = StyleSheet.create({
profile: { profile: {
width: '100%',
height: '100%',
display: 'flex',
},
scrollWrapper: {
flexGrow: 1,
height: 1,
},
scrollContainer: {
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
alignItems: 'center', alignItems: 'center',
@ -49,6 +58,8 @@ export const styles = StyleSheet.create({
flexShrink: 0, flexShrink: 0,
marginRight: 0, marginRight: 0,
marginLeft: 0, marginLeft: 0,
marginTop: 0,
marginBottom: 0,
backgroundColor: 'transparent', backgroundColor: 'transparent',
}, },
image: { image: {
@ -72,6 +83,10 @@ export const styles = StyleSheet.create({
height: 2, height: 2,
width: '100%', width: '100%',
}, },
border: {
width: '100%',
height: 2,
},
attributes: { attributes: {
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',

File diff suppressed because it is too large Load Diff

View File

@ -18,11 +18,14 @@ export const styles = StyleSheet.create({
paddingLeft: 8, paddingLeft: 8,
width: '100%', width: '100%',
zIndex: 1, zIndex: 1,
height: 48,
}, },
close: { close: {
flexShrink: 0, flexShrink: 0,
marginRight: 0, marginRight: 0,
marginLeft: 0, marginLeft: 0,
marginTop: 0,
marginBottom: 0,
backgroundColor: 'transparent', backgroundColor: 'transparent',
}, },
divider: { divider: {

View File

@ -13,7 +13,7 @@ export function Registry({close, openContact}: {close: () => void; openContact:
return ( return (
<View style={styles.registry}> <View style={styles.registry}>
<SafeAreaView style={styles.header}> <SafeAreaView style={styles.header}>
{close && <IconButton style={styles.close} compact="true" mode="contained" icon="arrow-left" size={24} onPress={close} />} {close && <IconButton style={styles.close} compact="true" mode="contained" icon="arrow-left" size={28} onPress={close} />}
<Surface mode="flat" style={styles.inputUsername}> <Surface mode="flat" style={styles.inputUsername}>
<TextInput <TextInput
dense={true} dense={true}
@ -48,7 +48,7 @@ export function Registry({close, openContact}: {close: () => void; openContact:
style={styles.cards} style={styles.cards}
data={state.profiles} data={state.profiles}
initialNumToRender={32} initialNumToRender={32}
contentContainerStyle={styles.cardsContainer} contentContainerStyle={state.layout === 'large' ? styles.cardsContainer : {}}
showsVerticalScrollIndicator={false} showsVerticalScrollIndicator={false}
renderItem={({item}) => { renderItem={({item}) => {
const select = () => { const select = () => {

View File

@ -11,6 +11,7 @@ export function useRegistry() {
const app = useContext(AppContext) as ContextType; const app = useContext(AppContext) as ContextType;
const display = useContext(DisplayContext) as ContextType; const display = useContext(DisplayContext) as ContextType;
const [state, setState] = useState({ const [state, setState] = useState({
layout: '',
strings: display.state.strings, strings: display.state.strings,
username: '', username: '',
server: '', server: '',
@ -43,6 +44,11 @@ export function useRegistry() {
} }
}; };
useEffect(() => {
const { layout } = display.state;
updateState({ layout });
}, [display.state]);
useEffect(() => { useEffect(() => {
if (!state.username && !state.server) { if (!state.username && !state.server) {
clearTimeout(debounce.current); clearTimeout(debounce.current);

View File

@ -8,6 +8,9 @@ export const styles = StyleSheet.create({
height: '100%', height: '100%',
alignItems: 'center', alignItems: 'center',
}, },
border: {
height: 2,
},
blur: { blur: {
position: 'absolute', position: 'absolute',
top: 0, top: 0,
@ -42,11 +45,22 @@ export const styles = StyleSheet.create({
paddingTop: 8, paddingTop: 8,
}, },
settings: { settings: {
width: '100%',
height: '100%',
position: 'relative', position: 'relative',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
alignItems: 'center', alignItems: 'center',
}, },
scrollWrapper: {
width: '100%',
flexGrow: 1,
height: 1,
},
scrollContainer: {
display: 'flex',
alignItems: 'center',
},
modalHeader: { modalHeader: {
width: '100%', width: '100%',
display: 'flex', display: 'flex',
@ -73,13 +87,18 @@ export const styles = StyleSheet.create({
modalDescription: { modalDescription: {
paddingTop: 16, paddingTop: 16,
}, },
title: {
width: '100%',
height: 48,
},
header: { header: {
fontSize: 22, fontSize: 22,
textAlign: 'center', textAlign: 'center',
textWrap: 'nowrap', textWrap: 'nowrap',
textOverflow: 'ellipsis', textOverflow: 'ellipsis',
overflow: 'hidden', overflow: 'hidden',
paddingTop: 8, padding: 8,
height: 48,
}, },
image: { image: {
position: 'relative', position: 'relative',

View File

@ -322,243 +322,248 @@ export function Settings({showLogout}: {showLogout: boolean}) {
return ( return (
<View> <View>
<ScrollView showsVerticalScrollIndicator={false} style={styles.full}> <View style={styles.settings}>
<View style={styles.settings}> <View style={styles.title}>
<Text style={styles.header} adjustsFontSizeToFit={true} numberOfLines={1}>{`${state.profile.handle}${state.profile.node ? '/' + state.profile.node : ''}`}</Text> <Text style={styles.header} adjustsFontSizeToFit={true} numberOfLines={1}>{`${state.profile.handle}${state.profile.node ? '/' + state.profile.node : ''}`}</Text>
<View style={styles.image}> <Divider style={styles.border} bold={true} />
{!state.profile.imageSet && <Image style={styles.logoUnset} resizeMode={'contain'} source={{uri: state.imageUrl}} />} </View>
{state.profile.imageSet && <Image style={styles.logoSet} resizeMode={'contain'} source={{uri: state.imageUrl}} />} <View style={styles.scrollWrapper}>
<View style={styles.editBar}> <ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={styles.scrollContainer}>
<TouchableOpacity onPress={selectImage}> <View style={styles.image}>
<Surface style={styles.editBorder} elevation={0}> {!state.profile.imageSet && <Image style={styles.logoUnset} resizeMode={'contain'} source={{uri: state.imageUrl}} />}
<Text style={styles.editLogo}>{state.strings.edit}</Text> {state.profile.imageSet && <Image style={styles.logoSet} resizeMode={'contain'} source={{uri: state.imageUrl}} />}
<View style={styles.editBar}>
<TouchableOpacity onPress={selectImage}>
<Surface style={styles.editBorder} elevation={0}>
<Text style={styles.editLogo}>{state.strings.edit}</Text>
</Surface>
</TouchableOpacity>
</View>
</View>
<View style={styles.divider}>
<Divider style={styles.line} bold={true} />
</View>
<View style={styles.attributes}>
{!state.profile.name && <Text style={styles.nameUnset}>{state.strings.name}</Text>}
{state.profile.name && (
<Text style={styles.nameSet} adjustsFontSizeToFit={true} numberOfLines={1}>
{state.profile.name}
</Text>
)}
<View style={styles.attribute}>
<View style={styles.icon}>
<Icon size={24} source="map-marker-outline" />
</View>
{!state.profile.location && <Text style={styles.labelUnset}>{state.strings.location}</Text>}
{state.profile.location && <Text style={styles.labelSet}>{state.profile.location}</Text>}
</View>
<View style={styles.attribute}>
<View style={styles.icon}>
<Icon size={24} source="book-open-outline" />
</View>
{!state.profile.description && <Text style={styles.labelUnset}>{state.strings.description}</Text>}
{state.profile.description && <Text style={styles.labelSet}>{state.profile.description}</Text>}
</View>
<TouchableOpacity style={styles.editDetails} onPress={() => setDetails(true)}>
<Surface elevation={4} mode="flat">
<Text style={styles.editDetailsLabel}>{state.strings.edit}</Text>
</Surface> </Surface>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
</View>
<View style={styles.divider}> <View style={styles.divider}>
<Divider style={styles.line} bold={true} /> <Divider style={styles.line} bold={true} />
</View>
<View style={styles.attributes}>
{!state.profile.name && <Text style={styles.nameUnset}>{state.strings.name}</Text>}
{state.profile.name && (
<Text style={styles.nameSet} adjustsFontSizeToFit={true} numberOfLines={1}>
{state.profile.name}
</Text>
)}
<View style={styles.attribute}>
<View style={styles.icon}>
<Icon size={24} source="map-marker-outline" />
</View>
{!state.profile.location && <Text style={styles.labelUnset}>{state.strings.location}</Text>}
{state.profile.location && <Text style={styles.labelSet}>{state.profile.location}</Text>}
</View> </View>
<View style={styles.attribute}> <View style={styles.attributes}>
<View style={styles.icon}>
<Icon size={24} source="book-open-outline" />
</View>
{!state.profile.description && <Text style={styles.labelUnset}>{state.strings.description}</Text>}
{state.profile.description && <Text style={styles.labelSet}>{state.profile.description}</Text>}
</View>
<TouchableOpacity style={styles.editDetails} onPress={() => setDetails(true)}>
<Surface elevation={4} mode="flat">
<Text style={styles.editDetailsLabel}>{state.strings.edit}</Text>
</Surface>
</TouchableOpacity>
</View>
<View style={styles.divider}>
<Divider style={styles.line} bold={true} />
</View>
<View style={styles.attributes}>
<View style={styles.attribute}>
<View style={styles.controlIcon}>
<Icon size={24} source="eye-outline" />
</View>
<View style={styles.control}>
<TouchableOpacity activeOpacity={1} onPress={() => setRegistry(!state.config.searchable)}>
<Text style={styles.controlLabel}>{state.strings.registry}</Text>
</TouchableOpacity>
<Switch style={styles.controlSwitch} value={state.config.searchable} onValueChange={setRegistry} />
</View>
</View>
<View style={styles.attribute}>
<View style={styles.controlIcon}>
<Icon size={24} source="cloud-lock-outline" />
</View>
<View style={styles.control}>
<TouchableOpacity activeOpacity={1} onPress={setSeal}>
<Text style={styles.controlLabel}>{state.strings.manageTopics}</Text>
</TouchableOpacity>
</View>
</View>
<View style={styles.attribute}>
<View style={styles.controlIcon}>
<Icon size={24} source="bell-outline" />
</View>
<View style={styles.control}>
<TouchableOpacity activeOpacity={1} onPress={() => setRegistry(!state.config.pushEnabled)}>
<Text style={styles.controlLabel}>{state.strings.enableNotifications}</Text>
</TouchableOpacity>
<Switch style={styles.controlSwitch} value={state.config.pushEnabled} onValueChange={setNotifications} />
</View>
</View>
</View>
<View style={styles.divider}>
<Divider style={styles.line} bold={true} />
</View>
<View style={styles.attributes}>
<View style={styles.attribute}>
<View style={styles.controlIcon}>
<Icon size={24} source="ticket-confirmation-outline" />
</View>
<View style={styles.control}>
<TouchableOpacity activeOpacity={1} onPress={() => setRegistry(!state.config.searchable)}>
<Text style={styles.controlLabel}>{state.strings.mfaTitle}</Text>
</TouchableOpacity>
<Switch style={styles.controlSwitch} value={state.config.mfaEnabled} onValueChange={setMfa} />
</View>
</View>
<View style={styles.attribute}>
<View style={styles.controlIcon}>
<Icon size={24} source="login" />
</View>
<View style={styles.control}>
<TouchableOpacity activeOpacity={1} onPress={changeLogin}>
<Text style={styles.controlLabel}>{state.strings.changeLogin}</Text>
</TouchableOpacity>
</View>
</View>
{showLogout && (
<View style={styles.attribute}> <View style={styles.attribute}>
<View style={styles.controlIcon}> <View style={styles.controlIcon}>
<Icon size={24} source="logout" /> <Icon size={24} source="eye-outline" />
</View> </View>
<View style={styles.control}> <View style={styles.control}>
<TouchableOpacity activeOpacity={1} onPress={() => setLogout(true)}> <TouchableOpacity activeOpacity={1} onPress={() => setRegistry(!state.config.searchable)}>
<Text style={styles.controlLabel}>{state.strings.logout}</Text> <Text style={styles.controlLabel}>{state.strings.registry}</Text>
</TouchableOpacity>
<Switch style={styles.controlSwitch} value={state.config.searchable} onValueChange={setRegistry} />
</View>
</View>
<View style={styles.attribute}>
<View style={styles.controlIcon}>
<Icon size={24} source="cloud-lock-outline" />
</View>
<View style={styles.control}>
<TouchableOpacity activeOpacity={1} onPress={setSeal}>
<Text style={styles.controlLabel}>{state.strings.manageTopics}</Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
</View> </View>
)} <View style={styles.attribute}>
<View style={styles.attribute}> <View style={styles.controlIcon}>
<View style={styles.controlIcon}> <Icon size={24} source="bell-outline" />
<Icon size={24} source="account-remove" /> </View>
</View> <View style={styles.control}>
<View style={styles.control}> <TouchableOpacity activeOpacity={1} onPress={() => setRegistry(!state.config.pushEnabled)}>
<TouchableOpacity activeOpacity={1} onPress={() => setRemove(true)}> <Text style={styles.controlLabel}>{state.strings.enableNotifications}</Text>
<Text style={styles.dangerLabel}>{state.strings.deleteAccount}</Text> </TouchableOpacity>
</TouchableOpacity> <Switch style={styles.controlSwitch} value={state.config.pushEnabled} onValueChange={setNotifications} />
</View>
</View>
</View>
<View style={styles.divider}>
<Divider style={styles.line} bold={true} />
</View>
<View style={styles.attributes}>
<View style={styles.attribute}>
<View style={styles.controlIcon}>
<Icon size={24} source="account-cancel-outline" />
</View>
<View style={styles.control}>
<TouchableOpacity activeOpacity={1} onPress={() => manageSeal}>
<Text style={styles.controlLabel}>{state.strings.blockedContacts}</Text>
</TouchableOpacity>
</View>
</View>
<View style={styles.attribute}>
<View style={styles.controlIcon}>
<Icon size={24} source="archive-cancel-outline" />
</View>
<View style={styles.control}>
<TouchableOpacity activeOpacity={1} onPress={() => manageSeal}>
<Text style={styles.controlLabel}>{state.strings.blockedTopics}</Text>
</TouchableOpacity>
</View>
</View>
<View style={styles.attribute}>
<View style={styles.controlIcon}>
<Icon size={24} source="file-cancel-outline" />
</View>
<View style={styles.control}>
<TouchableOpacity activeOpacity={1} onPress={() => manageSeal}>
<Text style={styles.controlLabel}>{state.strings.blockedMessages}</Text>
</TouchableOpacity>
</View>
</View>
</View>
<View style={styles.divider}>
<Divider style={styles.line} bold={true} />
</View>
<View style={styles.options}>
<View style={styles.attribute}>
<View style={styles.radioIcon}>
<Icon size={24} source="clock-outline" />
</View>
<View style={styles.radioControl}>
<Text style={styles.smallLabel}>{state.strings.timeFormat}:</Text>
<View style={styles.radioButtons}>
<RadioButton.Item
style={styles.radio}
label={state.strings.timeHalf}
labelStyle={styles.option}
mode="android"
status={state.fullDayTime ? 'unchecked' : 'checked'}
onPress={() => {
actions.setFullDayTime(false);
}}
/>
<RadioButton.Item
style={styles.radio}
label={state.strings.timeFull}
labelStyle={styles.option}
mode="android"
status={state.fullDayTime ? 'checked' : 'unchecked'}
onPress={() => {
actions.setFullDayTime(true);
}}
/>
</View> </View>
</View> </View>
</View> </View>
<View style={styles.attribute}>
<View style={styles.radioIcon}> <View style={styles.divider}>
<Icon size={24} source="calendar-text-outline" /> <Divider style={styles.line} bold={true} />
</View>
<View style={styles.attributes}>
<View style={styles.attribute}>
<View style={styles.controlIcon}>
<Icon size={24} source="ticket-confirmation-outline" />
</View>
<View style={styles.control}>
<TouchableOpacity activeOpacity={1} onPress={() => setRegistry(!state.config.searchable)}>
<Text style={styles.controlLabel}>{state.strings.mfaTitle}</Text>
</TouchableOpacity>
<Switch style={styles.controlSwitch} value={state.config.mfaEnabled} onValueChange={setMfa} />
</View>
</View> </View>
<View style={styles.radioControl}> <View style={styles.attribute}>
<Text style={styles.smallLabel}>{state.strings.dateFormat}:</Text> <View style={styles.controlIcon}>
<View style={styles.radioButtons}> <Icon size={24} source="login" />
<RadioButton.Item </View>
style={styles.radio} <View style={styles.control}>
label={state.strings.monthStart} <TouchableOpacity activeOpacity={1} onPress={changeLogin}>
labelStyle={styles.option} <Text style={styles.controlLabel}>{state.strings.changeLogin}</Text>
mode="android" </TouchableOpacity>
status={state.monthFirstDate ? 'checked' : 'unchecked'} </View>
onPress={() => { </View>
actions.setMonthFirstDate(true); {showLogout && (
}} <View style={styles.attribute}>
/> <View style={styles.controlIcon}>
<RadioButton.Item <Icon size={24} source="logout" />
style={styles.radio} </View>
label={state.strings.monthEnd} <View style={styles.control}>
labelStyle={styles.option} <TouchableOpacity activeOpacity={1} onPress={() => setLogout(true)}>
mode="android" <Text style={styles.controlLabel}>{state.strings.logout}</Text>
status={state.monthFirstDate ? 'unchecked' : 'checked'} </TouchableOpacity>
onPress={() => { </View>
actions.setMonthFirstDate(false); </View>
}} )}
/> <View style={styles.attribute}>
<View style={styles.controlIcon}>
<Icon size={24} source="account-remove" />
</View>
<View style={styles.control}>
<TouchableOpacity activeOpacity={1} onPress={() => setRemove(true)}>
<Text style={styles.dangerLabel}>{state.strings.deleteAccount}</Text>
</TouchableOpacity>
</View> </View>
</View> </View>
</View> </View>
</View>
<View style={styles.divider}>
<Divider style={styles.line} bold={true} />
</View>
<View style={styles.attributes}>
<View style={styles.attribute}>
<View style={styles.controlIcon}>
<Icon size={24} source="account-cancel-outline" />
</View>
<View style={styles.control}>
<TouchableOpacity activeOpacity={1} onPress={() => manageSeal}>
<Text style={styles.controlLabel}>{state.strings.blockedContacts}</Text>
</TouchableOpacity>
</View>
</View>
<View style={styles.attribute}>
<View style={styles.controlIcon}>
<Icon size={24} source="archive-cancel-outline" />
</View>
<View style={styles.control}>
<TouchableOpacity activeOpacity={1} onPress={() => manageSeal}>
<Text style={styles.controlLabel}>{state.strings.blockedTopics}</Text>
</TouchableOpacity>
</View>
</View>
<View style={styles.attribute}>
<View style={styles.controlIcon}>
<Icon size={24} source="file-cancel-outline" />
</View>
<View style={styles.control}>
<TouchableOpacity activeOpacity={1} onPress={() => manageSeal}>
<Text style={styles.controlLabel}>{state.strings.blockedMessages}</Text>
</TouchableOpacity>
</View>
</View>
</View>
<View style={styles.divider}>
<Divider style={styles.line} bold={true} />
</View>
<View style={styles.options}>
<View style={styles.attribute}>
<View style={styles.radioIcon}>
<Icon size={24} source="clock-outline" />
</View>
<View style={styles.radioControl}>
<Text style={styles.smallLabel}>{state.strings.timeFormat}:</Text>
<View style={styles.radioButtons}>
<RadioButton.Item
style={styles.radio}
label={state.strings.timeHalf}
labelStyle={styles.option}
mode="android"
status={state.fullDayTime ? 'unchecked' : 'checked'}
onPress={() => {
actions.setFullDayTime(false);
}}
/>
<RadioButton.Item
style={styles.radio}
label={state.strings.timeFull}
labelStyle={styles.option}
mode="android"
status={state.fullDayTime ? 'checked' : 'unchecked'}
onPress={() => {
actions.setFullDayTime(true);
}}
/>
</View>
</View>
</View>
<View style={styles.attribute}>
<View style={styles.radioIcon}>
<Icon size={24} source="calendar-text-outline" />
</View>
<View style={styles.radioControl}>
<Text style={styles.smallLabel}>{state.strings.dateFormat}:</Text>
<View style={styles.radioButtons}>
<RadioButton.Item
style={styles.radio}
label={state.strings.monthStart}
labelStyle={styles.option}
mode="android"
status={state.monthFirstDate ? 'checked' : 'unchecked'}
onPress={() => {
actions.setMonthFirstDate(true);
}}
/>
<RadioButton.Item
style={styles.radio}
label={state.strings.monthEnd}
labelStyle={styles.option}
mode="android"
status={state.monthFirstDate ? 'unchecked' : 'checked'}
onPress={() => {
actions.setMonthFirstDate(false);
}}
/>
</View>
</View>
</View>
</View>
</ScrollView>
</View> </View>
</ScrollView> </View>
<Modal animationType="fade" transparent={true} visible={sealing} supportedOrientations={['portrait', 'landscape']} onRequestClose={() => setSealing(false)}> <Modal animationType="fade" transparent={true} visible={sealing} supportedOrientations={['portrait', 'landscape']} onRequestClose={() => setSealing(false)}>
<View style={styles.modal}> <View style={styles.modal}>
<BlurView style={styles.blur} blurType="dark" blurAmount={2} reducedTransparencyFallbackColor="dark" /> <BlurView style={styles.blur} blurType="dark" blurAmount={2} reducedTransparencyFallbackColor="dark" />