From 9e0ec573258e809f9986debf3b4580a4bec93034 Mon Sep 17 00:00:00 2001 From: Pushkar Mishra Date: Tue, 28 Oct 2025 13:55:23 +0530 Subject: [PATCH 1/4] Add FolderDownload icon and implement download directory selection in settings - Introduced a new FolderDownload icon component for UI. - Enhanced settings page to allow users to select and display a custom download directory. - Implemented Tauri commands to get and set the download directory, improving file management capabilities. Signed-off-by: Pushkar Mishra --- src-tauri/src/lib.rs | 117 ++++++++++++++++-- .../components/icons/FolderDownload.svelte | 15 +++ src/routes/settings/+page.svelte | 47 ++++++- 3 files changed, 170 insertions(+), 9 deletions(-) create mode 100644 src/lib/components/icons/FolderDownload.svelte diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index dc097ca..a6fe608 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -13,11 +13,16 @@ use tauri::{ use tokio::sync::mpsc; use tokio::sync::Mutex; +/// Application state shared across all Tauri commands. struct AppState { + /// Iroh instance for peer-to-peer file transfers pub iroh: IrohInstance, + /// Channel sender for internal event communication inner: Mutex>, - // Store active send bubble to keep it alive + /// Active send bubble to keep it alive during transfers active_send_bubble: Arc>>, + /// Custom download directory set by user + custom_download_dir: Mutex>, } enum Event { @@ -30,6 +35,7 @@ impl AppState { iroh, inner: Mutex::new(async_proc_input_tx), active_send_bubble: Arc::new(Mutex::new(None)), + custom_download_dir: Mutex::new(None), } } } @@ -84,6 +90,8 @@ pub fn run() { .invoke_handler(generate_handler![ generate_ticket, receive_files, + set_download_directory, + get_download_directory, open_directory, is_valid_ticket, get_env @@ -112,11 +120,28 @@ fn event_handler(message: Event, manager: &AppHandle) { } } +/// Gets an environment variable value. +/// +/// # Arguments +/// * `key` - The environment variable name +/// +/// # Returns +/// The value of the environment variable, or an empty string if not found #[tauri::command] fn get_env(key: &str) -> String { std::env::var(String::from(key)).unwrap_or(String::from("")) } +/// Generates a ticket for sending files. +/// +/// Creates a ticket that encodes the file paths and connection information, +/// which can be shared with a receiver to initiate a file transfer. +/// +/// # Arguments +/// * `paths` - List of file paths to include in the transfer +/// +/// # Returns +/// A BlobTicket containing the transfer information #[tauri::command] async fn generate_ticket( state: tauri::State<'_, AppState>, @@ -171,6 +196,16 @@ async fn generate_ticket( Ok(ticket) } +/// Receives files using a transfer ticket. +/// +/// Downloads files from a sender using the provided ticket and saves them to +/// the configured download directory. +/// +/// # Arguments +/// * `ticket` - The transfer ticket string from the sender +/// +/// # Returns +/// The path to the directory where files were saved #[tauri::command] async fn receive_files( state: tauri::State<'_, AppState>, @@ -187,12 +222,12 @@ async fn receive_files( } }); - // Determine output directory - let output_dir = if let Some(path) = dirs::download_dir() { - path - } else { - // Android download path - PathBuf::from("/storage/emulated/0/Download/") + let output_dir = { + let custom_dir = state.custom_download_dir.lock().await; + custom_dir + .clone() + .or_else(|| dirs::download_dir()) + .unwrap_or_else(|| PathBuf::from("/storage/emulated/0/Download/")) }; // Receive files with proper file writing @@ -206,14 +241,80 @@ async fn receive_files( Ok(output_dir) } +/// Sets a custom download directory for received files. +/// +/// # Arguments +/// * `path` - The filesystem path to the directory +/// +/// # Errors +/// Returns an error if the path doesn't exist or is not a directory +#[tauri::command] +async fn set_download_directory( + state: tauri::State<'_, AppState>, + path: String, +) -> Result<(), InvokeError> { + let path_buf = PathBuf::from(&path); + + if !path_buf.exists() { + return Err(InvokeError::from_anyhow(anyhow!( + "Directory does not exist: {}", + path + ))); + } + + if !path_buf.is_dir() { + return Err(InvokeError::from_anyhow(anyhow!( + "Path is not a directory: {}", + path + ))); + } + + let mut custom_dir = state.custom_download_dir.lock().await; + *custom_dir = Some(path_buf); + + Ok(()) +} + +/// Gets the current download directory. +/// +/// Returns the custom directory if set, otherwise returns the system default +/// download directory, or the Android download path as a fallback. +/// +/// # Returns +/// The absolute path to the download directory as a string +#[tauri::command] +async fn get_download_directory(state: tauri::State<'_, AppState>) -> Result { + let custom_dir = state.custom_download_dir.lock().await; + + let output_dir = custom_dir + .clone() + .or_else(|| dirs::download_dir()) + .unwrap_or_else(|| PathBuf::from("/storage/emulated/0/Download/")); + + Ok(output_dir.to_string_lossy().to_string()) +} + +/// Opens a directory in the system's file manager. +/// +/// # Arguments +/// * `directory` - Path to the directory to open +/// +/// # Errors +/// Returns an error if the directory cannot be opened #[tauri::command] fn open_directory(directory: PathBuf) -> Result<(), InvokeError> { open::that(directory).map_err(|e| InvokeError::from_anyhow(anyhow!(e))) } +/// Validates a transfer ticket format. +/// +/// # Arguments +/// * `ticket` - The ticket string to validate +/// +/// # Returns +/// `true` if the ticket is valid, `false` otherwise #[tauri::command] fn is_valid_ticket(ticket: String) -> Result { - // With ark-core, we can simply try to parse the ticket match BlobTicket::parse(&ticket) { Ok(_) => Ok(true), Err(_) => Ok(false), diff --git a/src/lib/components/icons/FolderDownload.svelte b/src/lib/components/icons/FolderDownload.svelte new file mode 100644 index 0000000..cd9d357 --- /dev/null +++ b/src/lib/components/icons/FolderDownload.svelte @@ -0,0 +1,15 @@ + + + diff --git a/src/routes/settings/+page.svelte b/src/routes/settings/+page.svelte index 5822170..ece6dc8 100644 --- a/src/routes/settings/+page.svelte +++ b/src/routes/settings/+page.svelte @@ -2,10 +2,41 @@ import NavBar from '$lib/components/NavBar.svelte'; import Edit05 from '$lib/components/icons/Edit05.svelte'; import File06 from '$lib/components/icons/File06.svelte'; + import FolderDownload from '$lib/components/icons/FolderDownload.svelte'; import ShieldTick from '$lib/components/icons/ShieldTick.svelte'; import MessageQuestionSquare from '$lib/components/icons/MessageQuestionSquare.svelte'; import Star01 from '$lib/components/icons/Star01.svelte'; import { goto } from '$app/navigation'; + import { onMount } from 'svelte'; + import { invoke } from '@tauri-apps/api/core'; + import { open } from '@tauri-apps/plugin-dialog'; + + let currentDirectory = ''; + + onMount(async () => { + try { + currentDirectory = await invoke('get_download_directory'); + } catch (error) { + console.error('Failed to get download directory:', error); + } + }); + + async function selectDownloadDirectory() { + try { + const selected = await open({ + directory: true, + multiple: false, + title: 'Select Download Directory' + }); + + if (selected && typeof selected === 'string') { + await invoke('set_download_directory', { path: selected }); + currentDirectory = selected; + } + } catch (error) { + console.error('Failed to set download directory:', error); + } + }
@@ -32,7 +63,21 @@
    -
  • Tems of service
  • +
  • + +
  • +
  • Terms of service
  • Privacy Policy
  • From 185312c7ecd1d42e7b074a859cca367b7daef4b8 Mon Sep 17 00:00:00 2001 From: Pushkar Mishra Date: Tue, 28 Oct 2025 14:13:56 +0530 Subject: [PATCH 2/4] update download icon Signed-off-by: Pushkar Mishra --- src/lib/components/icons/FolderDownload.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/icons/FolderDownload.svelte b/src/lib/components/icons/FolderDownload.svelte index cd9d357..5287e02 100644 --- a/src/lib/components/icons/FolderDownload.svelte +++ b/src/lib/components/icons/FolderDownload.svelte @@ -7,7 +7,7 @@ xmlns="http://www.w3.org/2000/svg" > Date: Tue, 28 Oct 2025 14:19:45 +0530 Subject: [PATCH 3/4] Add tauri-plugin-store for enhanced settings management - Integrated the tauri-plugin-store to manage application settings, allowing users to save and retrieve their download directory preferences. - Updated relevant files including Cargo.lock, package.json, and package-lock.json to include the new plugin. - Modified the settings page to utilize the store for persistent storage of user settings. Signed-off-by: Pushkar Mishra --- Cargo.lock | 17 +++++++++++++++++ package-lock.json | 10 ++++++++++ package.json | 1 + src-tauri/Cargo.toml | 1 + src-tauri/capabilities/default.json | 3 ++- src-tauri/src/lib.rs | 1 + src/lib/components/icons/FolderDownload.svelte | 1 + src/routes/settings/+page.svelte | 15 ++++++++++++++- 8 files changed, 47 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc2acf3..ef17991 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,6 +113,7 @@ dependencies = [ "tauri-plugin-clipboard-manager", "tauri-plugin-dialog", "tauri-plugin-opener", + "tauri-plugin-store", "tokio", ] @@ -6104,6 +6105,22 @@ dependencies = [ "zbus", ] +[[package]] +name = "tauri-plugin-store" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a77036340a97eb5bbe1b3209c31e5f27f75e6f92a52fd9dd4b211ef08bf310" +dependencies = [ + "dunce", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "thiserror 2.0.17", + "tokio", + "tracing", +] + [[package]] name = "tauri-runtime" version = "2.9.1" diff --git a/package-lock.json b/package-lock.json index d618dd6..1b1f817 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@tauri-apps/plugin-clipboard-manager": "^2.3.0", "@tauri-apps/plugin-dialog": "^2.4.0", "@tauri-apps/plugin-opener": "^2.5.0", + "@tauri-apps/plugin-store": "^2.4.1", "html5-qrcode": "^2.3.8", "qrcode": "^1.5.4" }, @@ -1405,6 +1406,15 @@ "@tauri-apps/api": "^2.8.0" } }, + "node_modules/@tauri-apps/plugin-store": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-store/-/plugin-store-2.4.1.tgz", + "integrity": "sha512-ckGSEzZ5Ii4Hf2D5x25Oqnm2Zf9MfDWAzR+volY0z/OOBz6aucPKEY0F649JvQ0Vupku6UJo7ugpGRDOFOunkA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", diff --git a/package.json b/package.json index f772d35..413de00 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@tauri-apps/plugin-clipboard-manager": "^2.3.0", "@tauri-apps/plugin-dialog": "^2.4.0", "@tauri-apps/plugin-opener": "^2.5.0", + "@tauri-apps/plugin-store": "^2.4.1", "html5-qrcode": "^2.3.8", "qrcode": "^1.5.4" }, diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 22f7901..606af28 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -23,6 +23,7 @@ tauri = { version = "2.9.1", features = ["tray-icon"] } tauri-plugin-opener = "2.5.0" tauri-plugin-dialog = "2.4.0" tauri-plugin-clipboard-manager = "2.3.0" +tauri-plugin-store = "2.4.1" dirs = "6.0.0" open = "5.3.2" diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index 8228557..7020390 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -9,6 +9,7 @@ "dialog:default", "clipboard-manager:default", "clipboard-manager:allow-read-text", - "clipboard-manager:allow-write-text" + "clipboard-manager:allow-write-text", + "store:default" ] } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index a6fe608..b170deb 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -57,6 +57,7 @@ pub fn run() { let (async_proc_output_tx, mut async_proc_output_rx) = mpsc::channel(1); tauri::Builder::default() + .plugin(tauri_plugin_store::Builder::default().build()) .plugin(tauri_plugin_clipboard_manager::init()) .plugin(tauri_plugin_opener::init()) .plugin(tauri_plugin_dialog::init()) diff --git a/src/lib/components/icons/FolderDownload.svelte b/src/lib/components/icons/FolderDownload.svelte index 5287e02..0b8635e 100644 --- a/src/lib/components/icons/FolderDownload.svelte +++ b/src/lib/components/icons/FolderDownload.svelte @@ -8,6 +8,7 @@ > { try { - currentDirectory = await invoke('get_download_directory'); + store = await Store.load('settings.json'); + + const savedDirectory = await store.get('download_directory'); + if (savedDirectory) { + await invoke('set_download_directory', { path: savedDirectory }); + currentDirectory = savedDirectory; + } else { + currentDirectory = await invoke('get_download_directory'); + } } catch (error) { console.error('Failed to get download directory:', error); } @@ -32,6 +42,9 @@ if (selected && typeof selected === 'string') { await invoke('set_download_directory', { path: selected }); currentDirectory = selected; + + await store.set('download_directory', selected); + await store.save(); } } catch (error) { console.error('Failed to set download directory:', error); From 2b41b90093dafce7db5bd804482dbfa3f2384d52 Mon Sep 17 00:00:00 2001 From: Pushkar Mishra Date: Fri, 31 Oct 2025 13:00:39 +0530 Subject: [PATCH 4/4] Enhance user experience with display name feature - Added functionality to set and retrieve a custom display name for users, improving personalization during file transfers. - Updated relevant components to load and display the user's name across the application. - Integrated the `whoami` crate to fallback on the system username if no custom name is set. - Modified settings and profile pages to allow users to edit their display name. Signed-off-by: Pushkar Mishra --- Cargo.lock | 19 ++++++ README.md | 58 ++++++----------- core/src/lib.rs | 5 +- src-tauri/Cargo.toml | 1 + src-tauri/src/lib.rs | 64 ++++++++++++++++++- src/routes/settings/+page.svelte | 30 +++++++-- src/routes/settings/edit-profile/+page.svelte | 52 ++++++++++++--- src/routes/transfers/+page.svelte | 24 ++++++- 8 files changed, 198 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef17991..8cbb79b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -115,6 +115,7 @@ dependencies = [ "tauri-plugin-opener", "tauri-plugin-store", "tokio", + "whoami", ] [[package]] @@ -3086,6 +3087,7 @@ checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ "bitflags 2.10.0", "libc", + "redox_syscall", ] [[package]] @@ -6962,6 +6964,12 @@ dependencies = [ "wit-bindgen", ] +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" version = "0.2.104" @@ -7244,6 +7252,17 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" +[[package]] +name = "whoami" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" +dependencies = [ + "libredox", + "wasite", + "web-sys", +] + [[package]] name = "widestring" version = "1.2.1" diff --git a/README.md b/README.md index 366dcd7..26459f4 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ARK Drop is designed for easy file transfer. You can use QR codes to quickly sen > [!WARNING] > ARK Drop is currently under heavy development and should be used with caution. It has not undergone extensive testing and may contain bugs, vulnerabilities, or unexpected behavior. -## Development +## Tech Stack ARK Drop is built using [Tauri](https://tauri.app/) with [SvelteKit](https://kit.svelte.dev/). @@ -17,70 +17,52 @@ ARK Drop is built using [Tauri](https://tauri.app/) with [SvelteKit](https://kit [SvelteKit](https://kit.svelte.dev/) is an application framework built on Svelte. Unlike traditional frameworks, SvelteKit shifts work to a compile step during the build process, resulting in code that directly updates the DOM when the application's state changes, enhancing performance. -## Running ARK Drop Locally +## Development -You can use either `cargo tauri` CLI or `npm` CLI commands to run ARK Drop locally. +### Prerequisites -### Installing `cargo tauri` +- [Rust](https://rustup.rs/) +- [Node.js](https://nodejs.org/) -To install `cargo tauri`, run: +### Install Dependencies ```sh -cargo install tauri-cli +npm install ``` -### Starting the Tauri Development Window - -To start the Tauri development window, run: +### Run Development Server ```sh npm run tauri dev ``` -or - -```sh -cargo tauri dev -``` - This command builds the Rust code and opens the webview to display your web app. You can make changes to your web app, and if your tooling supports it, the webview will update automatically, similar to a browser. -## Building the Project +## Build -Tauri will detect your operating system and build a corresponding bundle. To build the project, run: +Tauri will detect your operating system and build a corresponding bundle. ```sh npm run tauri build ``` -or - -```sh -cargo tauri build -``` - This process will build your frontend, compile the Rust binary, gather all external binaries and resources, and produce platform-specific bundles and installers. -For more information about Tauri builds, refer to the [Tauri building guide](https://tauri.app/v1/guides/building/). - -## Dependencies +For more information, refer to the [Tauri building guide](https://tauri.app/v1/guides/building/). -Cross compilation building is done easiest via cross library. +## Android Build -- [Cross](https://github.com/cross-rs/cross) +Cross-compilation is easiest using [Cross](https://github.com/cross-rs/cross). Alternatively, you can set up the NDK and build manually. -Alternatively you can setup the NDK and build manually - -### Building for Android - -Make sure you have added the nessecary targets to build for android +### Add Android Targets ```sh -rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android +rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android ``` -Build the cdylib for all the targets +### Build for Android Targets +Using Cross: ```sh cross build -p drop_core --target aarch64-linux-android cross build -p drop_core --target armv7-linux-androideabi @@ -88,8 +70,8 @@ cross build -p drop_core --target i686-linux-android cross build -p drop_core --target x86_64-linux-android ``` -Generate the bindings using uniffi for kotlin - +Or using cargo-ndk: ```sh -cargo run -p uniffi-bingen generate --library target/x86_64-linux-android/debug/libdrop_core.so --language=kotlin --out-dir ./bindings +cargo install cargo-ndk +cargo ndk -o ./target/release/jniLibs --target aarch64-linux-android --target armv7-linux-androideabi --target i686-linux-android --target x86_64-linux-android build -p drop_core --release ``` diff --git a/core/src/lib.rs b/core/src/lib.rs index 8d58b24..0d746ec 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -206,6 +206,7 @@ impl IrohInstance { ticket_str: String, output_dir: PathBuf, handle: Arc, + display_name: Option, ) -> IrohResult { // Parse ticket to extract confirmation let (ticket, confirmation) = TicketWrapper::parse(&ticket_str)?; @@ -229,9 +230,9 @@ impl IrohInstance { IrohError::DownloadError(format!("Failed to create receiving directory: {}", e)) })?; - // Create receiver profile + // Create receiver profile with provided name or default to "Anonymous" let profile = ReceiverProfile { - name: "Anonymous".to_string(), + name: display_name.unwrap_or_else(|| "Anonymous".to_string()), avatar_b64: None, }; diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 606af28..917a713 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -26,6 +26,7 @@ tauri-plugin-clipboard-manager = "2.3.0" tauri-plugin-store = "2.4.1" dirs = "6.0.0" open = "5.3.2" +whoami = "1.5.2" anyhow = { workspace = true } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index b170deb..c1be0b2 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -23,6 +23,8 @@ struct AppState { active_send_bubble: Arc>>, /// Custom download directory set by user custom_download_dir: Mutex>, + /// User display name for file transfer identification + user_display_name: Mutex>, } enum Event { @@ -36,6 +38,7 @@ impl AppState { inner: Mutex::new(async_proc_input_tx), active_send_bubble: Arc::new(Mutex::new(None)), custom_download_dir: Mutex::new(None), + user_display_name: Mutex::new(None), } } } @@ -93,6 +96,8 @@ pub fn run() { receive_files, set_download_directory, get_download_directory, + set_display_name, + get_display_name, open_directory, is_valid_ticket, get_env @@ -231,10 +236,22 @@ async fn receive_files( .unwrap_or_else(|| PathBuf::from("/storage/emulated/0/Download/")) }; + // Get display name with fallback chain: custom → system username → None + let display_name = { + let custom_name = state.user_display_name.lock().await; + custom_name.clone() + .or_else(|| Some(whoami::username())) + }; + // Receive files with proper file writing let _collection = state .iroh - .receive_files(ticket, output_dir.clone(), Arc::new(FileTransferHandle(tx))) + .receive_files( + ticket, + output_dir.clone(), + Arc::new(FileTransferHandle(tx)), + display_name + ) .await .map_err(|e| InvokeError::from_anyhow(anyhow!(e)))?; @@ -295,6 +312,51 @@ async fn get_download_directory(state: tauri::State<'_, AppState>) -> Result, + name: String, +) -> Result<(), InvokeError> { + let trimmed = name.trim(); + + if trimmed.is_empty() { + return Err(InvokeError::from_anyhow(anyhow!("Display name cannot be empty"))); + } + + if trimmed.len() > 50 { + return Err(InvokeError::from_anyhow(anyhow!("Display name cannot exceed 50 characters"))); + } + + let mut display_name = state.user_display_name.lock().await; + *display_name = Some(trimmed.to_string()); + + Ok(()) +} + +/// Gets the current display name. +/// +/// Returns the custom name if set, otherwise returns the system username. +/// +/// # Returns +/// The display name as a string +#[tauri::command] +async fn get_display_name(state: tauri::State<'_, AppState>) -> Result { + let custom_name = state.user_display_name.lock().await; + + let name = custom_name + .clone() + .unwrap_or_else(|| whoami::username()); + + Ok(name) +} + /// Opens a directory in the system's file manager. /// /// # Arguments diff --git a/src/routes/settings/+page.svelte b/src/routes/settings/+page.svelte index fee161f..21fbd2c 100644 --- a/src/routes/settings/+page.svelte +++ b/src/routes/settings/+page.svelte @@ -13,12 +13,14 @@ import { Store } from '@tauri-apps/plugin-store'; let currentDirectory = ''; + let displayName = ''; let store: Store; - onMount(async () => { + async function loadSettings() { try { store = await Store.load('settings.json'); + // Load download directory const savedDirectory = await store.get('download_directory'); if (savedDirectory) { await invoke('set_download_directory', { path: savedDirectory }); @@ -26,10 +28,30 @@ } else { currentDirectory = await invoke('get_download_directory'); } + + // Load display name + const savedName = await store.get('display_name'); + if (savedName) { + await invoke('set_display_name', { name: savedName }); + displayName = savedName; + } else { + displayName = await invoke('get_display_name'); + } } catch (error) { - console.error('Failed to get download directory:', error); + console.error('Failed to load settings:', error); } - }); + } + + onMount(loadSettings); + + // Reload settings when page becomes visible (e.g., returning from edit-profile) + $: if (typeof document !== 'undefined') { + document.addEventListener('visibilitychange', () => { + if (!document.hidden) { + loadSettings(); + } + }); + } async function selectDownloadDirectory() { try { @@ -61,7 +83,7 @@
    - Gilbert + {displayName || 'Loading...'}
- - + + {#if openAvatars} diff --git a/src/routes/transfers/+page.svelte b/src/routes/transfers/+page.svelte index 6649bff..3fbd8a9 100644 --- a/src/routes/transfers/+page.svelte +++ b/src/routes/transfers/+page.svelte @@ -1,5 +1,8 @@