use crate::hand_view::HandView; use crate::remote_view::RemoteGameView; use crate::tile_view::PlacedTileView; use crate::types::SelectedTile; use board_shared::board::Board; use board_shared::deck::RngDeck; use board_shared::expr::is_valid_guess; use board_shared::game::Game; use board_shared::position::Grid2d; use board_shared::tile::Tile; use futures::StreamExt; use gloo_dialogs::alert; use gloo_net::websocket::futures::WebSocket; use std::cell::RefCell; use std::rc::Rc; use web_sys::HtmlInputElement; use yew::prelude::*; #[derive(Properties, PartialEq)] pub struct BoardViewProps { pub board: Board, pub on_click: Callback<(usize, usize)>, } #[function_component(BoardView)] pub fn board_view(BoardViewProps { board, on_click }: &BoardViewProps) -> Html { html! { { (0..board.height()).map(|y| html! { { (0..board.width()).map(|x| html! { }).collect::() } }).collect::() }
} } #[function_component(GameView)] pub fn game_view() -> Html { let game = use_state(Game::default); let current_game = use_state(Game::default); let selected_tile = use_state(|| SelectedTile::None); let on_tile_click = { let game = current_game.clone(); let selected_tile = selected_tile.clone(); Callback::from(move |(x, y)| { if let SelectedTile::InHand(idx) = *selected_tile { let mut in_hand = game.in_hand.clone(); let tile = in_hand.tiles.remove(idx); let mut board = game.board.clone(); board.set(x, y, tile); game.set(Game { board, in_hand }); selected_tile.set(SelectedTile::None); } else if let SelectedTile::Equals = *selected_tile { let mut board = game.board.clone(); board.set(x, y, Tile::Equals); game.set(Game { board, in_hand: game.in_hand.clone(), }); selected_tile.set(SelectedTile::None); } }) }; let on_tile_select = { let selected_tile = selected_tile.clone(); Callback::from(move |idx| { selected_tile.set(SelectedTile::InHand(idx)); }) }; let on_equals_select = { Callback::from(move |_| { selected_tile.set(SelectedTile::Equals); }) }; let on_continue_click = { let current_game = current_game.clone(); Callback::from(move |_| { let diff = game.board.difference(¤t_game.board); let mut deck = RngDeck::new_complete(); if let Some(true) = Board::is_contiguous(&diff) { if let Ok(true) = is_valid_guess(¤t_game.board, &diff) { alert("Valid move!"); let mut in_hand = current_game.in_hand.clone(); if in_hand.complete(&mut deck).is_err() { alert("No more tiles left in deck!"); } game.set(Game { board: current_game.board.clone(), in_hand: in_hand.clone(), }); current_game.set(Game { board: current_game.board.clone(), in_hand, }); } else { alert("Invalid move! (invalid expressions)"); current_game.set(Game { board: game.board.clone(), in_hand: game.in_hand.clone(), }); } } else { if !diff.is_empty() { alert("Invalid move! (not contiguous)"); } let mut in_hand = game.in_hand.clone(); if in_hand.complete(&mut deck).is_err() { alert("No more tiles left in deck!"); } current_game.set(Game { board: game.board.clone(), in_hand, }); } }) }; html! {
} } #[function_component(App)] pub fn app() -> Html { let remote = use_state(|| "ws://localhost:8081/ws".to_string()); let player_name = use_state(|| None); let room_name = use_state(|| None); let remote_ref = use_node_ref(); let player_name_ref = use_node_ref(); let room_name_ref = use_node_ref(); let on_create_click = { let remote = remote.clone(); let remote_ref = remote_ref.clone(); let player_name = player_name.clone(); let player_name_ref = player_name_ref.clone(); Callback::from(move |_| { remote.set( remote_ref .cast::() .expect("remote_ref is not attached to a input element") .value(), ); player_name.set(Some( player_name_ref .cast::() .expect("player_name_ref is not attached to a input element") .value(), )); }) }; let on_join_click = { let remote = remote.clone(); let remote_ref = remote_ref.clone(); let player_name = player_name.clone(); let player_name_ref = player_name_ref.clone(); let room_name = room_name.clone(); let room_name_ref = room_name_ref.clone(); Callback::from(move |_| { remote.set( remote_ref .cast::() .expect("remote_ref is not attached to a input element") .value(), ); player_name.set(Some( player_name_ref .cast::() .expect("player_name_ref is not attached to a input element") .value(), )); room_name.set(Some( room_name_ref .cast::() .expect("room_name_ref is not attached to a input element") .value(), )); }) }; if let Some(player_name) = (*player_name).as_ref() { let ws = WebSocket::open(remote.as_ref()).unwrap(); let (write, read) = ws.split(); return html! {
}; } html! {
} }