Switching Dioxus Component from Server

Hi there,

I'm playing around with Dioxus to create a simple game. Multiple web views communicate through a server to send their state, and one "display" view regularly polls the server to display a common state.

So far it all works nicely, but now I would like to have the players web view update depending on what happens on the server. I managed to have #[server] parts which can be called from the players.

I use some hand-written javascript code injected using

use_effect(move || {
  document::eval(include_str!("script.js"));
});

to do this push / polling. Now I would like to be able from my javascript code to change the currently shown component. Any idea how I can do this? I looked at signals and all that, but cannot see how I can use them to change components. The only way I see how to change components is to use a rsx!{ Link { to: Route::OtherComponent } }. Or can I just change the document.location to something which is in the path?

Thanks for any hints,

Ineiti

OK, using document.location = "/" reloads the app, and I lose all state...

I didn't find out how to go from one path to another. But you can change the component which is shown like this:

    rsx! {
        div {
            // Link {to: Route::Display{}, "Display"}
            match game() {
                Game::Idle => rsx!{Join{joined: vec![], current_player}},
                Game::Signup(joined) => if current_player().is_some() {
                    rsx!{WaitJoin{ joined }}
                } else {
                    rsx!{Join{joined, current_player}}
                },
                Game::Play(players) => if let Some(player) = current_player() {
                    rsx!{Play { players, player }}
                } else {
                    rsx!{WaitWinner {  }}
                },
                Game::Winner(winner) => rsx!{Winner {winner, player: current_player() }},
                Game::Draw => rsx!{Draw {}},
            }
        }
    }

game() itself is defined here, and updated in a polling loop:

    let mut game = use_signal(|| Game::Idle);
    let current_player: Signal<Option<PlayColor>> = use_signal(|| None);

    use_future(move || async move {
        loop {
            game.set(game_state().await.unwrap());
            sleep(Duration::from_millis(500)).await;
        }
    });

Once the game signal of type Signal<Game> changes value, the match in the main rsx! will return a different Element, and show it to the user.