First commit
This commit is contained in:
		
						commit
						f5c2080cd5
					
				
					 11 changed files with 386989 additions and 0 deletions
				
			
		
							
								
								
									
										185
									
								
								web_gui/src/lib.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								web_gui/src/lib.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,185 @@
 | 
			
		|||
use std::sync::Mutex;
 | 
			
		||||
 | 
			
		||||
use wasm_bindgen::prelude::*;
 | 
			
		||||
use web_sys::{console, Event, HtmlElement, HtmlInputElement};
 | 
			
		||||
 | 
			
		||||
use anagrams::{AnagramDict, Dict};
 | 
			
		||||
 | 
			
		||||
static DICTIONNARY: Mutex<Option<AnagramDict>> = Mutex::new(None);
 | 
			
		||||
 | 
			
		||||
fn window() -> web_sys::Window {
 | 
			
		||||
    web_sys::window().expect("no global `window` exists")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn document() -> web_sys::Document {
 | 
			
		||||
    window()
 | 
			
		||||
        .document()
 | 
			
		||||
        .expect("should have a document on window")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn display_spinner() {
 | 
			
		||||
    let result = document()
 | 
			
		||||
        .get_element_by_id("spinner")
 | 
			
		||||
        .expect("#spinner not found");
 | 
			
		||||
    let style = result
 | 
			
		||||
        .dyn_ref::<HtmlElement>()
 | 
			
		||||
        .expect("Failed to cast #spinner to HtmlElement")
 | 
			
		||||
        .style();
 | 
			
		||||
    style
 | 
			
		||||
        .set_property("display", "inline-block")
 | 
			
		||||
        .expect("Failed to edit #spinner's CSS");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn hide_spinner() {
 | 
			
		||||
    let result = document()
 | 
			
		||||
        .get_element_by_id("spinner")
 | 
			
		||||
        .expect("#spinner not found");
 | 
			
		||||
    let style = result
 | 
			
		||||
        .dyn_ref::<HtmlElement>()
 | 
			
		||||
        .expect("Failed to cast #spinner to HtmlElement")
 | 
			
		||||
        .style();
 | 
			
		||||
    style
 | 
			
		||||
        .set_property("display", "none")
 | 
			
		||||
        .expect("Failed to edit #spinner's CSS");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn hide_ask_dict() {
 | 
			
		||||
    let result = document()
 | 
			
		||||
        .get_element_by_id("ask_dict")
 | 
			
		||||
        .expect("#ask_dic not found");
 | 
			
		||||
    let style = result
 | 
			
		||||
        .dyn_ref::<HtmlElement>()
 | 
			
		||||
        .expect("Failed to cast #ask_dict to HtmlElement")
 | 
			
		||||
        .style();
 | 
			
		||||
    console::log_1(&style);
 | 
			
		||||
    style
 | 
			
		||||
        .set_property("display", "none")
 | 
			
		||||
        .expect("Failed to edit #ask_dict's CSS");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn update_letters() {
 | 
			
		||||
    let el = document()
 | 
			
		||||
        .get_element_by_id("select_word")
 | 
			
		||||
        .expect("#select_word not found");
 | 
			
		||||
    let val = el
 | 
			
		||||
        .dyn_ref::<HtmlInputElement>()
 | 
			
		||||
        .expect("Failed to dyn cast to HtmlInputElement")
 | 
			
		||||
        .value();
 | 
			
		||||
    let result = document()
 | 
			
		||||
        .get_element_by_id("result")
 | 
			
		||||
        .expect("#result not found");
 | 
			
		||||
    while let Some(child) = result.first_element_child() {
 | 
			
		||||
        child.remove();
 | 
			
		||||
    }
 | 
			
		||||
    DICTIONNARY
 | 
			
		||||
        .lock()
 | 
			
		||||
        .expect("Failed to access DICTIONNARY")
 | 
			
		||||
        .as_ref()
 | 
			
		||||
        .map(|dict| dict.find(&val))
 | 
			
		||||
        .flatten()
 | 
			
		||||
        .map(|anagrms| {
 | 
			
		||||
            for anagram in anagrms {
 | 
			
		||||
                let val = document().create_element("li").unwrap();
 | 
			
		||||
                val.set_text_content(Some(&anagram));
 | 
			
		||||
                result.append_child(&val).unwrap();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn load_dict(text: JsValue) {
 | 
			
		||||
    display_spinner();
 | 
			
		||||
    let text = text.as_string().expect("Failed to get content of the file");
 | 
			
		||||
    let el = document()
 | 
			
		||||
        .get_element_by_id("nb_wild_card")
 | 
			
		||||
        .expect("#nb_wild_card not found");
 | 
			
		||||
    let nb_wild_card = el
 | 
			
		||||
        .dyn_ref::<HtmlInputElement>()
 | 
			
		||||
        .expect("Failed to dyn cast #nb_wild_card to HtmlInputElement")
 | 
			
		||||
        .value();
 | 
			
		||||
    console::log_1(&(&nb_wild_card).into());
 | 
			
		||||
    let dict = Dict::load_from_str(
 | 
			
		||||
        &text,
 | 
			
		||||
        nb_wild_card
 | 
			
		||||
            .parse()
 | 
			
		||||
            .expect("#nb_wild_card should be an interger"),
 | 
			
		||||
        '?',
 | 
			
		||||
    );
 | 
			
		||||
    *DICTIONNARY.lock().expect("Failed to access DICTIONNARY") = Some((&dict).into());
 | 
			
		||||
    hide_spinner();
 | 
			
		||||
    hide_ask_dict();
 | 
			
		||||
    update_letters();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Called when the wasm module is instantiated
 | 
			
		||||
#[wasm_bindgen(start)]
 | 
			
		||||
fn main() -> Result<(), JsValue> {
 | 
			
		||||
    let load_dict_c1 = Closure::<dyn FnMut(_)>::new(move |text: JsValue| load_dict(text));
 | 
			
		||||
    let load_dict_c2 = Closure::<dyn FnMut(_)>::new(move |text: JsValue| load_dict(text));
 | 
			
		||||
 | 
			
		||||
    let update_dict = Closure::<dyn FnMut(_)>::new(move |event: Event| {
 | 
			
		||||
        display_spinner();
 | 
			
		||||
        let target = event.target().expect("No target");
 | 
			
		||||
        let _ = target
 | 
			
		||||
            .dyn_ref::<HtmlInputElement>()
 | 
			
		||||
            .expect("Failed to dyn cast to HtmlInputElement")
 | 
			
		||||
            .files()
 | 
			
		||||
            .expect("Failed to get files")
 | 
			
		||||
            .get(0)
 | 
			
		||||
            .expect("Failed to get first file")
 | 
			
		||||
            .text()
 | 
			
		||||
            .then(&load_dict_c1);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    let update_nb_wild_card = Closure::<dyn FnMut(_)>::new(move |_: Event| {
 | 
			
		||||
        let el = document()
 | 
			
		||||
            .get_element_by_id("upload_dict")
 | 
			
		||||
            .expect("#upload_dict not found");
 | 
			
		||||
        let files = el
 | 
			
		||||
            .dyn_ref::<HtmlInputElement>()
 | 
			
		||||
            .expect("Failed to dyn cast to HtmlInputElement")
 | 
			
		||||
            .files()
 | 
			
		||||
            .expect("Failed to get files");
 | 
			
		||||
        if files.length() > 0 {
 | 
			
		||||
            display_spinner();
 | 
			
		||||
            let _ = files
 | 
			
		||||
                .get(0)
 | 
			
		||||
                .expect("Failed to get first file")
 | 
			
		||||
                .text()
 | 
			
		||||
                .then(&load_dict_c2);
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    let update_letters_closure = Closure::<dyn FnMut(_)>::new(|_: Event| update_letters());
 | 
			
		||||
 | 
			
		||||
    let input_dict = document()
 | 
			
		||||
        .get_element_by_id("upload_dict")
 | 
			
		||||
        .expect("#upload_dict not found");
 | 
			
		||||
    input_dict
 | 
			
		||||
        .dyn_ref::<HtmlInputElement>()
 | 
			
		||||
        .expect("#upload_dict must be an <input type='file'>")
 | 
			
		||||
        .add_event_listener_with_callback("change", update_dict.as_ref().unchecked_ref())
 | 
			
		||||
        .expect("Failed to register event listener to #upload_dict");
 | 
			
		||||
    let input_text = document()
 | 
			
		||||
        .get_element_by_id("select_word")
 | 
			
		||||
        .expect("#select_word not found");
 | 
			
		||||
    input_text
 | 
			
		||||
        .dyn_ref::<HtmlInputElement>()
 | 
			
		||||
        .expect("#select_word must be an <input type='text'>")
 | 
			
		||||
        .add_event_listener_with_callback("input", update_letters_closure.as_ref().unchecked_ref())
 | 
			
		||||
        .expect("Failed to register event listener to #select_word");
 | 
			
		||||
    let nb_wild_card = document()
 | 
			
		||||
        .get_element_by_id("nb_wild_card")
 | 
			
		||||
        .expect("#nb_wild_card not found");
 | 
			
		||||
    nb_wild_card
 | 
			
		||||
        .dyn_ref::<HtmlInputElement>()
 | 
			
		||||
        .expect("#nb_wild_card must be an <input type='numver'>")
 | 
			
		||||
        .add_event_listener_with_callback("change", update_nb_wild_card.as_ref().unchecked_ref())
 | 
			
		||||
        .expect("Failed to register event listener to #nb_wild_card");
 | 
			
		||||
 | 
			
		||||
    update_dict.forget(); // The callback will invalidate when the closure is dropped, this prevent it,
 | 
			
		||||
                          // at the cost of a "memory leak"
 | 
			
		||||
    update_letters_closure.forget();
 | 
			
		||||
    update_nb_wild_card.forget();
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue