BlueWallet/screen/settings/ElectrumSettings.tsx

649 lines
22 KiB
TypeScript
Raw Normal View History

2024-09-26 19:21:47 -04:00
import React, { useState, useEffect, useMemo, useCallback } from 'react';
import { Alert, Keyboard, LayoutAnimation, Platform, ScrollView, StyleSheet, Switch, TextInput, View } from 'react-native';
2024-09-23 21:36:45 -04:00
import * as BlueElectrum from '../../blue_modules/BlueElectrum';
import triggerHapticFeedback, { HapticFeedbackTypes, triggerSelectionHapticFeedback } from '../../blue_modules/hapticFeedback';
2024-09-26 19:21:47 -04:00
import { BlueCard, BlueSpacing10, BlueSpacing20, BlueText } from '../../BlueComponents';
2024-09-23 21:36:45 -04:00
import DeeplinkSchemaMatch from '../../class/deeplink-schema-match';
2024-09-27 18:00:53 -04:00
import presentAlert from '../../components/Alert';
2024-09-23 21:36:45 -04:00
import Button from '../../components/Button';
import { scanQrHelper } from '../../helpers/scan-qr';
import loc from '../../loc';
import {
DoneAndDismissKeyboardInputAccessory,
DoneAndDismissKeyboardInputAccessoryViewID,
} from '../../components/DoneAndDismissKeyboardInputAccessory';
import DefaultPreference from 'react-native-default-preference';
import { DismissKeyboardInputAccessory, DismissKeyboardInputAccessoryViewID } from '../../components/DismissKeyboardInputAccessory';
import { useTheme } from '../../components/themes';
import { RouteProp, useRoute } from '@react-navigation/native';
import { DetailViewStackParamList } from '../../navigation/DetailViewStackParamList';
import { useExtendedNavigation } from '../../hooks/useExtendedNavigation';
import { CommonToolTipActions } from '../../typings/CommonToolTipActions';
2024-09-27 08:27:32 -04:00
import { Divider } from '@rneui/themed';
2024-09-23 21:36:45 -04:00
import { Header } from '../../components/Header';
import AddressInput from '../../components/AddressInput';
import { GROUP_IO_BLUEWALLET } from '../../blue_modules/currency';
2024-09-26 19:21:47 -04:00
import { Action } from '../../components/types';
import ListItem, { PressableWrapper } from '../../components/ListItem';
2024-09-27 08:27:32 -04:00
import HeaderMenuButton from '../../components/HeaderMenuButton';
import { useSettings } from '../../hooks/context/useSettings';
2024-12-29 01:26:10 -04:00
import { suggestedServers, hardcodedPeers, presentResetToDefaultsAlert } from '../../blue_modules/BlueElectrum';
2024-09-23 21:36:45 -04:00
type RouteProps = RouteProp<DetailViewStackParamList, 'ElectrumSettings'>;
export interface ElectrumServerItem {
host: string;
2024-12-29 01:26:10 -04:00
tcp?: number;
ssl?: number;
2024-09-23 21:36:45 -04:00
}
2024-12-29 01:26:10 -04:00
const SET_PREFERRED_PREFIX = 'set_preferred_';
const DELETE_PREFIX = 'delete_';
const PREFERRED_SERVER_ROW = 'preferredserverrow';
2024-09-23 21:36:45 -04:00
const ElectrumSettings: React.FC = () => {
const { colors } = useTheme();
const { server } = useRoute<RouteProps>().params;
const { setOptions } = useExtendedNavigation();
const [isLoading, setIsLoading] = useState(true);
const [serverHistory, setServerHistory] = useState<ElectrumServerItem[]>([]);
const [config, setConfig] = useState<{ connected?: number; host?: string; port?: string }>({});
const [host, setHost] = useState<string>('');
const [port, setPort] = useState<number | undefined>();
const [sslPort, setSslPort] = useState<number | undefined>(undefined);
const [isAndroidNumericKeyboardFocused, setIsAndroidNumericKeyboardFocused] = useState(false);
const [isAndroidAddressKeyboardVisible, setIsAndroidAddressKeyboardVisible] = useState(false);
const { setIsElectrumDisabled, isElectrumDisabled } = useSettings();
2024-09-23 21:36:45 -04:00
const stylesHook = StyleSheet.create({
inputWrap: {
borderColor: colors.formBorder,
backgroundColor: colors.inputBackgroundColor,
},
containerConnected: {
backgroundColor: colors.feeLabel,
},
containerDisconnected: {
backgroundColor: colors.redBG,
},
textConnected: {
color: colors.feeValue,
},
textDisconnected: {
color: colors.redText,
},
hostname: {
color: colors.foregroundColor,
},
inputText: {
color: colors.foregroundColor,
},
usePort: {
color: colors.foregroundColor,
},
});
2024-12-29 01:26:10 -04:00
const configIntervalRef = React.useRef<NodeJS.Timeout | null>(null);
const fetchData = React.useCallback(async () => {
console.log('Fetching data...');
const preferredServer = await BlueElectrum.getPreferredServer();
const savedHost = preferredServer?.host;
const savedPort = preferredServer?.tcp;
const savedSslPort = preferredServer?.ssl;
const serverHistoryStr = (await DefaultPreference.get(BlueElectrum.ELECTRUM_SERVER_HISTORY)) as string;
console.log('Preferred server:', preferredServer);
console.log('Server history string:', serverHistoryStr);
const parsedServerHistory: ElectrumServerItem[] = serverHistoryStr ? JSON.parse(serverHistoryStr) : [];
const filteredServerHistory = parsedServerHistory.filter(
v =>
v.host &&
(v.tcp || v.ssl) &&
!suggestedServers.some(suggested => suggested.host === v.host && suggested.tcp === v.tcp && suggested.ssl === v.ssl) &&
!hardcodedPeers.some(peer => peer.host === v.host),
);
console.log('Filtered server history:', filteredServerHistory);
setHost(savedHost || '');
setPort(savedPort ? Number(savedPort) : undefined);
setSslPort(savedSslPort ? Number(savedSslPort) : undefined);
setServerHistory(filteredServerHistory);
setConfig(await BlueElectrum.getConfig());
configIntervalRef.current = setInterval(async () => {
2024-09-23 21:36:45 -04:00
setConfig(await BlueElectrum.getConfig());
2024-12-29 01:26:10 -04:00
}, 500);
setIsLoading(false);
2024-09-23 21:36:45 -04:00
2024-12-29 01:26:10 -04:00
return () => {
if (configIntervalRef.current) clearInterval(configIntervalRef.current);
2024-09-23 21:36:45 -04:00
};
2024-12-29 01:26:10 -04:00
}, []);
2024-09-23 21:36:45 -04:00
2024-12-29 01:26:10 -04:00
useEffect(() => {
2024-09-23 21:36:45 -04:00
fetchData();
2024-10-08 09:43:48 -04:00
return () => {
2024-12-29 01:26:10 -04:00
if (configIntervalRef.current) clearInterval(configIntervalRef.current);
2024-10-08 09:43:48 -04:00
};
2024-12-29 01:26:10 -04:00
}, [fetchData]);
2024-09-23 21:36:45 -04:00
useEffect(() => {
if (server) {
triggerHapticFeedback(HapticFeedbackTypes.ImpactHeavy);
Alert.alert(
loc.formatString(loc.settings.set_electrum_server_as_default, { server: (server as ElectrumServerItem).host }),
'',
[
{
text: loc._.ok,
onPress: () => {
onBarScanned(JSON.stringify(server));
},
style: 'default',
},
{ text: loc._.cancel, onPress: () => {}, style: 'cancel' },
],
{ cancelable: false },
);
}
2024-09-26 19:21:47 -04:00
}, [server]);
2024-09-23 21:36:45 -04:00
2024-09-26 19:21:47 -04:00
const clearHistory = useCallback(async () => {
2024-09-23 21:36:45 -04:00
setIsLoading(true);
2024-12-29 01:26:10 -04:00
await DefaultPreference.clear(BlueElectrum.ELECTRUM_SERVER_HISTORY);
2024-09-23 21:36:45 -04:00
setServerHistory([]);
setIsLoading(false);
2024-09-26 19:21:47 -04:00
}, []);
2024-09-23 21:36:45 -04:00
const serverExists = useCallback(
(value: ElectrumServerItem) => {
2024-12-29 01:26:10 -04:00
return serverHistory.some(s => `${s.host}:${s.tcp}:${s.ssl}` === `${value.host}:${value.tcp}:${value.ssl}`);
2024-09-23 21:36:45 -04:00
},
[serverHistory],
);
2024-12-29 01:26:10 -04:00
const save = useCallback(
async (v?: ElectrumServerItem) => {
Keyboard.dismiss();
setIsLoading(true);
try {
const serverHost = v?.host || host;
const serverPort = v?.tcp || port?.toString() || '';
const serverSslPort = v?.ssl || sslPort?.toString() || '';
if (serverHost && (serverPort || serverSslPort)) {
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
await DefaultPreference.set(BlueElectrum.ELECTRUM_HOST, serverHost);
await DefaultPreference.set(BlueElectrum.ELECTRUM_TCP_PORT, serverPort);
await DefaultPreference.set(BlueElectrum.ELECTRUM_SSL_PORT, serverSslPort);
if (
!serverExists({ host: serverHost, tcp: Number(serverPort), ssl: Number(serverSslPort) }) &&
(serverPort || serverSslPort) &&
!hardcodedPeers.some(peer => peer.host === serverHost)
) {
const newServerHistory = [...serverHistory, { host: serverHost, tcp: Number(serverPort), ssl: Number(serverSslPort) }];
await DefaultPreference.set(BlueElectrum.ELECTRUM_SERVER_HISTORY, JSON.stringify(newServerHistory));
setServerHistory(newServerHistory);
}
2024-09-23 21:36:45 -04:00
}
2024-12-29 01:26:10 -04:00
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
presentAlert({ message: loc.settings.electrum_saved });
} catch (error) {
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
presentAlert({ message: (error as Error).message });
} finally {
setIsLoading(false);
2024-09-23 21:36:45 -04:00
}
2024-12-29 01:26:10 -04:00
},
[host, port, sslPort, serverExists, serverHistory],
);
2024-09-23 21:36:45 -04:00
const resetToDefault = useCallback(() => {
2024-12-29 01:26:10 -04:00
Alert.alert(loc.settings.electrum_preferred_server, loc.settings.electrum_preferred_server_description, [
2024-09-27 18:00:53 -04:00
{
text: loc._.cancel,
onPress: () => console.log('Cancel Pressed'),
style: 'cancel',
},
{
text: loc._.ok,
style: 'destructive',
onPress: async () => {
2024-12-29 01:26:10 -04:00
await BlueElectrum.removePreferredServer();
2024-09-27 18:00:53 -04:00
setHost('');
setPort(undefined);
setSslPort(undefined);
2024-12-29 15:25:51 -04:00
presentAlert({ message: loc.settings.electrum_saved });
2024-09-27 18:00:53 -04:00
},
},
]);
2024-12-29 01:26:10 -04:00
}, []);
2024-09-23 21:36:45 -04:00
2024-09-26 19:21:47 -04:00
const selectServer = useCallback(
(value: string) => {
const parsedServer = JSON.parse(value) as ElectrumServerItem;
setHost(parsedServer.host);
2024-12-29 01:26:10 -04:00
setPort(parsedServer.tcp);
setSslPort(parsedServer.ssl);
save(parsedServer);
2024-09-26 19:21:47 -04:00
},
[save],
);
const clearHistoryAlert = useCallback(() => {
triggerHapticFeedback(HapticFeedbackTypes.ImpactHeavy);
Alert.alert(loc.settings.electrum_clear_alert_title, loc.settings.electrum_clear_alert_message, [
{ text: loc.settings.electrum_clear_alert_cancel, onPress: () => console.log('Cancel Pressed'), style: 'cancel' },
2024-12-29 01:26:10 -04:00
{ text: loc._.ok, onPress: () => clearHistory() },
2024-09-26 19:21:47 -04:00
]);
}, [clearHistory]);
2024-09-23 21:36:45 -04:00
const onPressMenuItem = useCallback(
(id: string) => {
2024-12-29 01:26:10 -04:00
if (id.startsWith(SET_PREFERRED_PREFIX)) {
const rawServer = JSON.parse(id.replace(SET_PREFERRED_PREFIX, ''));
selectServer(JSON.stringify(rawServer));
} else if (id.startsWith(DELETE_PREFIX)) {
const rawServer = JSON.parse(id.replace(DELETE_PREFIX, ''));
const newServerHistory = serverHistory
.filter(s => !(s.host === rawServer.host && s.tcp === rawServer.tcp && s.ssl === rawServer.ssl))
.filter(
v => !suggestedServers.some(suggested => suggested.host === v.host && suggested.tcp === v.tcp && suggested.ssl === v.ssl),
);
setServerHistory(newServerHistory);
DefaultPreference.set(BlueElectrum.ELECTRUM_SERVER_HISTORY, JSON.stringify(newServerHistory));
} else if (id === PREFERRED_SERVER_ROW) {
presentResetToDefaultsAlert().then(async result => {
if (result) {
await BlueElectrum.removePreferredServer();
2024-12-29 15:25:51 -04:00
presentAlert({ message: loc.settings.electrum_saved });
2024-12-29 01:26:10 -04:00
fetchData();
2024-09-26 19:21:47 -04:00
}
2024-12-29 01:26:10 -04:00
});
} else {
switch (id) {
case CommonToolTipActions.ResetToDefault.id:
resetToDefault();
break;
case CommonToolTipActions.ClearHistory.id:
clearHistoryAlert();
break;
default:
try {
selectServer(id);
} catch (error) {
console.warn('Unknown menu item selected:', id);
}
break;
}
2024-09-23 21:36:45 -04:00
}
},
2024-12-29 01:26:10 -04:00
[selectServer, serverHistory, fetchData, resetToDefault, clearHistoryAlert],
2024-09-23 21:36:45 -04:00
);
2024-12-29 01:26:10 -04:00
const createServerAction = useCallback(
(value: ElectrumServerItem, seenHosts: Set<string>) => {
const hostKey = `${value.host}:${value.ssl ?? value.tcp}`;
if (seenHosts.has(hostKey)) return null;
2024-09-26 19:21:47 -04:00
2024-12-29 01:26:10 -04:00
seenHosts.add(hostKey);
return {
2024-09-26 19:21:47 -04:00
id: JSON.stringify(value),
2024-12-29 01:26:10 -04:00
text: Platform.OS === 'android' ? `${value.host}:${value.ssl ?? value.tcp}` : value.host,
subactions: [
...(host === value.host && (port === value.tcp || sslPort === value.ssl)
? []
: [
{
id: `${SET_PREFERRED_PREFIX}${JSON.stringify(value)}`,
text: loc.settings.set_as_preferred,
subtitle: `${loc._.port}: ${value.ssl ?? value.tcp}`,
},
]),
...(hardcodedPeers.some(peer => peer.host === value.host)
? []
: [
{
id: `${DELETE_PREFIX}${JSON.stringify(value)}`,
text: loc.wallets.details_delete,
},
]),
],
} as Action;
},
[host, port, sslPort],
);
const generateToolTipActions = useCallback(() => {
const actions: Action[] = [];
const seenHosts = new Set<string>();
if (host) {
const preferred = {
id: 'preferred',
hidden: false,
displayInline: true,
text: loc.settings.electrum_preferred_server,
subactions: [
{
id: PREFERRED_SERVER_ROW,
text: Platform.OS === 'android' ? `${host} (${sslPort ?? port})` : host,
subtitle: `${loc._.port}: ${sslPort ?? port}`,
menuState: true,
},
],
};
actions.push(preferred);
seenHosts.add(`${host}:${sslPort ?? port}`);
}
const suggestedServersAction: Action = {
id: 'suggested_servers',
text: loc._.suggested,
displayInline: true,
subtitle: loc.settings.electrum_suggested_description,
subactions: suggestedServers.map(value => createServerAction(value, seenHosts)).filter((action): action is Action => action !== null),
};
actions.push(suggestedServersAction);
console.warn('serverHistory', serverHistory);
if (serverHistory.length > 0) {
const serverSubactions: Action[] = serverHistory
.map(value => createServerAction(value, seenHosts))
.filter((action): action is Action => action !== null);
2024-09-26 19:21:47 -04:00
actions.push({
id: 'server_history',
text: loc.settings.electrum_history,
2024-12-29 01:26:10 -04:00
displayInline: serverHistory.length <= 5 && serverHistory.length > 0,
2024-09-26 19:21:47 -04:00
subactions: [CommonToolTipActions.ClearHistory, ...serverSubactions],
2024-12-29 01:26:10 -04:00
hidden: serverHistory.length === 0,
2024-09-26 19:21:47 -04:00
});
}
2024-12-29 01:26:10 -04:00
2024-09-26 19:21:47 -04:00
return actions;
2024-12-29 01:26:10 -04:00
}, [createServerAction, host, port, serverHistory, sslPort]);
2024-09-23 21:36:45 -04:00
const HeaderRight = useMemo(
2024-12-29 01:26:10 -04:00
() => <HeaderMenuButton actions={generateToolTipActions()} onPressMenuItem={onPressMenuItem} />,
[onPressMenuItem, generateToolTipActions],
2024-09-23 21:36:45 -04:00
);
useEffect(() => {
setOptions({
headerRight: isElectrumDisabled ? null : () => HeaderRight,
2024-09-23 21:36:45 -04:00
});
}, [HeaderRight, isElectrumDisabled, setOptions]);
2024-09-23 21:36:45 -04:00
const checkServer = async () => {
setIsLoading(true);
try {
const features = await BlueElectrum.serverFeatures();
triggerHapticFeedback(HapticFeedbackTypes.NotificationWarning);
presentAlert({ message: JSON.stringify(features, null, 2) });
} catch (error) {
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
2024-10-16 00:11:13 -04:00
presentAlert({ message: (error as Error).message });
}
2024-09-23 21:36:45 -04:00
setIsLoading(false);
};
const onBarScanned = (value: string) => {
let v = value;
if (value && DeeplinkSchemaMatch.getServerFromSetElectrumServerAction(value)) {
v = DeeplinkSchemaMatch.getServerFromSetElectrumServerAction(value) as string;
}
const [scannedHost, scannedPort, type] = v?.split(':') ?? [];
setHost(scannedHost);
if (type === 's') {
setSslPort(Number(scannedPort));
setPort(undefined);
} else {
setPort(Number(scannedPort));
setSslPort(undefined);
}
};
const importScan = async () => {
const scanned = await scanQrHelper('ElectrumSettings', true);
if (scanned) {
onBarScanned(scanned);
}
};
const onSSLPortChange = (value: boolean) => {
2024-09-27 08:27:32 -04:00
Keyboard.dismiss();
2024-09-23 21:36:45 -04:00
if (value) {
setPort(undefined);
setSslPort(port);
} else {
setPort(sslPort);
setSslPort(undefined);
}
};
const onElectrumConnectionEnabledSwitchChange = async (value: boolean) => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
2024-11-01 11:44:18 -04:00
try {
triggerSelectionHapticFeedback();
await BlueElectrum.setDisabled(value);
setIsElectrumDisabled(value);
} catch (error) {
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
presentAlert({ message: (error as Error).message });
}
2024-09-23 21:36:45 -04:00
};
2024-12-29 01:26:10 -04:00
const preferredServerIsEmpty = !host || (!port && !sslPort);
2024-09-23 21:36:45 -04:00
const renderElectrumSettings = () => {
return (
<>
2024-09-26 19:21:47 -04:00
<Divider />
<BlueSpacing20 />
2024-09-23 21:36:45 -04:00
<Header leftText={loc.settings.electrum_status} />
2024-09-26 19:21:47 -04:00
<BlueSpacing20 />
2024-09-23 21:36:45 -04:00
<BlueCard>
<View style={styles.connectWrap}>
<View style={[styles.container, config.connected === 1 ? stylesHook.containerConnected : stylesHook.containerDisconnected]}>
<BlueText
style={[styles.textConnectionStatus, config.connected === 1 ? stylesHook.textConnected : stylesHook.textDisconnected]}
>
{config.connected === 1 ? loc.settings.electrum_connected : loc.settings.electrum_connected_not}
</BlueText>
</View>
</View>
2024-09-26 19:21:47 -04:00
<BlueSpacing10 />
2024-09-27 08:27:32 -04:00
<BlueText style={[styles.hostname, stylesHook.hostname]} onPress={checkServer} selectable>
2024-09-23 21:36:45 -04:00
{config.host}:{config.port}
</BlueText>
</BlueCard>
2024-09-26 19:21:47 -04:00
<BlueSpacing20 />
2024-09-23 21:36:45 -04:00
2024-09-26 19:21:47 -04:00
<Divider />
<BlueSpacing10 />
<BlueSpacing20 />
<Header leftText={loc.settings.electrum_preferred_server} />
2024-09-23 21:36:45 -04:00
<BlueCard>
2024-09-26 19:21:47 -04:00
<BlueText>{loc.settings.electrum_preferred_server_description}</BlueText>
<BlueSpacing20 />
2024-09-23 21:36:45 -04:00
<AddressInput
2024-09-26 19:21:47 -04:00
testID="HostInput"
2024-09-23 21:36:45 -04:00
placeholder={loc.formatString(loc.settings.electrum_host, { example: '10.20.30.40' })}
address={host}
onChangeText={text => setHost(text.trim())}
editable={!isLoading}
onBarScanned={importScan}
2024-09-26 19:21:47 -04:00
keyboardType="default"
2024-09-23 21:36:45 -04:00
onBlur={() => setIsAndroidAddressKeyboardVisible(false)}
2024-09-26 19:21:47 -04:00
onFocus={() => setIsAndroidAddressKeyboardVisible(true)}
2024-09-23 21:36:45 -04:00
inputAccessoryViewID={DoneAndDismissKeyboardInputAccessoryViewID}
isLoading={isLoading}
/>
<BlueSpacing20 />
<View style={styles.portWrap}>
<View style={[styles.inputWrap, stylesHook.inputWrap]}>
<TextInput
placeholder={loc.formatString(loc.settings.electrum_port, { example: '50001' })}
value={sslPort?.toString() === '' || sslPort === undefined ? port?.toString() || '' : sslPort?.toString() || ''}
onChangeText={text => {
const parsed = Number(text.trim());
if (Number.isNaN(parsed)) {
// Handle invalid input
sslPort === undefined ? setPort(undefined) : setSslPort(undefined);
return;
}
sslPort === undefined ? setPort(parsed) : setSslPort(parsed);
2024-09-23 21:36:45 -04:00
}}
numberOfLines={1}
style={[styles.inputText, stylesHook.inputText]}
editable={!isLoading}
placeholderTextColor="#81868e"
underlineColorAndroid="transparent"
autoCorrect={false}
autoCapitalize="none"
keyboardType="number-pad"
inputAccessoryViewID={DismissKeyboardInputAccessoryViewID}
testID="PortInput"
onFocus={() => setIsAndroidNumericKeyboardFocused(true)}
onBlur={() => setIsAndroidNumericKeyboardFocused(false)}
/>
</View>
<BlueText style={[styles.usePort, stylesHook.usePort]}>{loc.settings.use_ssl}</BlueText>
<Switch
testID="SSLPortInput"
value={sslPort !== undefined}
onValueChange={onSSLPortChange}
2024-12-29 01:26:10 -04:00
disabled={host?.endsWith('.onion') || isLoading || host === '' || (port === undefined && sslPort === undefined)}
2024-09-23 21:36:45 -04:00
/>
</View>
</BlueCard>
<BlueCard>
<BlueSpacing20 />
2024-12-29 01:26:10 -04:00
<Button
showActivityIndicator={isLoading}
disabled={isLoading || preferredServerIsEmpty}
testID="Save"
onPress={save}
title={loc.settings.save}
/>
2024-09-23 21:36:45 -04:00
</BlueCard>
{Platform.select({
ios: <DismissKeyboardInputAccessory />,
android: isAndroidNumericKeyboardFocused && <DismissKeyboardInputAccessory />,
})}
{Platform.select({
ios: (
<DoneAndDismissKeyboardInputAccessory
onClearTapped={() => setHost('')}
onPasteTapped={text => {
setHost(text);
Keyboard.dismiss();
}}
/>
),
android: isAndroidAddressKeyboardVisible && (
<DoneAndDismissKeyboardInputAccessory
onClearTapped={() => {
setHost('');
Keyboard.dismiss();
}}
onPasteTapped={text => {
setHost(text);
Keyboard.dismiss();
}}
/>
),
})}
</>
);
};
return (
<ScrollView
keyboardShouldPersistTaps="always"
automaticallyAdjustContentInsets
contentInsetAdjustmentBehavior="automatic"
automaticallyAdjustKeyboardInsets
testID="ElectrumSettingsScrollView"
>
<ListItem
Component={PressableWrapper}
title={loc.settings.electrum_offline_mode}
switch={{
onValueChange: onElectrumConnectionEnabledSwitchChange,
value: isElectrumDisabled,
2024-09-23 21:36:45 -04:00
testID: 'ElectrumConnectionEnabledSwitch',
}}
disabled={isLoading}
2024-09-26 19:21:47 -04:00
bottomDivider={false}
subtitle={loc.settings.electrum_offline_description}
2024-09-23 21:36:45 -04:00
/>
2024-09-26 19:21:47 -04:00
{!isElectrumDisabled && renderElectrumSettings()}
2024-09-23 21:36:45 -04:00
</ScrollView>
);
};
const styles = StyleSheet.create({
connectWrap: {
width: 'auto',
height: 34,
flexWrap: 'wrap',
justifyContent: 'center',
flexDirection: 'row',
},
hostname: {
textAlign: 'center',
},
container: {
paddingTop: 6,
paddingBottom: 6,
paddingLeft: 16,
paddingRight: 16,
borderRadius: 20,
},
inputWrap: {
flex: 1,
flexDirection: 'row',
borderWidth: 1,
borderBottomWidth: 0.5,
minHeight: 44,
height: 44,
alignItems: 'center',
borderRadius: 4,
},
portWrap: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
inputText: {
flex: 1,
marginHorizontal: 8,
minHeight: 36,
height: 36,
},
textConnectionStatus: {
fontWeight: 'bold',
},
usePort: {
marginHorizontal: 16,
},
});
export default ElectrumSettings;