Add support for listing and creating notes
This commit is contained in:
parent
6309c90f34
commit
2bd64cfb8a
|
@ -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" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,4 +2,14 @@
|
|||
margin: auto;
|
||||
width: 60%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.pull-right {
|
||||
text-align: right;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.pull-left {
|
||||
text-align: left;
|
||||
border: 0;
|
||||
}
|
|
@ -1,3 +1,11 @@
|
|||
function listLocalStorageKeys() {
|
||||
return Object.keys(localStorage);
|
||||
}
|
||||
|
||||
function getCurrentTimeMillis() {
|
||||
return Date.now();
|
||||
}
|
||||
|
||||
function timeHR(millis) {
|
||||
return new Date(millis).toLocaleString();
|
||||
}
|
Loading…
Reference in a new issue