Skip to content

Commit

Permalink
feat(desktop): save window size on resize (#309)
Browse files Browse the repository at this point in the history
  • Loading branch information
doums authored Apr 19, 2024
1 parent 76b79dd commit 38cd55f
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 8 deletions.
2 changes: 1 addition & 1 deletion nym-vpn-desktop/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ tauri-build = { version = "1.5", features = [] }
build-info-build = "0.0.34"

[dependencies]
tauri = { version = "1.6.0", features = [ "os-all", "updater", "process-all", "shell-open"] }
tauri = { version = "1.6.0", features = [ "window-set-size", "os-all", "updater", "process-all", "shell-open"] }
tokio = { version = "1.33", features = ["rt", "sync", "time", "fs"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Expand Down
2 changes: 2 additions & 0 deletions nym-vpn-desktop/src-tauri/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ pub enum Key {
EntryNodeLocation,
#[strum(serialize = "exit_node_location")]
ExitNodeLocation,
#[strum(serialize = "window_size")]
WindowSize,
}

impl Display for Key {
Expand Down
3 changes: 2 additions & 1 deletion nym-vpn-desktop/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"all": false,
"process": { "all": true },
"shell": { "all": false, "open": true },
"os": { "all": true }
"os": { "all": true },
"window": { "setSize": true }
},
"bundle": {
"active": true,
Expand Down
15 changes: 15 additions & 0 deletions nym-vpn-desktop/src/state/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { appWindow } from '@tauri-apps/api/window';
import { DefaultRootFontSize, DefaultThemeMode } from '../constants';
import { getJsLicenses, getRustLicenses } from '../data';
import { kvGet } from '../kvStore';
import logu from '../log';
import {
CodeDependency,
ConnectionState,
Expand All @@ -13,6 +14,7 @@ import {
ThemeMode,
UiTheme,
VpnMode,
WindowSize,
} from '../types';
import fireRequests, { TauriReq } from './helper';

Expand Down Expand Up @@ -206,6 +208,18 @@ async function init(dispatch: StateDispatch) {
},
};

const getWindowSizeRq: TauriReq<() => Promise<WindowSize | undefined>> = {
name: 'getWindowSize',
request: () => kvGet<WindowSize>('WindowSize'),
onFulfilled: (size) => {
if (size) {
appWindow.setSize(size);
dispatch({ type: 'set-window-size', size });
logu.debug(`restored window size to ${size.width}x${size.height}`);
}
},
};

const getDepsRustRq: TauriReq<() => Promise<CodeDependency[] | undefined>> = {
name: 'getDepsRustRq',
request: () => getRustLicenses(),
Expand Down Expand Up @@ -245,6 +259,7 @@ async function init(dispatch: StateDispatch) {
getMonitoringRq,
getDepsRustRq,
getDepsJsRq,
getWindowSizeRq,
]);
}

Expand Down
9 changes: 8 additions & 1 deletion nym-vpn-desktop/src/state/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
ThemeMode,
UiTheme,
VpnMode,
WindowSize,
} from '../types';

export type StateAction =
Expand Down Expand Up @@ -48,7 +49,8 @@ export type StateAction =
| { type: 'set-fastest-node-location'; country: Country }
| { type: 'set-root-font-size'; size: number }
| { type: 'set-code-deps-js'; dependencies: CodeDependency[] }
| { type: 'set-code-deps-rust'; dependencies: CodeDependency[] };
| { type: 'set-code-deps-rust'; dependencies: CodeDependency[] }
| { type: 'set-window-size'; size: WindowSize };

export const initialState: AppState = {
initialized: false,
Expand Down Expand Up @@ -226,6 +228,11 @@ export function reducer(state: AppState, action: StateAction): AppState {
...state,
codeDepsRust: action.dependencies,
};
case 'set-window-size':
return {
...state,
windowSize: action.size,
};

case 'reset':
return initialState;
Expand Down
2 changes: 1 addition & 1 deletion nym-vpn-desktop/src/state/provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type Props = {
export function MainStateProvider({ children }: Props) {
const [state, dispatch] = useReducer(reducer, initialState);

useTauriEvents(dispatch);
useTauriEvents(dispatch, state);

// initialize app state
useEffect(() => {
Expand Down
34 changes: 31 additions & 3 deletions nym-vpn-desktop/src/state/useTauriEvents.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import * as _ from 'lodash-es';
import { useCallback, useEffect } from 'react';
import { listen } from '@tauri-apps/api/event';
import { appWindow } from '@tauri-apps/api/window';
import { EventCallback, listen } from '@tauri-apps/api/event';
import { PhysicalSize, appWindow } from '@tauri-apps/api/window';
import dayjs from 'dayjs';
import { kvSet } from '../kvStore';
import {
AppState,
ConnectionEventPayload,
ProgressEventPayload,
StateDispatch,
WindowSize,
} from '../types';
import { ConnectionEvent, ProgressEvent } from '../constants';

Expand All @@ -18,7 +22,7 @@ function handleError(dispatch: StateDispatch, error?: string | null) {
dispatch({ type: 'set-error', error });
}

export function useTauriEvents(dispatch: StateDispatch) {
export function useTauriEvents(dispatch: StateDispatch, state: AppState) {
const registerStateListener = useCallback(() => {
return listen<ConnectionEventPayload>(ConnectionEvent, (event) => {
console.log(
Expand Down Expand Up @@ -74,20 +78,44 @@ export function useTauriEvents(dispatch: StateDispatch) {
});
}, [dispatch]);

const registerWindowResizedListener = useCallback(() => {
return appWindow.onResized(
_.debounce<EventCallback<PhysicalSize>>(
({ payload }) => {
if (
payload.width !== state.windowSize?.width ||
payload.height !== state.windowSize?.height
) {
kvSet<WindowSize>('WindowSize', payload);
dispatch({ type: 'set-window-size', size: payload });
}
},
200,
{
leading: false,
trailing: true,
},
),
);
}, [dispatch, state.windowSize]);

// register/unregister event listener
useEffect(() => {
const unlistenState = registerStateListener();
const unlistenProgress = registerProgressListener();
const unlistenThemeChanges = registerThemeChangedListener();
const unlistenWindowResized = registerWindowResizedListener();

return () => {
unlistenState.then((f) => f());
unlistenProgress.then((f) => f());
unlistenThemeChanges.then((f) => f());
unlistenWindowResized.then((f) => f());
};
}, [
registerStateListener,
registerProgressListener,
registerThemeChangedListener,
registerWindowResizedListener,
]);
}
4 changes: 4 additions & 0 deletions nym-vpn-desktop/src/types/app-state.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PhysicalSize } from '@tauri-apps/api/window';
import { Dispatch } from 'react';
import { Dayjs } from 'dayjs';
import { StateAction } from '../state';
Expand Down Expand Up @@ -27,6 +28,8 @@ export type CodeDependency = {
copyright?: string;
};

export type WindowSize = PhysicalSize;

export type AppState = {
// initial loading phase when the app is starting and fetching data from the backend
initialized: boolean;
Expand Down Expand Up @@ -54,6 +57,7 @@ export type AppState = {
rootFontSize: number;
codeDepsJs: CodeDependency[];
codeDepsRust: CodeDependency[];
windowSize?: WindowSize | null;
};

export type ConnectionEventPayload = {
Expand Down
3 changes: 2 additions & 1 deletion nym-vpn-desktop/src/types/tauri-ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ export type DbKey =
| 'UiRootFontSize'
| 'VpnMode'
| 'EntryNodeLocation'
| 'ExitNodeLocation';
| 'ExitNodeLocation'
| 'WindowSize';

0 comments on commit 38cd55f

Please sign in to comment.