Compare commits

...

3 commits

Author SHA1 Message Date
Yash Karandikar c921ed1ebd
Add README.md 2022-04-25 11:53:46 -05:00
Yash Karandikar e2bfe635a9
More UX changes 2022-04-25 11:36:22 -05:00
Yash Karandikar 93818956a7
Add ability to modify current dec 2022-04-25 11:14:57 -05:00
3 changed files with 83 additions and 11 deletions

23
quicksilver/README.md Normal file
View file

@ -0,0 +1,23 @@
# Quicksilver
[Live App](https://etc.karx.xyz/rgl/quicksilver/)
## Running Locally
1. Install dependencies
First, install `rust` from [the Rust website](https://www.rust-lang.org/). Then, install `trunk`:
```bash
cargo install --locked trunk
```
This project requires `rustc` version `1.60.0 stable` because it uses the 2021 edition of Rust and sycamore 0.8!
2. Build project
```bash
cd /path/to/quicksilver
trunk serve
```
3. Open in browser
[Check the supported browser list](https://rustwasm.github.io/docs/wasm-bindgen/reference/browser-support.html) and open https://localhost:8080 in one of the supported browsers.
<small>Created using [Sycamore](https://crates.io/crates/sycamore) and Rust with WebAssembly</small>

View file

@ -4,6 +4,12 @@ function get_token() {
return token;
}
function get_edit_token() {
let params = new URLSearchParams(document.location.search);
let token = params.get("edit");
return token;
}
function set_location(l) {
window.location = l;
}

View file

@ -43,6 +43,7 @@ struct Card {
}
wasm_import!(get_token() -> Option<String>);
wasm_import!(get_edit_token() -> Option<String>);
wasm_import!(prompt(s: &str) -> Option<String>);
wasm_import!(set_location(l: &str));
wasm_import!(alert(s: &str));
@ -82,9 +83,15 @@ fn CardsComponent<G: Html>(ctx: Scope) -> View<G> {
let go_home = |_| set_location("/");
let go_modify = move |_| {
let location = format!("/?edit={}", token);
set_location(&location);
};
view! {ctx,
div(class="text-align-center") {
button(on:click=go_home) { "Home" }
button(on:click=go_modify) { "Edit Deck" }
button(on:click=recompute_current) { "Next" }
}
({
@ -107,6 +114,25 @@ fn CardsComponent<G: Html>(ctx: Scope) -> View<G> {
#[component]
fn CreatorComponent<G: Html>(ctx: Scope) -> View<G> {
let front = create_signal(ctx, String::new());
let back = create_signal(ctx, String::new());
let error_empty = create_signal(ctx, false);
let error_parse = create_signal(ctx, false);
let cards = create_signal(ctx, Vec::new());
if let Some(token) = get_edit_token() {
let stripped = token
.chars()
.filter(|c| !c.is_whitespace())
.collect::<String>();
let decoded = base64::decode(stripped.as_bytes()).unwrap_or_default();
let parsed = String::from_utf8(decoded).unwrap_or_default();
let items: Vec<Card> = serde_json::from_str(&parsed).unwrap_or_default();
*cards.modify() = items;
}
let do_import = |_| {
let p = prompt("Deck code:");
if let Some(inp) = p {
@ -119,14 +145,6 @@ fn CreatorComponent<G: Html>(ctx: Scope) -> View<G> {
}
};
let front = create_signal(ctx, String::new());
let back = create_signal(ctx, String::new());
let error_empty = create_signal(ctx, false);
let error_parse = create_signal(ctx, false);
let cards = create_signal(ctx, Vec::new());
let do_add = |_| {
let f = (*front.get()).clone();
let b = (*back.get()).clone();
@ -163,9 +181,33 @@ fn CreatorComponent<G: Html>(ctx: Scope) -> View<G> {
}
};
let do_use_current = |_| {
let d = Deck((*cards.get()).clone());
if d.is_empty() {
return;
}
let r = serde_json::to_string(&d);
if let Ok(s) = r {
error_parse.set(false);
let e = base64::encode(s.as_bytes());
let f = format!("/?deck={}", e);
set_location(&f);
} else {
error_parse.set(true);
}
};
let do_delete_last = |_| {
cards.modify().pop();
};
view! {ctx,
div(class="text-align-center") {
button(on:click=do_import) {"Import"}
button(on:click=do_use_current) {"Use Current Deck"}
button(on:click=do_export) {"Export"}
br
input(bind:value=front)
@ -181,14 +223,15 @@ fn CreatorComponent<G: Html>(ctx: Scope) -> View<G> {
view! {ctx,}
})
button(on:click=do_add) {"Add"}
button(on:click=do_delete_last) {"Delete Last"}
Indexed {
iterable: cards,
view: |ctx, card| view! {ctx,
div(class="card", style="background-color: white;") {
"Front:"
div(class="card", style="background-color: white; padding: 5px; transform: none") {
"Front: "
(card.front)
br
"Back:"
"Back: "
(card.back)
}
}