diff --git a/nym-connect/desktop/src/components/CustomTitleBar.tsx b/nym-connect/desktop/src/components/CustomTitleBar.tsx index 88235e6074..5baa05c5b0 100644 --- a/nym-connect/desktop/src/components/CustomTitleBar.tsx +++ b/nym-connect/desktop/src/components/CustomTitleBar.tsx @@ -39,7 +39,8 @@ const ArrowBackIcon = ({ onBack }: { onBack?: () => void }) => { return ; }; -const getTitleIcon = (path: string) => { +const getTitle = (path: string) => { + if (path.includes('settings')) return 'Settings'; if (path !== '/') { const title = path.split('/').slice(-1); return ( @@ -61,7 +62,7 @@ export const CustomTitleBar = ({ path = '/', onBack }: { path?: string; onBack?: {/* set width to keep logo centered */} {path === '/' ? : } - {getTitleIcon(path)} + {getTitle(path)} appWindow.minimize()} /> appWindow.close()} /> diff --git a/nym-connect/desktop/src/context/main.tsx b/nym-connect/desktop/src/context/main.tsx index a933a8c36f..2efdc49289 100644 --- a/nym-connect/desktop/src/context/main.tsx +++ b/nym-connect/desktop/src/context/main.tsx @@ -25,6 +25,7 @@ export type TClientContext = { selectedProvider?: ServiceProvider; showInfoModal: boolean; userDefinedGateway?: UserDefinedGateway; + serviceProviders?: ServiceProvider[]; setMode: (mode: ModeType) => void; clearError: () => void; setConnectionStatus: (connectionStatus: ConnectionStatusKind) => void; @@ -165,6 +166,7 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { showInfoModal, setConnectionStats, selectedProvider, + serviceProviders, connectedSince, setConnectedSince, setRandomSerivceProvider, @@ -180,6 +182,7 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { appVersion, error, showInfoModal, + serviceProviders, connectedSince, connectionStatus, connectionStats, diff --git a/nym-connect/desktop/src/pages/menu/settings/GatewaySettings.tsx b/nym-connect/desktop/src/pages/menu/settings/GatewaySettings.tsx index c273a8a007..80efa7988a 100644 --- a/nym-connect/desktop/src/pages/menu/settings/GatewaySettings.tsx +++ b/nym-connect/desktop/src/pages/menu/settings/GatewaySettings.tsx @@ -6,7 +6,7 @@ import { ConnectionStatusKind } from 'src/types'; import { AppVersion } from 'src/components/AppVersion'; export const GatewaySettings = () => { - const { userDefinedGateway, setUserDefinedGateway } = useClientContext(); + const { userDefinedGateway, setUserDefinedGateway, connectionStatus } = useClientContext(); const [gatewayKey, setGatewayKey] = useState(userDefinedGateway?.gateway); const handleIsValidGatewayKey = (isValid: boolean) => { @@ -23,8 +23,6 @@ export const GatewaySettings = () => { setUserDefinedGateway((current) => ({ ...current, isActive: e.target.checked })); }; - const { connectionStatus } = useClientContext(); - return ( @@ -60,6 +58,7 @@ export const GatewaySettings = () => { onValidate={handleIsValidGatewayKey} sx={{ mt: 1 }} disabled={connectionStatus === 'connected' || !userDefinedGateway?.isActive} + autoFocus /> )} diff --git a/nym-connect/desktop/src/pages/menu/settings/ServiceProviderSettings.tsx b/nym-connect/desktop/src/pages/menu/settings/ServiceProviderSettings.tsx new file mode 100644 index 0000000000..8906c67129 --- /dev/null +++ b/nym-connect/desktop/src/pages/menu/settings/ServiceProviderSettings.tsx @@ -0,0 +1,85 @@ +import React, { ChangeEvent, useState } from 'react'; +import { + Autocomplete, + Box, + FormControl, + FormControlLabel, + FormHelperText, + Stack, + Switch, + TextField, + Typography, +} from '@mui/material'; +import { AppVersion } from 'src/components/AppVersion'; +import { ConnectionStatusKind } from 'src/types'; +import { useClientContext } from 'src/context/main'; + +export const ServiceProviderSettings = () => { + const [spAddress, setSPAddress] = useState(); + const [isOn, setIsOn] = useState(false); + + const { connectionStatus, serviceProviders } = useClientContext(); + + const toggleOnOff = (e: ChangeEvent) => { + if (!isOn) setSPAddress(undefined); + setIsOn(e.target.checked); + }; + + const handleSelectFromList = (value: string | null) => { + setSPAddress(value ?? undefined); + }; + + return ( + + + + + Select your Service Provider + + + Pick a service provider from the list or enter your own + + + + } + label={isOn ? 'On' : 'Off'} + /> + {connectionStatus === ConnectionStatusKind.connected && ( + This setting is disabled during an active connection + )} + {isOn && serviceProviders && ( + `${sp.address.substring(0, 20)}...`)} + freeSolo + onChange={(e, value) => handleSelectFromList(value)} + value={spAddress} + size="small" + renderInput={(params) => ( + console.log(e.target.value)} + placeholder="Service provider" + /> + )} + ListboxProps={{ style: { background: 'unset', fontSize: '14px' } }} + /> + )} + + + + + + ); +}; diff --git a/nym-connect/desktop/src/pages/menu/settings/index.tsx b/nym-connect/desktop/src/pages/menu/settings/index.tsx index edd1050272..bc58b69f1b 100644 --- a/nym-connect/desktop/src/pages/menu/settings/index.tsx +++ b/nym-connect/desktop/src/pages/menu/settings/index.tsx @@ -4,7 +4,10 @@ import { Link, List, ListItem, ListItemButton, ListItemText, Stack } from '@mui/ import { AppVersion } from 'src/components/AppVersion'; import { toggleLogViewer } from 'src/utils'; -const menuSchema = [{ title: 'Select your gateway', path: 'gateway' }]; +const menuSchema = [ + { title: 'Select your gateway', path: 'gateway' }, + { title: 'Select a service provider', path: 'service-provider' }, +]; export const SettingsMenu = () => ( diff --git a/nym-connect/desktop/src/routes/index.tsx b/nym-connect/desktop/src/routes/index.tsx index aaf09fac16..dd3eec678e 100644 --- a/nym-connect/desktop/src/routes/index.tsx +++ b/nym-connect/desktop/src/routes/index.tsx @@ -6,6 +6,7 @@ import { CompatibleApps } from 'src/pages/menu/Apps'; import { HelpGuide } from 'src/pages/menu/Guide'; import { SettingsMenu } from 'src/pages/menu/settings'; import { GatewaySettings } from 'src/pages/menu/settings/GatewaySettings'; +import { ServiceProviderSettings } from 'src/pages/menu/settings/ServiceProviderSettings'; export const AppRoutes = () => ( @@ -17,6 +18,7 @@ export const AppRoutes = () => ( } /> } /> + } /> diff --git a/ts-packages/react-components/src/components/mixnodes/IdentityKeyFormField.tsx b/ts-packages/react-components/src/components/mixnodes/IdentityKeyFormField.tsx index 4417bbffe5..692e666fe7 100644 --- a/ts-packages/react-components/src/components/mixnodes/IdentityKeyFormField.tsx +++ b/ts-packages/react-components/src/components/mixnodes/IdentityKeyFormField.tsx @@ -22,6 +22,7 @@ export const IdentityKeyFormField: FCWithChildren<{ size?: 'small' | 'medium'; sx?: SxProps; disabled?: boolean; + autoFocus?: boolean; }> = ({ required, fullWidth, @@ -37,6 +38,7 @@ export const IdentityKeyFormField: FCWithChildren<{ showTickOnValid = true, size, disabled, + autoFocus, }) => { const [value, setValue] = React.useState(initialValue); const [validationError, setValidationError] = React.useState(); @@ -106,6 +108,7 @@ export const IdentityKeyFormField: FCWithChildren<{ InputLabelProps={{ shrink: true }} size={size} disabled={disabled} + autoFocus={autoFocus} /> ); };