Added live subscription to persons

This commit is contained in:
xeovalyte 2024-03-19 20:16:27 +01:00
parent afd5de8f02
commit 86de475a2e
No known key found for this signature in database
4 changed files with 122 additions and 21 deletions

View File

@ -75,6 +75,7 @@ pub fn App() -> impl IntoView {
<Route path="/participants" view=participants::Participants /> <Route path="/participants" view=participants::Participants />
<Route path="/participants/add" view=participants::add::Add /> <Route path="/participants/add" view=participants::add::Add />
<Route path="/times" view=times::Times /> <Route path="/times" view=times::Times />
<Route path="/times/add" view=times::add::Add />
<Route path="/*" view=NotFound /> <Route path="/*" view=NotFound />
</Route> </Route>
</Routes> </Routes>

View File

@ -1,4 +1,5 @@
use leptos::*; use leptos::*;
use leptos_router::*;
pub mod add; pub mod add;
@ -6,10 +7,6 @@ pub mod add;
#[component] #[component]
pub fn Times() -> impl IntoView { pub fn Times() -> impl IntoView {
view! { view! {
<div class="container"> <A class="btn-add-link" href="/times/add">"Tijd toevoegen"</A>
<h1>"Tijden"</h1>
</div>
} }
} }

View File

@ -3,7 +3,38 @@ use leptos::*;
/// Navigation bar /// Navigation bar
#[component] #[component]
pub fn Add() -> impl IntoView { pub fn Add() -> impl IntoView {
let websocket = expect_context::<crate::util::surrealdb::SurrealContext>();
let participants = expect_context::<crate::util::surrealdb::ParticipantsContext>();
let (name, set_name) = create_signal(String::from(""));
let (error, set_error) = create_signal(String::from(""));
let on_submit = move |ev: leptos::ev::SubmitEvent| {
ev.prevent_default();
set_error.set(String::from(""));
/*
match websocket.add_person(name.get(), group.get()) {
Ok(_) => set_name.set(String::from("")),
Err(err) => set_error.set(err),
}
*/
};
view! { view! {
<h1>"Deelnemer toevoegen"</h1> <h1>"Tijd toevoegen"</h1>
<p>{ move || format!("{:?}", participants.read.get()) }</p>
<form class="add" on:submit=on_submit>
<input type="text"
placeholder="Name"
on:input=move |ev| {
set_name.set(event_target_value(&ev));
}
prop:value=name
/>
<input type="submit" value="Submit" />
</form>
<p class="error">
{ error }
</p>
} }
} }

View File

@ -3,11 +3,18 @@ use leptos::*;
use leptos_use::{core::ConnectionReadyState, use_websocket, UseWebsocketReturn}; use leptos_use::{core::ConnectionReadyState, use_websocket, UseWebsocketReturn};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::json; use serde_json::json;
use std::rc::Rc; use std::{alloc::handle_alloc_error, rc::Rc};
#[derive(Serialize)]
#[serde(untagged)]
enum SurrealId {
String(String),
Integer(u32),
}
#[derive(Serialize)] #[derive(Serialize)]
struct SurrealRequest { struct SurrealRequest {
id: u32, id: SurrealId,
method: String, method: String,
params: Vec<SurrealParams>, params: Vec<SurrealParams>,
} }
@ -33,14 +40,18 @@ struct CreatePersonParam {
group: String, group: String,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Participant { pub struct Participant {
id: String,
name: String, name: String,
group: String, group: String,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ParticipantsContext(pub ReadSignal<Vec<Participant>>); pub struct ParticipantsContext {
pub read: ReadSignal<Vec<Participant>>,
write: WriteSignal<Vec<Participant>>,
}
#[derive(Clone)] #[derive(Clone)]
pub struct SurrealContext { pub struct SurrealContext {
@ -51,16 +62,25 @@ pub struct SurrealContext {
pub set_authenticated: WriteSignal<bool>, pub set_authenticated: WriteSignal<bool>,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone)]
struct SurrealResponse { struct SurrealResponse {
id: u32, id: Option<u32>,
result: SurrealResult, result: SurrealResult,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
struct SurrealAction {
id: String,
action: String,
result: Participant,
}
#[derive(Serialize, Deserialize, Clone)]
#[serde(untagged)] #[serde(untagged)]
enum SurrealResult { enum SurrealResult {
String(String), String(String),
Participants(Vec<Participant>),
Action(SurrealAction),
Null, Null,
} }
@ -92,7 +112,7 @@ impl SurrealContext {
log::debug!("Signing into surrealdb"); log::debug!("Signing into surrealdb");
let request = SurrealRequest { let request = SurrealRequest {
id: 0, id: SurrealId::Integer(0),
method: String::from("signin"), method: String::from("signin"),
params: vec![SurrealParams::SigninParam(SigninParam { params: vec![SurrealParams::SigninParam(SigninParam {
user: String::from("root"), user: String::from("root"),
@ -109,7 +129,7 @@ impl SurrealContext {
} }
let request = SurrealRequest { let request = SurrealRequest {
id: 1, id: SurrealId::Integer(10),
method: String::from("create"), method: String::from("create"),
params: vec![ params: vec![
SurrealParams::String(String::from("person")), SurrealParams::String(String::from("person")),
@ -134,7 +154,7 @@ pub fn init_surrealdb() {
} = use_websocket("ws://localhost:80/rpc"); } = use_websocket("ws://localhost:80/rpc");
// Create reactive signals for the websocket connection to surrealDB // Create reactive signals for the websocket connection to surrealDB
let (participants, _set_participants) = create_signal::<Vec<Participant>>(vec![]); let (participants, set_participants) = create_signal::<Vec<Participant>>(vec![]);
let (authenticated, set_authenticated) = create_signal::<bool>(false); let (authenticated, set_authenticated) = create_signal::<bool>(false);
// Bind the websocket connection to a context // Bind the websocket connection to a context
@ -147,7 +167,10 @@ pub fn init_surrealdb() {
); );
provide_context(websocket); provide_context(websocket);
provide_context(ParticipantsContext(participants)); provide_context(ParticipantsContext {
read: participants,
write: set_participants,
});
// Watch for a message recieved from the surrealDB connection // Watch for a message recieved from the surrealDB connection
create_effect(move |prev_value| { create_effect(move |prev_value| {
@ -178,9 +201,17 @@ fn surrealdb_response(response: String) {
}; };
match response.id { match response.id {
0 => use_surrealdb(response), Some(0) => use_surrealdb(response.clone()),
1 => log::debug!("Succesfully execute use wrb timings"), Some(1) => get_participants(),
_ => return, Some(2) => log::debug!("Subscribed to live timings"),
Some(5) => got_participants(response.result.clone()),
Some(_) => (),
None => (),
}
match response.result {
SurrealResult::Action(action) => handle_action(action),
_ => (),
} }
} }
@ -196,7 +227,7 @@ fn use_surrealdb(_response: SurrealResponse) {
websocket.set_authenticated.set(true); websocket.set_authenticated.set(true);
let request = SurrealRequest { let request = SurrealRequest {
id: 1, id: SurrealId::Integer(1),
method: String::from("use"), method: String::from("use"),
params: vec![ params: vec![
SurrealParams::String(String::from("wrb")), SurrealParams::String(String::from("wrb")),
@ -206,3 +237,44 @@ fn use_surrealdb(_response: SurrealResponse) {
websocket.send(&json!(request).to_string()) websocket.send(&json!(request).to_string())
} }
/// Function to get all participants and subscribe to changes
fn get_participants() {
let websocket = expect_context::<SurrealContext>();
let request = SurrealRequest {
id: SurrealId::Integer(5),
method: String::from("select"),
params: vec![SurrealParams::String(String::from("person"))],
};
websocket.send(&json!(request).to_string());
let request = SurrealRequest {
id: SurrealId::Integer(2),
method: String::from("live"),
params: vec![SurrealParams::String(String::from("person"))],
};
websocket.send(&json!(request).to_string());
}
/// Function that will execute when participants are recieved
fn got_participants(result: SurrealResult) {
let participants_context = expect_context::<ParticipantsContext>();
if let SurrealResult::Participants(mut value) = result {
let mut participants = participants_context.read.get();
participants.append(&mut value);
participants_context.write.set(participants);
}
}
/// Function to call when an action is recieved from surrealDB
fn handle_action(action: SurrealAction) {
let participants_context = expect_context::<ParticipantsContext>();
let mut participants = participants_context.read.get();
participants.push(action.result);
participants_context.write.set(participants);
}