bazzar/web/src/lib.rs

168 lines
4.9 KiB
Rust
Raw Normal View History

2022-05-15 10:30:15 +02:00
#![feature(try_trait_v2)]
2022-05-09 16:17:27 +02:00
pub mod api;
2022-05-15 13:08:42 +02:00
#[cfg(debug_assertions)]
mod debug;
2022-05-10 08:23:35 +02:00
mod i18n;
2022-05-05 16:30:25 +02:00
mod model;
mod pages;
2022-05-15 10:30:15 +02:00
pub mod session;
2022-05-09 16:41:11 +02:00
pub mod shared;
2022-05-15 14:05:26 +02:00
pub mod shopping_cart;
2022-05-05 16:30:25 +02:00
use seed::empty;
use seed::prelude::*;
use crate::i18n::I18n;
2022-05-09 16:17:27 +02:00
use crate::model::Model;
2022-05-05 16:30:25 +02:00
use crate::pages::{Msg, Page, PublicPage};
2022-05-15 10:30:15 +02:00
use crate::session::SessionMsg;
2022-05-05 16:30:25 +02:00
2022-05-11 15:56:41 +02:00
#[macro_export]
2022-05-09 16:17:27 +02:00
macro_rules! fetch_page {
(public $model: expr, $page: ident, $ret: expr) => {{
let p = match &mut $model.page {
crate::pages::Page::Public(p) => p,
_ => return $ret,
};
match p {
crate::pages::PublicPage::$page(p) => p,
_ => return $ret,
}
}};
2022-05-11 15:56:41 +02:00
(public $model: expr, $page: ident) => {{
let p = match &mut $model.page {
crate::pages::Page::Public(p) => p,
_ => return,
};
match p {
crate::pages::PublicPage::$page(p) => p,
_ => return,
}
}};
(public page $page: expr, $page_name: ident) => {{
let p = match $page {
crate::pages::Page::Public(p) => p,
_ => return,
};
match p {
crate::pages::PublicPage::$page_name(p) => p,
_ => return,
}
}};
2022-05-12 08:38:31 +02:00
(public page $page: expr, $page_name: ident, $ret: expr) => {{
let p = match $page {
crate::pages::Page::Public(p) => p,
_ => {
*$page = $ret;
return;
}
};
match p {
crate::pages::PublicPage::$page_name(p) => p,
_ => {
*$page = $ret;
return;
}
}
}};
2022-05-09 16:17:27 +02:00
}
2022-05-05 16:30:25 +02:00
fn init(url: Url, orders: &mut impl Orders<Msg>) -> Model {
2022-05-15 10:30:15 +02:00
orders.subscribe(Msg::UrlChanged);
2022-05-10 16:20:37 +02:00
2022-05-15 10:30:15 +02:00
let mut model = Model {
2022-05-11 15:56:41 +02:00
url: url.clone().set_path(&[] as &[&str]),
2022-05-05 16:30:25 +02:00
token: LocalStorage::get("auth-token").ok(),
2022-05-11 15:56:41 +02:00
page: Page::init(url, orders),
2022-05-10 16:20:37 +02:00
logo: seed::document()
.query_selector("link[rel=icon]")
.ok()
.flatten()
.and_then(|el: web_sys::Element| el.get_attribute("href")),
shared: shared::Model::default(),
i18n: I18n::load(),
2022-05-15 14:05:26 +02:00
cart: Default::default(),
2022-05-15 13:08:42 +02:00
#[cfg(debug_assertions)]
debug_modal: false,
2022-05-15 10:30:15 +02:00
};
2022-05-15 14:05:26 +02:00
shopping_cart::init(&mut model, orders);
2022-05-15 10:30:15 +02:00
session::init(&mut model, orders);
2022-05-15 13:08:42 +02:00
shared::init(&mut model, orders);
#[cfg(debug_assertions)]
crate::debug::init(&mut model, orders);
2022-05-15 10:30:15 +02:00
model
2022-05-05 16:30:25 +02:00
}
fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
match msg {
2022-05-15 13:08:42 +02:00
#[cfg(debug_assertions)]
Msg::NoOp => {
orders.skip();
}
2022-05-10 16:20:37 +02:00
Msg::Shared(msg) => {
2022-05-15 14:05:26 +02:00
shared::update(msg, model, orders);
2022-05-10 16:20:37 +02:00
}
2022-05-12 08:38:31 +02:00
Msg::UrlChanged(subs::UrlChanged(url)) => model.page.page_changed(url, orders),
2022-05-09 16:17:27 +02:00
Msg::Public(pages::public::Msg::Listing(msg)) => {
2022-05-11 15:56:41 +02:00
let page = fetch_page!(public model, Listing);
2022-05-13 15:24:11 +02:00
pages::public::listing::update(msg, page, &mut orders.proxy(Into::into));
2022-05-09 16:17:27 +02:00
}
2022-05-11 15:56:41 +02:00
Msg::Public(pages::public::Msg::Product(msg)) => {
let page = fetch_page!(public model, Product);
2022-05-13 15:24:11 +02:00
pages::public::product::update(msg, page, &mut orders.proxy(Into::into))
2022-05-11 15:56:41 +02:00
}
2022-05-13 15:24:11 +02:00
Msg::Public(pages::public::Msg::SignIn(msg)) => {
let page = fetch_page!(public model, SignIn);
pages::public::sign_in::update(msg, page, &mut orders.proxy(Into::into))
}
2022-05-15 10:30:15 +02:00
Msg::Public(pages::public::Msg::SignUp(pages::public::sign_up::Msg::AccountCreated(
res,
))) => {
orders
.skip()
.send_msg(Msg::Session(SessionMsg::TokenRefreshed(res)));
}
2022-05-13 15:24:11 +02:00
Msg::Public(pages::public::Msg::SignUp(msg)) => {
let page = fetch_page!(public model, SignUp);
pages::public::sign_up::update(msg, page, &mut orders.proxy(Into::into))
}
Msg::Admin(_) => {}
2022-05-15 10:30:15 +02:00
Msg::Session(msg) => {
session::update(msg, model, orders);
}
2022-05-15 13:08:42 +02:00
#[cfg(debug_assertions)]
Msg::Debug(msg) => {
2022-05-15 19:33:06 +02:00
debug::update(msg, model);
}
Msg::Cart(msg) => {
shopping_cart::update(msg, model, orders);
2022-05-15 13:08:42 +02:00
}
2022-05-05 16:30:25 +02:00
}
}
fn view(model: &Model) -> Node<Msg> {
2022-05-15 13:08:42 +02:00
let view = match &model.page {
2022-05-11 15:56:41 +02:00
Page::Public(PublicPage::Listing(page)) => pages::public::listing::view(model, page),
Page::Public(PublicPage::Product(page)) => pages::public::product::view(model, page),
2022-05-13 15:24:11 +02:00
Page::Public(PublicPage::SignIn(page)) => pages::public::sign_in::view(model, page),
Page::Public(PublicPage::SignUp(page)) => pages::public::sign_up::view(model, page),
2022-05-05 16:30:25 +02:00
_ => empty![],
2022-05-15 13:08:42 +02:00
};
if cfg!(debug_assertions) {
use seed::*;
div![crate::debug::view(model), view]
} else {
view
2022-05-05 16:30:25 +02:00
}
}
#[wasm_bindgen(start)]
pub fn start() {
App::start("main", init, update, view);
}