refactor (ldk): extract shared VssServerPicker component
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
import * as React from 'react';
|
||||
import { Text, View } from 'react-native';
|
||||
|
||||
import DropdownSetting from './DropdownSetting';
|
||||
import TextInput from './TextInput';
|
||||
|
||||
import { LDK_VSS_SERVER_KEYS } from '../stores/SettingsStore';
|
||||
|
||||
import { localeString } from '../utils/LocaleUtils';
|
||||
import { themeColor } from '../utils/ThemeUtils';
|
||||
import UrlUtils from '../utils/UrlUtils';
|
||||
import { DEFAULT_VSS_SERVER } from '../utils/LdkNodeUtils';
|
||||
|
||||
export const VSS_CUSTOM_VALUE = 'custom';
|
||||
|
||||
interface VssServerPickerProps {
|
||||
selectedValue: string;
|
||||
customServer: string;
|
||||
onChange: (selectedValue: string, customServer: string) => void;
|
||||
locked?: boolean;
|
||||
}
|
||||
|
||||
export const resolveVssServer = (
|
||||
selectedValue: string,
|
||||
customServer: string
|
||||
): string =>
|
||||
selectedValue === VSS_CUSTOM_VALUE ? customServer.trim() : selectedValue;
|
||||
|
||||
export const isVssServerValid = (
|
||||
selectedValue: string,
|
||||
customServer: string
|
||||
): boolean => {
|
||||
if (selectedValue !== VSS_CUSTOM_VALUE) return true;
|
||||
const trimmed = customServer.trim();
|
||||
return trimmed !== '' && UrlUtils.isValidUrl(trimmed);
|
||||
};
|
||||
|
||||
export default function VssServerPicker({
|
||||
selectedValue,
|
||||
customServer,
|
||||
onChange,
|
||||
locked
|
||||
}: VssServerPickerProps) {
|
||||
const isCustom = selectedValue === VSS_CUSTOM_VALUE;
|
||||
const showInvalidUrlError =
|
||||
isCustom &&
|
||||
customServer.trim() !== '' &&
|
||||
!UrlUtils.isValidUrl(customServer);
|
||||
|
||||
return (
|
||||
<View>
|
||||
<DropdownSetting
|
||||
title={localeString(
|
||||
'views.Settings.EmbeddedNode.VssServer.serverUrl'
|
||||
)}
|
||||
selectedValue={selectedValue}
|
||||
onValueChange={(value: string) =>
|
||||
onChange(
|
||||
value,
|
||||
value === VSS_CUSTOM_VALUE ? customServer : ''
|
||||
)
|
||||
}
|
||||
values={LDK_VSS_SERVER_KEYS}
|
||||
disabled={locked}
|
||||
/>
|
||||
|
||||
{isCustom && (
|
||||
<>
|
||||
<TextInput
|
||||
value={customServer}
|
||||
placeholder={DEFAULT_VSS_SERVER}
|
||||
onChangeText={(text: string) =>
|
||||
onChange(selectedValue, text)
|
||||
}
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
locked={locked}
|
||||
/>
|
||||
{showInvalidUrlError && (
|
||||
<Text
|
||||
style={{
|
||||
color: themeColor('error'),
|
||||
fontFamily: 'PPNeueMontreal-Book',
|
||||
fontSize: 12,
|
||||
marginTop: 4
|
||||
}}
|
||||
>
|
||||
{localeString(
|
||||
'views.Settings.EmbeddedNode.invalidServerUrl'
|
||||
)}
|
||||
</Text>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -4,10 +4,13 @@ import { inject, observer } from 'mobx-react';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
|
||||
import Button from '../../../components/Button';
|
||||
import DropdownSetting from '../../../components/DropdownSetting';
|
||||
import Header from '../../../components/Header';
|
||||
import Screen from '../../../components/Screen';
|
||||
import TextInput from '../../../components/TextInput';
|
||||
import VssServerPicker, {
|
||||
VSS_CUSTOM_VALUE,
|
||||
resolveVssServer,
|
||||
isVssServerValid
|
||||
} from '../../../components/VssServerPicker';
|
||||
|
||||
import SettingsStore, {
|
||||
LDK_VSS_SERVER_KEYS
|
||||
@@ -16,11 +19,8 @@ import SettingsStore, {
|
||||
import { localeString } from '../../../utils/LocaleUtils';
|
||||
import { restartNeeded } from '../../../utils/RestartUtils';
|
||||
import { themeColor } from '../../../utils/ThemeUtils';
|
||||
import UrlUtils from '../../../utils/UrlUtils';
|
||||
import { DEFAULT_VSS_SERVER } from '../../../utils/LdkNodeUtils';
|
||||
|
||||
const CUSTOM_VALUE = 'custom';
|
||||
|
||||
interface VssServerProps {
|
||||
navigation: NativeStackNavigationProp<any, any>;
|
||||
SettingsStore: SettingsStore;
|
||||
@@ -48,19 +48,12 @@ export default class VssServer extends React.Component<
|
||||
const isPreset = presetValues.includes(saved);
|
||||
|
||||
return {
|
||||
selectedValue: isPreset ? saved : CUSTOM_VALUE,
|
||||
selectedValue: isPreset ? saved : VSS_CUSTOM_VALUE,
|
||||
customServer: isPreset ? '' : saved,
|
||||
savedVssServer: saved
|
||||
};
|
||||
})();
|
||||
|
||||
getEffectiveServer = (): string => {
|
||||
const { selectedValue, customServer } = this.state;
|
||||
return selectedValue === CUSTOM_VALUE
|
||||
? customServer.trim()
|
||||
: selectedValue;
|
||||
};
|
||||
|
||||
saveSettings = async (server: string) => {
|
||||
const { SettingsStore } = this.props;
|
||||
const { settings, updateSettings } = SettingsStore;
|
||||
@@ -81,17 +74,12 @@ export default class VssServer extends React.Component<
|
||||
const { navigation } = this.props;
|
||||
const { selectedValue, customServer, savedVssServer } = this.state;
|
||||
|
||||
const isCustom = selectedValue === CUSTOM_VALUE;
|
||||
const effectiveServer = this.getEffectiveServer();
|
||||
const customServerTrimmed = customServer.trim();
|
||||
const showInvalidUrlError =
|
||||
isCustom &&
|
||||
customServerTrimmed !== '' &&
|
||||
!UrlUtils.isValidUrl(customServer);
|
||||
const effectiveServer = resolveVssServer(selectedValue, customServer);
|
||||
const isValid = isVssServerValid(selectedValue, customServer);
|
||||
const hasUnsavedChanges =
|
||||
isValid &&
|
||||
effectiveServer !== '' &&
|
||||
effectiveServer !== savedVssServer &&
|
||||
!showInvalidUrlError;
|
||||
effectiveServer !== savedVssServer;
|
||||
const showReset = effectiveServer !== DEFAULT_VSS_SERVER;
|
||||
|
||||
return (
|
||||
@@ -125,51 +113,17 @@ export default class VssServer extends React.Component<
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<DropdownSetting
|
||||
title={localeString(
|
||||
'views.Settings.EmbeddedNode.VssServer.serverUrl'
|
||||
)}
|
||||
<VssServerPicker
|
||||
selectedValue={selectedValue}
|
||||
onValueChange={(value: string) => {
|
||||
customServer={customServer}
|
||||
onChange={(value, custom) =>
|
||||
this.setState({
|
||||
selectedValue: value,
|
||||
customServer:
|
||||
value === CUSTOM_VALUE
|
||||
? customServer
|
||||
: ''
|
||||
});
|
||||
}}
|
||||
values={LDK_VSS_SERVER_KEYS}
|
||||
customServer: custom
|
||||
})
|
||||
}
|
||||
/>
|
||||
|
||||
{isCustom && (
|
||||
<>
|
||||
<TextInput
|
||||
value={customServer}
|
||||
placeholder={DEFAULT_VSS_SERVER}
|
||||
onChangeText={(text: string) => {
|
||||
this.setState({ customServer: text });
|
||||
}}
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
/>
|
||||
{showInvalidUrlError && (
|
||||
<Text
|
||||
style={{
|
||||
color: themeColor('error'),
|
||||
fontFamily: 'PPNeueMontreal-Book',
|
||||
fontSize: 12,
|
||||
marginTop: 4
|
||||
}}
|
||||
>
|
||||
{localeString(
|
||||
'views.Settings.EmbeddedNode.invalidServerUrl'
|
||||
)}
|
||||
</Text>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
<View style={{ marginTop: 10 }}>
|
||||
<Text
|
||||
style={{
|
||||
|
||||
@@ -4,18 +4,17 @@ import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import { Route } from '@react-navigation/native';
|
||||
|
||||
import Button from '../../../components/Button';
|
||||
import DropdownSetting from '../../../components/DropdownSetting';
|
||||
import Header from '../../../components/Header';
|
||||
import Screen from '../../../components/Screen';
|
||||
import Text from '../../../components/Text';
|
||||
import TextInput from '../../../components/TextInput';
|
||||
|
||||
import { LDK_VSS_SERVER_KEYS } from '../../../stores/SettingsStore';
|
||||
import VssServerPicker, {
|
||||
resolveVssServer,
|
||||
isVssServerValid
|
||||
} from '../../../components/VssServerPicker';
|
||||
|
||||
import { themeColor } from '../../../utils/ThemeUtils';
|
||||
import { localeString } from '../../../utils/LocaleUtils';
|
||||
import { DEFAULT_VSS_SERVER } from '../../../utils/LdkNodeUtils';
|
||||
import UrlUtils from '../../../utils/UrlUtils';
|
||||
|
||||
interface LdkRecoveryVssServerProps {
|
||||
navigation: NativeStackNavigationProp<any, any>;
|
||||
@@ -44,14 +43,10 @@ export default class LdkRecoveryVssServer extends React.Component<
|
||||
customServer: ''
|
||||
};
|
||||
|
||||
private getEffectiveServer = (): string => {
|
||||
const { selectedValue, customServer } = this.state;
|
||||
return selectedValue === 'custom' ? customServer.trim() : selectedValue;
|
||||
};
|
||||
|
||||
private continueToRecovery = () => {
|
||||
const { navigation, route } = this.props;
|
||||
const { network, nickname, photo, wordCount } = route.params ?? {};
|
||||
const { selectedValue, customServer } = this.state;
|
||||
|
||||
navigation.navigate('SeedRecovery', {
|
||||
network,
|
||||
@@ -59,23 +54,14 @@ export default class LdkRecoveryVssServer extends React.Component<
|
||||
nickname,
|
||||
photo,
|
||||
wordCount,
|
||||
vssServer: this.getEffectiveServer() || undefined
|
||||
vssServer:
|
||||
resolveVssServer(selectedValue, customServer) || undefined
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { navigation } = this.props;
|
||||
const { selectedValue, customServer } = this.state;
|
||||
const customServerTrimmed = customServer.trim();
|
||||
|
||||
const isCustom = selectedValue === 'custom';
|
||||
|
||||
const showInvalidUrlError =
|
||||
isCustom &&
|
||||
customServerTrimmed !== '' &&
|
||||
!UrlUtils.isValidUrl(customServer);
|
||||
const disabled =
|
||||
isCustom && (customServerTrimmed === '' || showInvalidUrlError);
|
||||
|
||||
return (
|
||||
<Screen>
|
||||
@@ -104,52 +90,24 @@ export default class LdkRecoveryVssServer extends React.Component<
|
||||
)}
|
||||
</Text>
|
||||
|
||||
<DropdownSetting
|
||||
title={localeString(
|
||||
'views.Settings.EmbeddedNode.VssServer.serverUrl'
|
||||
)}
|
||||
<VssServerPicker
|
||||
selectedValue={selectedValue}
|
||||
onValueChange={(value: string) => {
|
||||
customServer={customServer}
|
||||
onChange={(value, custom) =>
|
||||
this.setState({
|
||||
selectedValue: value,
|
||||
customServer:
|
||||
value === 'custom' ? customServer : ''
|
||||
});
|
||||
}}
|
||||
values={LDK_VSS_SERVER_KEYS}
|
||||
customServer: custom
|
||||
})
|
||||
}
|
||||
/>
|
||||
|
||||
{isCustom && (
|
||||
<>
|
||||
<TextInput
|
||||
value={customServer}
|
||||
placeholder={DEFAULT_VSS_SERVER}
|
||||
onChangeText={(text: string) =>
|
||||
this.setState({ customServer: text })
|
||||
}
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
/>
|
||||
{showInvalidUrlError && (
|
||||
<Text
|
||||
style={{
|
||||
...styles.error,
|
||||
color: themeColor('error')
|
||||
}}
|
||||
>
|
||||
{localeString(
|
||||
'views.Settings.EmbeddedNode.invalidServerUrl'
|
||||
)}
|
||||
</Text>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
<View style={styles.button}>
|
||||
<Button
|
||||
title={localeString('general.next')}
|
||||
onPress={this.continueToRecovery}
|
||||
disabled={disabled}
|
||||
disabled={
|
||||
!isVssServerValid(selectedValue, customServer)
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
@@ -169,11 +127,6 @@ const styles = StyleSheet.create({
|
||||
fontSize: 15,
|
||||
marginBottom: 24
|
||||
},
|
||||
error: {
|
||||
fontFamily: 'PPNeueMontreal-Book',
|
||||
fontSize: 12,
|
||||
marginTop: 4
|
||||
},
|
||||
button: {
|
||||
marginTop: 24
|
||||
}
|
||||
|
||||
@@ -46,6 +46,9 @@ import {
|
||||
import Switch from '../../components/Switch';
|
||||
import TextInput from '../../components/TextInput';
|
||||
import Accordion from '../../components/Accordion';
|
||||
import VssServerPicker, {
|
||||
resolveVssServer
|
||||
} from '../../components/VssServerPicker';
|
||||
import { Row } from '../../components/layout/Row';
|
||||
import ShowHideToggle from '../../components/ShowHideToggle';
|
||||
|
||||
@@ -56,7 +59,6 @@ import SettingsStore, {
|
||||
INTERFACE_KEYS,
|
||||
LNC_MAILBOX_KEYS,
|
||||
EMBEDDED_NODE_NETWORK_KEYS,
|
||||
LDK_VSS_SERVER_KEYS,
|
||||
Settings,
|
||||
Node,
|
||||
Implementations,
|
||||
@@ -157,7 +159,8 @@ interface WalletConfigurationState {
|
||||
ldkRgsServer?: string;
|
||||
ldkScorerUrl?: string;
|
||||
ldkVssServer?: string;
|
||||
ldkVssServerMode: string;
|
||||
ldkVssServerSelected: string;
|
||||
ldkVssServerCustom: string;
|
||||
ldkNodeInitialized?: boolean;
|
||||
// NWC
|
||||
nostrWalletConnectUrl: string;
|
||||
@@ -240,7 +243,8 @@ export default class WalletConfiguration extends React.Component<
|
||||
ldkRgsServer: '',
|
||||
ldkScorerUrl: '',
|
||||
ldkVssServer: DEFAULT_VSS_SERVER,
|
||||
ldkVssServerMode: DEFAULT_VSS_SERVER,
|
||||
ldkVssServerSelected: DEFAULT_VSS_SERVER,
|
||||
ldkVssServerCustom: '',
|
||||
ldkNodeInitialized: false,
|
||||
// NWC
|
||||
nostrWalletConnectUrl: '',
|
||||
@@ -1231,8 +1235,8 @@ export default class WalletConfiguration extends React.Component<
|
||||
ldkMnemonic,
|
||||
ldkNetwork,
|
||||
ldkSeedWordCount,
|
||||
ldkVssServer,
|
||||
ldkVssServerMode,
|
||||
ldkVssServerSelected,
|
||||
ldkVssServerCustom,
|
||||
ldkNodeInitialized,
|
||||
// NWC
|
||||
nostrWalletConnectUrl,
|
||||
@@ -1811,44 +1815,28 @@ export default class WalletConfiguration extends React.Component<
|
||||
]}
|
||||
/>
|
||||
|
||||
<DropdownSetting
|
||||
title={localeString(
|
||||
'views.Settings.EmbeddedNode.VssServer.title'
|
||||
)}
|
||||
selectedValue={ldkVssServerMode}
|
||||
onValueChange={(
|
||||
value: string
|
||||
) => {
|
||||
<VssServerPicker
|
||||
selectedValue={
|
||||
ldkVssServerSelected
|
||||
}
|
||||
customServer={
|
||||
ldkVssServerCustom
|
||||
}
|
||||
locked={loading}
|
||||
onChange={(value, custom) =>
|
||||
this.setState({
|
||||
ldkVssServerMode: value,
|
||||
ldkVssServerSelected:
|
||||
value,
|
||||
ldkVssServerCustom:
|
||||
custom,
|
||||
ldkVssServer:
|
||||
value === 'custom'
|
||||
? ''
|
||||
: value
|
||||
});
|
||||
}}
|
||||
values={LDK_VSS_SERVER_KEYS}
|
||||
resolveVssServer(
|
||||
value,
|
||||
custom
|
||||
)
|
||||
})
|
||||
}
|
||||
/>
|
||||
|
||||
{ldkVssServerMode === 'custom' && (
|
||||
<TextInput
|
||||
placeholder={
|
||||
DEFAULT_VSS_SERVER
|
||||
}
|
||||
value={ldkVssServer}
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
onChangeText={(
|
||||
text: string
|
||||
) =>
|
||||
this.setState({
|
||||
ldkVssServer:
|
||||
text.trim()
|
||||
})
|
||||
}
|
||||
locked={loading}
|
||||
/>
|
||||
)}
|
||||
</Accordion>
|
||||
</View>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user