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}
/>
);
};