Add support for listing and creating notes

This commit is contained in:
Yash Karandikar 2021-10-23 20:28:19 -05:00
parent 6309c90f34
commit 2bd64cfb8a
Signed by: karx
GPG key ID: A794DA2529474BA5
4 changed files with 111 additions and 4 deletions

View file

@ -1,9 +1,33 @@
use sycamore::prelude::*;
use wasm_bindgen::prelude::*;
use crate::local_storage;
use crate::{local_storage, AppMode};
#[derive(Clone, Debug)]
pub struct DefaultViewProps {
mode: Signal<AppMode>,
selected: Signal<String>,
}
impl DefaultViewProps {
pub fn new(mode: Signal<AppMode>, selected: Signal<String>) -> Self {
Self { mode, selected }
}
}
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_name = getCurrentTimeMillis)]
fn get_current_time_millis() -> usize;
#[wasm_bindgen(js_name = timeHR)]
fn time_hr(millis: usize) -> String;
}
#[component(DefaultView<G>)]
pub fn default_view() -> Template<G> {
pub fn default_view(props: DefaultViewProps) -> Template<G> {
let mode = props.clone().mode;
let selected = props.clone().selected;
let templates = Template::new_fragment({
let mut new_vec: Vec<Template<G>> = Vec::new();
@ -20,10 +44,63 @@ pub fn default_view() -> Template<G> {
new_vec
});
let start_create = cloned!((mode, selected) => move |_| {
let timestamp = format!("{}", get_current_time_millis());
selected.set(timestamp);
mode.set(AppMode::Create);
});
template! {
div(class="pull-right") {
button(on:click=start_create) { "Create" }
}
ul {
(templates)
}
}
}
#[derive(Clone, Debug)]
pub struct CreateViewProps {
mode: Signal<AppMode>,
selected: StateHandle<String>,
}
impl CreateViewProps {
pub fn new(mode: Signal<AppMode>, selected: StateHandle<String>) -> Self {
Self { mode, selected }
}
}
#[component(CreateView<G>)]
pub fn create_view(props: CreateViewProps) -> Template<G> {
let value = Signal::new(String::new());
let mode = props.clone().mode;
let selected = props.clone().selected;
let save = cloned!((mode, selected, value) => move |_| {
let timestamp = &*selected.get();
let note = &*value.get();
local_storage::set_item(timestamp, note);
mode.set(AppMode::Default); // Return to default screen
});
let go_back = cloned!((mode) => move |_| {
mode.set(AppMode::Default); // Return to default screen
});
template! {
div(class="pull-left") {
button(on:click=go_back) { "Go Back" }
}
div(style="display: flex; flex-direction: column; height: 75vh") {
textarea(bind:value=value, style="resize: vertical; flex-grow: 1")
br
div(style="text-align: center;") {
button(on:click=save) { "Save" }
}
}
}
}

View file

@ -1,3 +1,5 @@
#![allow(unreachable_patterns)] // Because we can exhaust AppModes in the `match`
mod components;
mod console;
mod local_storage;
@ -9,20 +11,30 @@ macro_rules! log {
($($t:tt)*) => (console::log_raw(&format_args!($($t)*).to_string()))
}
#[derive(Debug)]
#[allow(unused)] // temp
pub enum AppMode {
Default // note list view
Default, // note list view
Create, // note create view (might be merged into edit)
}
fn main() {
use crate::components::*;
let mode = Signal::new(AppMode::Default);
let selected = Signal::new(String::new());
sycamore::render(|| template! {
h1(style="text-align: center") { "NoteRS" }
div(class="wrapper") {
(match *mode.get() {
AppMode::Default => template! {
crate::components::DefaultView()
DefaultView(DefaultViewProps::new(cloned!((mode) => mode), cloned!((selected) => selected)))
},
AppMode::Create => template! {
CreateView(CreateViewProps::new(cloned!((mode) => mode), cloned!((selected) => selected.handle())))
},
_ => template! {
DefaultView(DefaultViewProps::new(cloned!((mode) => mode), cloned!((selected) => selected)))
}
})
}

View file

@ -2,4 +2,14 @@
margin: auto;
width: 60%;
padding: 10px;
}
.pull-right {
text-align: right;
border: 0;
}
.pull-left {
text-align: left;
border: 0;
}

View file

@ -1,3 +1,11 @@
function listLocalStorageKeys() {
return Object.keys(localStorage);
}
function getCurrentTimeMillis() {
return Date.now();
}
function timeHR(millis) {
return new Date(millis).toLocaleString();
}