diff --git a/application/src/app.rs b/application/src/app.rs index 881955a..f461325 100644 --- a/application/src/app.rs +++ b/application/src/app.rs @@ -11,8 +11,7 @@ use crate::util; pub fn App() -> impl IntoView { // Provides context that manages stylesheets, titles, meta tags, etc. provide_meta_context(); - let participants: RwSignal> = - create_rw_signal(vec![]); + let participants: util::surrealdb::schemas::ParticipantsContext = create_rw_signal(vec![]); provide_context(participants); util::surrealdb::init_participants(); diff --git a/application/src/components.rs b/application/src/components.rs index f505d68..7a2354d 100644 --- a/application/src/components.rs +++ b/application/src/components.rs @@ -1 +1,2 @@ pub mod header; +pub mod participants; diff --git a/application/src/components/participants.rs b/application/src/components/participants.rs new file mode 100644 index 0000000..77c4108 --- /dev/null +++ b/application/src/components/participants.rs @@ -0,0 +1,45 @@ +use crate::util::surrealdb::schemas; +use leptos::*; + +/// Renders the home page of your application. +#[component] +pub fn Participants() -> impl IntoView { + let participants_context = use_context::().unwrap(); + + view! { +
+ + + + + + + + + + + + + { move || match child.value.get().events { + Some(events) => view! { + + + + }, + None => view! { + + + + } + } + } + + +
"Naam""Groep""Lifesaver""Hindernis""Popduiken"
{ move || child.value.get().name }{ move || child.value.get().group }{ events.lifesaver.unwrap_or(0) }{ events.hindernis.unwrap_or(0) }{ events.popduiken.unwrap_or(0) }"0""0""0"
+
+ } +} diff --git a/application/src/pages/add_participant.rs b/application/src/pages/add_participant.rs index a757c9f..c0e196e 100644 --- a/application/src/pages/add_participant.rs +++ b/application/src/pages/add_participant.rs @@ -1,8 +1,6 @@ use leptos::*; use leptos_router::ActionForm; -use crate::util::surrealdb::schemas::Participant; - cfg_if::cfg_if! { if #[cfg(feature = "ssr")] { use crate::util::surrealdb::{DB, schemas}; @@ -29,11 +27,11 @@ async fn add_participant(name: String, group: String) -> Result<(), ServerFnErro ); let action = ParticipantsAction::Add { - participant: Participant { + participant: schemas::Participant { name: participant.name.clone(), group: participant.group.clone(), id: participant.id.to_string(), - events: None, + events: participant.events.clone(), }, }; diff --git a/application/src/pages/add_time.rs b/application/src/pages/add_time.rs index acbb404..a0bb117 100644 --- a/application/src/pages/add_time.rs +++ b/application/src/pages/add_time.rs @@ -6,7 +6,8 @@ use web_sys::ScrollIntoViewOptions; cfg_if::cfg_if! { if #[cfg(feature = "ssr")] { - use crate::util::surrealdb::{DB}; + use crate::util::surrealdb::{DB, schemas::Participant}; + use crate::util::websocket::{server, ParticipantsAction}; use surrealdb::opt::PatchOp; use leptos::logging; } @@ -31,19 +32,33 @@ async fn add_time( event: String, time: u32, ) -> Result<(), ServerFnError> { + let websocket_state = &server::WEBSOCKET_STATE; + let updated: Option = DB - .update(("participant", participant.id)) + .update(("participant", &participant.id)) .patch(PatchOp::replace(&("/events/".to_owned() + &event), time)) .await?; match updated { - Some(participant) => { + Some(participant_updated) => { logging::log!( "Updated participant: {} ({})", - participant.name, - participant.group + participant_updated.name, + participant_updated.group ); - Ok(()) + let action = ParticipantsAction::Replace { + participant: Participant { + name: participant_updated.name.clone(), + group: participant_updated.group.clone(), + id: participant.id, + events: participant_updated.events.clone(), + }, + }; + + match websocket_state.apply(action) { + Ok(_) => Ok(()), + Err(_) => Err(ServerFnError::new("Error sending websocket action")), + } } None => Err(ServerFnError::ServerError(String::from( "Could not update participant", @@ -54,7 +69,7 @@ async fn add_time( /// Renders the home page of your application. #[component] pub fn AddTime() -> impl IntoView { - let participants = use_context::>>().unwrap(); + let participants = use_context::().unwrap(); let container_ref: NodeRef = create_node_ref(); let name_input_ref: NodeRef = create_node_ref(); @@ -82,7 +97,7 @@ pub fn AddTime() -> impl IntoView { let participant = &participants_sorted.get()[selected_index.get()]; add_time_action.dispatch(( participant.clone(), - String::from("lifesaver"), + event.get(), time.get().as_milliseconds(), )); @@ -213,16 +228,16 @@ pub fn SelectOption(is: &'static str, value: ReadSignal) -> impl IntoVie } } fn sort_participants( - participants: Vec, + participants: Vec, search: String, ) -> Vec { let mut filtered_sorted_list: Vec<(schemas::Participant, f64)> = participants .into_iter() .map(|participant| { ( - participant.clone(), + participant.value.get(), normalized_damerau_levenshtein( - &participant.name.to_lowercase(), + &participant.value.get().name.to_lowercase(), &search.to_lowercase(), ), ) diff --git a/application/src/pages/index.rs b/application/src/pages/index.rs index e68c818..d8b153c 100644 --- a/application/src/pages/index.rs +++ b/application/src/pages/index.rs @@ -1,3 +1,4 @@ +use crate::components; use leptos::*; use leptos_router::*; @@ -9,5 +10,6 @@ pub fn HomePage() -> impl IntoView { Deelnemer toevoegen Tijd toevoegen + } } diff --git a/application/src/util/surrealdb.rs b/application/src/util/surrealdb.rs index 8c9edba..0fe1718 100644 --- a/application/src/util/surrealdb.rs +++ b/application/src/util/surrealdb.rs @@ -51,9 +51,18 @@ pub fn init_participants() { create_effect(move |_| { participants.and_then(|data: &Vec| { - let participants_context = - use_context::>>().unwrap(); - participants_context.set(data.to_vec()); + let participants_context = use_context::().unwrap(); + + let mut participants_new: Vec = vec![]; + + for participant in data { + participants_new.push(schemas::ParticipantSignal { + id: participant.id.clone(), + value: create_rw_signal(participant.clone()), + }) + } + + participants_context.set(participants_new); }); }); } diff --git a/application/src/util/surrealdb/schemas.rs b/application/src/util/surrealdb/schemas.rs index 997c4dc..2ccd416 100644 --- a/application/src/util/surrealdb/schemas.rs +++ b/application/src/util/surrealdb/schemas.rs @@ -4,13 +4,14 @@ cfg_if::cfg_if! { } } +use leptos::RwSignal; use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Hash, Eq)] pub struct Events { - lifesaver: Option, - hindernis: Option, - popduiken: Option, + pub lifesaver: Option, + pub hindernis: Option, + pub popduiken: Option, } #[cfg(feature = "ssr")] @@ -30,6 +31,14 @@ pub struct Participant { pub events: Option, } +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct ParticipantSignal { + pub id: String, + pub value: RwSignal, +} + +pub type ParticipantsContext = RwSignal>; + #[derive(Serialize, Deserialize, Debug)] pub struct NewParticipant { pub name: String, diff --git a/application/src/util/websocket.rs b/application/src/util/websocket.rs index 98f64ec..38a141d 100644 --- a/application/src/util/websocket.rs +++ b/application/src/util/websocket.rs @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize}; use crate::util::surrealdb::schemas::Participant; -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Debug)] pub enum ParticipantsAction { Add { participant: Participant }, Replace { participant: Participant }, diff --git a/application/src/util/websocket/client.rs b/application/src/util/websocket/client.rs index 7b0bb28..3a8f077 100644 --- a/application/src/util/websocket/client.rs +++ b/application/src/util/websocket/client.rs @@ -35,23 +35,29 @@ fn handle_message(message: &str) { } }; - let participants_context = use_context::>>().unwrap(); + logging::log!("Recieved action: {:?}", action); + + let participants_context = use_context::().unwrap(); match action { - ParticipantsAction::Add { participant } => { - participants_context.update(|participants| participants.push(participant)) - } + ParticipantsAction::Add { participant } => participants_context.update(|participants| { + participants.push(schemas::ParticipantSignal { + id: participant.id.clone(), + value: create_rw_signal(participant), + }) + }), ParticipantsAction::Remove { id } => participants_context .update(|participants| participants.retain(|participant| participant.id != id)), ParticipantsAction::Replace { participant } => { - participants_context.update(|participants| { - if let Some(index) = participants - .iter() - .position(|item| item.id == participant.id) - { - let _ = std::mem::replace(&mut participants[index], participant); + participants_context.with(|participants| { + for participant_signal in participants { + if participant_signal.id == participant.id { + participant_signal.value.update(|value| { + *value = participant.clone(); + }) + } } - }) + }); } } }