use crate::components::websocket::WebSocketContext; use leptos::html::Input; use leptos::*; use leptos_use::core::ConnectionReadyState; use lib::*; use serde_json::to_string; use std::collections::BTreeSet; #[component] pub fn Browser() -> impl IntoView { let websocket = expect_context::<WebSocketContext>(); let connected = move || websocket.ready_state.get() == ConnectionReadyState::Open; let game_update_context = expect_context::<ReadSignal<Option<GamesUpdate>>>(); let card_packs = expect_context::<ReadSignal<CardPacksMeta>>(); let (active_games, set_active_games) = create_signal::<Vec<String>>(vec![]); let new_game_name_ref = create_node_ref::<Input>(); let (selected_packs, set_selected_packs) = create_signal::<BTreeSet<u8>>(BTreeSet::new()); create_effect(move |_| { logging::log!("{:#?}", selected_packs().iter().collect::<Vec<_>>()); }); // Game stuff let new_game = move |_| { if let Some(input) = new_game_name_ref.get() { if input.value() == String::from("") { logging::log!("New game name is empty!"); } else if selected_packs().is_empty() { logging::log!("New game selected packs is empty!"); } else { (websocket.send)( &to_string(&NewGameRequest { name: input.value(), packs: selected_packs() .into_iter() .map(|n| n.clone()) // hax .collect::<Vec<_>>(), }) .unwrap(), ); input.set_value(""); } } }; create_effect(move |_| { game_update_context.with(move |games| { if let Some(games) = games { set_active_games(games.games.clone()); } }) }); // Clear games list on disconnect create_effect(move |_| { if !connected() { set_active_games(vec![]); } }); let (show_packs, set_show_packs) = create_signal(false); let show_packs_button = move |_| set_show_packs(!show_packs()); view! { <div class="p-1"> <h2 class="text-2xl">Game Browser</h2> <ul> {move || active_games().into_iter().map(|n| view! { <li>{n}</li> }).collect_view()} </ul> </div> <hr/> <div class="flex p-1"> <form onsubmit="return false" on:submit=new_game> <h2 class="text-2xl">Create Game</h2> <input class="w-80 h-11 font-mono rounded-sm bg-neutral-900 text-neutral-200" placeholder="Name" disabled=move || !connected() node_ref=new_game_name_ref /> <h2 class="text-2xl">Packs</h2> <div class="p-2"> <button type="button" class="bg-neutral-600"> <input type="checkbox" id="all"/> <label for="all">All</label> </button> <button type="button" class="bg-neutral-600"> <input type="checkbox" id="official" checked/> <label for="official">Official</label> </button> <button type="button" class="bg-neutral-600" on:click=show_packs_button> <label>Custom</label> </button> finish this </div> <Show when=move || show_packs()> <span class="flex"> <div> <h2 class="text-xl">Official</h2> {move || { card_packs() .official_meta .into_iter() .map(|n| { view! { <input type="checkbox" value=n.pack id=n.pack checked on:change=move |e| { if event_target_checked(&e) { logging::log!("insert"); set_selected_packs .update(|packs| { packs.insert(n.pack); }) } else { logging::log!("remove"); set_selected_packs .update(|packs| { packs.remove(&n.pack); }) } } /> <label for=n.pack>{n.name}</label> <br/> {set_selected_packs .update(|packs| { packs.insert(n.pack); })} } }) .collect_view() }} </div> <div> <h2 class="text-xl">Unofficial</h2> {move || { card_packs() .unofficial_meta .into_iter() .map(|n| { view! { <input type="checkbox" value=n.pack id=n.pack on:change=move |e| { if event_target_checked(&e) { logging::log!("insert"); set_selected_packs .update(|packs| { packs.insert(n.pack); }) } else { logging::log!("remove"); set_selected_packs .update(|packs| { packs.remove(&n.pack); }) } } /> <label for=n.pack>{n.name}</label> <br/> } }) .collect_view() }} </div> </span> </Show> <input class="py-2 px-4 pl-4 font-bold text-white rounded border-b-4 bg-neutral-600 border-neutral-800 hover:bg-neutral-700 hover:border-neutral-500" type="submit" disabled=move || !connected() value="New Game" /> </form> </div> } }