feat(nc-desktop): use userdata storage to save user gateway&sp
This commit is contained in:
@@ -115,4 +115,4 @@
|
||||
"webpack-merge": "^5.8.0",
|
||||
"yaml-loader": "^0.8.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ mod template;
|
||||
mod upgrade;
|
||||
mod user_data;
|
||||
|
||||
pub use user_data::PrivacyLevel;
|
||||
pub use user_data::UserData;
|
||||
pub use user_data::*;
|
||||
// pub use user_data::UserData;
|
||||
|
||||
static SOCKS5_CONFIG_ID: &str = "nym-connect";
|
||||
|
||||
|
||||
@@ -14,6 +14,18 @@ pub enum PrivacyLevel {
|
||||
Medium,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
pub struct SelectedGateway {
|
||||
address: Option<String>,
|
||||
is_active: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
pub struct SelectedSp {
|
||||
address: Option<String>,
|
||||
is_active: Option<bool>,
|
||||
}
|
||||
|
||||
// User data is read from and write on disk
|
||||
// Linux: $XDG_DATA_HOME or $HOME/.local/share/
|
||||
// macOS: $HOME/Library/Application Support
|
||||
@@ -22,6 +34,8 @@ pub enum PrivacyLevel {
|
||||
pub struct UserData {
|
||||
pub monitoring: Option<bool>,
|
||||
pub privacy_level: Option<PrivacyLevel>,
|
||||
pub selected_gateway: Option<SelectedGateway>,
|
||||
pub selected_sp: Option<SelectedSp>,
|
||||
}
|
||||
|
||||
fn create_directory_path() -> Result<()> {
|
||||
|
||||
@@ -74,6 +74,8 @@ fn main() {
|
||||
crate::operations::common::get_user_data,
|
||||
crate::operations::common::set_monitoring,
|
||||
crate::operations::common::set_privacy_level,
|
||||
crate::operations::common::set_selected_gateway,
|
||||
crate::operations::common::set_selected_sp,
|
||||
crate::operations::connection::connect::get_gateway,
|
||||
crate::operations::connection::connect::get_service_provider,
|
||||
crate::operations::connection::connect::set_gateway,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::config::PrivacyLevel;
|
||||
use crate::config::{PrivacyLevel, SelectedGateway, SelectedSp};
|
||||
use crate::error::Result;
|
||||
use crate::{config::UserData, state::State};
|
||||
use std::env;
|
||||
@@ -36,3 +36,21 @@ pub async fn set_privacy_level(
|
||||
let mut guard = state.write().await;
|
||||
guard.set_privacy_level(privacy_level)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn set_selected_gateway(
|
||||
gateway: Option<SelectedGateway>,
|
||||
state: tauri::State<'_, Arc<RwLock<State>>>,
|
||||
) -> Result<()> {
|
||||
let mut guard = state.write().await;
|
||||
guard.set_user_selected_gateway(gateway)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn set_selected_sp(
|
||||
service_provider: Option<SelectedSp>,
|
||||
state: tauri::State<'_, Arc<RwLock<State>>>,
|
||||
) -> Result<()> {
|
||||
let mut guard = state.write().await;
|
||||
guard.set_user_selected_sp(service_provider)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ use tokio::time::Instant;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::config::PrivacyLevel;
|
||||
use crate::config::SelectedGateway;
|
||||
use crate::config::SelectedSp;
|
||||
use crate::config::UserData;
|
||||
use crate::{
|
||||
config::{self, socks5_config_id_appended_with},
|
||||
@@ -120,6 +122,22 @@ impl State {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_user_selected_gateway(&mut self, gateway: Option<SelectedGateway>) -> Result<()> {
|
||||
self.user_data.selected_gateway = gateway;
|
||||
self.user_data.write().map_err(|e| {
|
||||
error!("Failed to write user data to disk {e}");
|
||||
BackendError::UserDataWriteError
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_user_selected_sp(&mut self, service_provider: Option<SelectedSp>) -> Result<()> {
|
||||
self.user_data.selected_sp = service_provider;
|
||||
self.user_data.write().map_err(|e| {
|
||||
error!("Failed to write user data to disk {e}");
|
||||
BackendError::UserDataWriteError
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_gateway_connectivity(&mut self, gateway_connectivity: GatewayConnectivity) {
|
||||
self.gateway_connectivity = gateway_connectivity
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ export const AppWindowFrame: FCWithChildren = ({ children }) => {
|
||||
return () => {
|
||||
// when the user moves away from the settings page and the gateway is not valid
|
||||
// set isActive to false
|
||||
if (!userDefinedGateway?.gateway) {
|
||||
if (!userDefinedGateway?.address) {
|
||||
setUserDefinedGateway((current) => ({ ...current, isActive: false }));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6,15 +6,11 @@ import { getVersion } from '@tauri-apps/api/app';
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { useEvents } from 'src/hooks/events';
|
||||
import { UserDefinedGateway, UserDefinedSPAddress } from 'src/types/service-provider';
|
||||
import { getItemFromStorage, setItemInStorage } from 'src/utils';
|
||||
import { ConnectionStatusKind, GatewayPerformance, PrivacyLevel, UserData } from '../types';
|
||||
import { ConnectionStatsItem } from '../components/ConnectionStats';
|
||||
import { ServiceProvider, Gateway } from '../types/directory';
|
||||
import initSentry from '../sentry';
|
||||
|
||||
const FORAGE_GATEWAY_KEY = 'nym-connect-user-gateway';
|
||||
const FORAGE_SP_KEY = 'nym-connect-user-sp';
|
||||
|
||||
type ModeType = 'light' | 'dark';
|
||||
|
||||
export type TClientContext = {
|
||||
@@ -72,7 +68,7 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => {
|
||||
const [showInfoModal, setShowInfoModal] = useState(false);
|
||||
const [userDefinedGateway, setUserDefinedGateway] = useState<UserDefinedGateway>({
|
||||
isActive: false,
|
||||
gateway: undefined,
|
||||
address: undefined,
|
||||
});
|
||||
const [userDefinedSPAddress, setUserDefinedSPAddress] = useState<UserDefinedSPAddress>({
|
||||
isActive: false,
|
||||
@@ -92,6 +88,15 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => {
|
||||
data.privacy_level = 'High';
|
||||
}
|
||||
setUserData(data);
|
||||
if (data.selected_gateway) {
|
||||
setUserDefinedGateway({
|
||||
address: data.selected_gateway.address,
|
||||
isActive: data.selected_gateway.is_active || false,
|
||||
});
|
||||
}
|
||||
if (data.selected_sp) {
|
||||
setUserDefinedSPAddress({ address: data.selected_sp.address, isActive: data.selected_sp.is_active || false });
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
@@ -107,30 +112,35 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setItemInStorage({ key: FORAGE_GATEWAY_KEY, value: userDefinedGateway });
|
||||
const saveUserGateway = async () => {
|
||||
console.log('******** SAVE GATEWAY');
|
||||
console.log(userDefinedGateway);
|
||||
await invoke('set_selected_gateway', {
|
||||
gateway: { address: userDefinedGateway.address, is_active: userDefinedGateway.isActive },
|
||||
});
|
||||
};
|
||||
saveUserGateway();
|
||||
}, [userDefinedGateway]);
|
||||
|
||||
useEffect(() => {
|
||||
setItemInStorage({ key: FORAGE_SP_KEY, value: userDefinedSPAddress });
|
||||
const saveUserServiceProvider = async () => {
|
||||
console.log('******** SAVE SP');
|
||||
console.log(userDefinedSPAddress);
|
||||
await invoke('set_selected_sp', {
|
||||
serviceProvider: { address: userDefinedSPAddress.address, is_active: userDefinedSPAddress.isActive },
|
||||
});
|
||||
};
|
||||
saveUserServiceProvider();
|
||||
}, [userDefinedSPAddress]);
|
||||
|
||||
const initialiseApp = async () => {
|
||||
const fetchedServices = await invoke<ServiceProvider[]>('get_services');
|
||||
const fetchedGateways = await invoke<Gateway[]>('get_gateways');
|
||||
const AppVersion = await getAppVersion();
|
||||
const storedUserDefinedGateway = await getItemFromStorage({ key: FORAGE_GATEWAY_KEY });
|
||||
const storedUserDefinedSP = await getItemFromStorage({ key: FORAGE_SP_KEY });
|
||||
|
||||
setAppVersion(AppVersion);
|
||||
setServiceProviders(fetchedServices);
|
||||
setGateways(fetchedGateways);
|
||||
|
||||
if (storedUserDefinedGateway) {
|
||||
setUserDefinedGateway(storedUserDefinedGateway);
|
||||
}
|
||||
if (storedUserDefinedSP) {
|
||||
setUserDefinedSPAddress(storedUserDefinedSP);
|
||||
}
|
||||
};
|
||||
|
||||
useEvents({
|
||||
@@ -179,7 +189,7 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const shouldUseUserGateway = !!userDefinedGateway.gateway && userDefinedGateway.isActive;
|
||||
const shouldUseUserGateway = !!userDefinedGateway.address && userDefinedGateway.isActive;
|
||||
const shouldUseUserSP = !!userDefinedSPAddress.address && userDefinedSPAddress.isActive;
|
||||
|
||||
const buildServiceProvider = async (serviceProvider: ServiceProvider) => {
|
||||
@@ -190,7 +200,7 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => {
|
||||
|
||||
const buildGateway = async (gateway: Gateway) => {
|
||||
const gw = { ...gateway };
|
||||
if (shouldUseUserGateway) gw.identity = userDefinedGateway.gateway as string;
|
||||
if (shouldUseUserGateway) gw.identity = userDefinedGateway.address as string;
|
||||
return gw;
|
||||
};
|
||||
|
||||
@@ -211,7 +221,7 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => {
|
||||
const randomGateway = getRandomFromList(gateways);
|
||||
const withUserDefinitions = await buildGateway(randomGateway);
|
||||
await invoke('set_gateway', {
|
||||
gateway: shouldUseUserGateway ? userDefinedGateway.gateway : withUserDefinitions.identity,
|
||||
gateway: shouldUseUserGateway ? userDefinedGateway.address : withUserDefinitions.identity,
|
||||
});
|
||||
setSelectedGateway(withUserDefinitions);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ const mockValues: TClientContext = {
|
||||
selectedProvider: { id: '1', description: 'Keybase service provider', address: '123abc' },
|
||||
gatewayPerformance: 'Good',
|
||||
showInfoModal: false,
|
||||
userDefinedGateway: { isActive: false, gateway: '' },
|
||||
userDefinedGateway: { isActive: false, address: '' },
|
||||
userDefinedSPAddress: { isActive: false, address: '' },
|
||||
userData: { monitoring: false, privacy_level: 'High' },
|
||||
showFeedbackNote: false,
|
||||
|
||||
@@ -7,7 +7,7 @@ import { AppVersion } from 'src/components/AppVersion';
|
||||
|
||||
export const GatewaySettings = () => {
|
||||
const { userDefinedGateway, setUserDefinedGateway, connectionStatus } = useClientContext();
|
||||
const [gatewayKey, setGatewayKey] = useState<string | undefined>(userDefinedGateway?.gateway);
|
||||
const [gatewayKey, setGatewayKey] = useState<string | undefined>(userDefinedGateway?.address);
|
||||
|
||||
const handleIsValidGatewayKey = (isValid: boolean) => {
|
||||
let gateway: string | undefined;
|
||||
@@ -16,7 +16,7 @@ export const GatewaySettings = () => {
|
||||
gateway = gatewayKey;
|
||||
}
|
||||
|
||||
setUserDefinedGateway((current) => ({ ...current, gateway }));
|
||||
setUserDefinedGateway((current) => ({ ...current, address: gateway }));
|
||||
};
|
||||
|
||||
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export interface UserDefinedGateway {
|
||||
isActive: boolean;
|
||||
gateway?: string;
|
||||
address?: string;
|
||||
}
|
||||
|
||||
export interface UserDefinedSPAddress {
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
export type PrivacyLevel = 'High' | 'Medium';
|
||||
|
||||
export type SelectedGateway = {
|
||||
address?: string;
|
||||
is_active?: boolean;
|
||||
};
|
||||
|
||||
export type SelectedSp = {
|
||||
address?: string;
|
||||
is_active?: boolean;
|
||||
};
|
||||
|
||||
export type UserData = {
|
||||
monitoring?: boolean;
|
||||
privacy_level?: PrivacyLevel;
|
||||
selected_gateway?: SelectedGateway;
|
||||
selected_sp?: SelectedSp;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user