feat(gui, tauri): Save settings in Tauri storage (#102)

- Implemented dual persistence strategy:
  - **User Settings**: Persisted across app restarts using `tauri-plugin-store`.
  - **Transient State**: Persisted across page reloads using `sessionStorage`.
- Added `settingsSlice` reducer for managing persistent user settings.
- Updated Redux store configuration to handle multiple persistence layers.
- Added a new Settings page in the GUI where users can specify custom Electrum RPC URLs for Bitcoin and Monero node URLs.
  - Users can input their preferred Electrum server (`ssl://host:port`) and Monero daemon (`http://host:port`).
  - Input fields include validation to ensure correct URL formats.
  - Settings persist across application restarts using Tauri's storage plugin.
  - A reset option is available to revert to default settings.
- Improved the Daemon Controller in the Help page:
  - Renamed `RpcControlBox` to `DaemonControlBox` for clarity.
  - Users can now start the daemon manually if it isn't running or has failed.
  - Added a "Restart GUI" button to apply new settings immediately.
  - Displayed the daemon's status within the controller.
- Upgraded Tauri and related plugins to stable version `2.0.0`:
  - Updated `tauri`, `tauri-build`, and `tauri-utils` to `2.0.0`.
  - Ensured compatibility with the latest stable release.
- Updated Tauri plugins to version `2.0.0`:
  - `tauri-plugin-clipboard-manager`
  - `tauri-plugin-shell`
  - Added new plugins:
    - `tauri-plugin-store` for settings persistence.
    - `tauri-plugin-process` to enable application relaunch.
- Deferred Context initialization until explicitly triggered from the frontend.
  - Moved Context setup from the `setup` function to a new `initialize_context` Tauri command.
  - Allows the application to start without immediately initializing the backend context.
  - Context initialization now considers user-provided settings for Electrum and Monero nodes.
- Introduced a `ValidatedTextField` component for form inputs with validation logic.
  - Provides immediate feedback on input validity.
  - Used in the Settings page for Electrum and Monero node URLs.
- If the user provides an override Monero remote daemon, we check if it reachable and on the correct network before starting the `monero-wallet-rpc`
- Changed `bitcoin_confirmation_target` type from `usize` to `u16`.
This commit is contained in:
binarybaron 2024-10-08 16:57:01 +06:00 committed by GitHub
parent d4503a6e9c
commit 253e0b0cf6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
40 changed files with 1124 additions and 451 deletions

View file

@ -3,29 +3,63 @@ import { persistReducer, persistStore } from "redux-persist";
import sessionStorage from "redux-persist/lib/storage/session";
import { reducers } from "store/combinedReducer";
import { createMainListeners } from "store/middleware/storeListener";
import { createStore } from "@tauri-apps/plugin-store";
import { getNetworkName } from "store/config";
// We persist the redux store in sessionStorage
// The point of this is to preserve the store across reloads while not persisting it across GUI restarts
//
// If the user reloads the page, while a swap is running we want to
// continue displaying the correct state of the swap
const persistConfig = {
// Goal: Maintain application state across page reloads while allowing a clean slate on application restart
// Settings are persisted across application restarts, while the rest of the state is cleared
// Persist user settings across application restarts
// We use Tauri's storage for settings to ensure they're retained even when the application is closed
const rootPersistConfig = {
key: "gui-global-state-store",
storage: sessionStorage,
blacklist: ["settings"],
};
const persistedReducer = persistReducer(
persistConfig,
combineReducers(reducers),
// Use Tauri's store plugin for persistent settings
const tauriStore = await createStore(`${getNetworkName()}_settings.bin`, {
autoSave: 1000 as unknown as boolean,
});
// Configure how settings are stored and retrieved using Tauri's storage
const settingsPersistConfig = {
key: "settings",
storage: {
getItem: (key: string) => tauriStore.get(key),
setItem: (key: string, value: unknown) => tauriStore.set(key, value),
removeItem: (key: string) => tauriStore.delete(key),
},
};
// Create a persisted version of the settings reducer
const persistedSettingsReducer = persistReducer(
settingsPersistConfig,
reducers.settings,
);
// Combine all reducers, using the persisted settings reducer
const rootReducer = combineReducers({
...reducers,
settings: persistedSettingsReducer,
});
// Enable persistence for the entire application state
const persistedReducer = persistReducer(rootPersistConfig, rootReducer);
// Set up the Redux store with persistence and custom middleware
export const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().prepend(createMainListeners().middleware),
getDefaultMiddleware({
// Disable serializable to silence warnings about non-serializable actions
serializableCheck: false,
}).prepend(createMainListeners().middleware),
});
// Create a persistor to manage the persisted store
export const persistor = persistStore(store);
// TypeScript type definitions for easier use of the store in the application
export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;
export type RootState = ReturnType<typeof store.getState>;