1

I have tauri command on backend(tauri) that returns a string(light theme value from windows registry). I need to get it on frontend + listen if this string changes. I couldn't find needed functions in leptos or tauri docs. So I came up with this crutch on frontend:

let (is_light_theme, set_is_light_theme) = create_signal(String::new());

let is_light_theme_fn = move || {
        spawn_local(async move {
            let is_light_theme_fetch = invoke("is_light_theme", to_value("").unwrap())
                .await
                .as_string()
                .unwrap();
            set_is_light_theme.set(_is_light_theme_);
            loop {
                let old_value = is_light_theme.get();
                let new_value = invoke("is_light_theme", to_value("").unwrap())
                    .await
                    .as_string()
                    .unwrap();
                if new_value != old_value {
                    set_is_light_theme.set(new_value);
                };
                // sleep(Duration::from_millis(2000)).await; // breaks loop
            }
        });
    };
    is_light_theme_fn();

tauri command on the backend:

#[tauri::command]
fn is_light_theme() -> String {
    let theme = helpers::is_light_theme();
    format!("{}", theme)
}

is_light_theme in helpers:

pub fn is_light_theme() -> bool {
    let val = CURRENT_USER
        .open(r#"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"#)
        .expect("Failed to get registry key")
        .get_u32("AppsUseLightTheme")
        .expect("Failed to get registry value");
    println!("{}", val);
    val != 0
}

This runs somewhat okay but this loop is very process-intensive. I tried adding sleep from std:thread and tokio to loop, both of them are breaking it.

Maybe there's a better a way to listen for value changes in backend?

1

1 Answer 1

1

Backend -> Frontend

You can use Tauri events:

// in your setup routine or tauri command function, where you can have access to the app handle
app.emit_all("event-name", Payload { message: "Tauri is awesome!".into() }).unwrap();

And then listen to this event in the frontend:

import { emit, listen } from '@tauri-apps/api/event'

const unlisten = await listen('event-name', (event) => {
  // event.payload is the payload object
  console.log(event);
})

========== OLD ANSWER =============

Frontend -> Backend

It's usually a bad idea to continuously poll data, I might be not fully understanding your use case, but here's how I would do it, if I needed to get theme from the frontend.

I'd use state management instead:

use std::sync::Mutex;
use tauri::State;

struct Theme {
    theme: Mutex<String>,
}

fn main() {
    tauri::Builder::default()
                .manage(Theme { theme: Mutex::new(String::from("default")) })
        .invoke_handler(tauri::generate_handler![update_theme])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

#[tauri::command]
fn update_theme(new_theme: String, state: State<Theme>) {
        let mut theme = state.theme.lock().unwrap();
        *theme = new_theme;
}
Sign up to request clarification or add additional context in comments.

5 Comments

Am I understanding this code correctly? When I invoke update_theme on frontend it will update theme in the backend. If so, I need the opposite - when value changes in backend I need to send new value to frontend
@Grayza in this case you'd want to use events. I just updated the answer with the example. Take a look.
Thanks for sharing! I'm interested if there are alternatives to @tauri/apps for the Rust frontend(Leptos). Looks like listen in docs.rs is for backend.
@Grayza you'd probably have to build it yourself, since it's just a wrapper around window.__TAURI__.invoke(). I don't know how leptos compiles to WASM, but from WASM you could probably just call rust wasm_bindgen::JsCast; and then the invoke function.
If this answer helped you, feel free to go ahead and accept it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.