Add wasm live rendering of the Qr-Code only svg
This commit is contained in:
parent
a5cfdeff54
commit
6b0daecd31
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -465,6 +465,7 @@ version = "0.3.1"
|
||||
dependencies = [
|
||||
"enum-map",
|
||||
"fluent 0.15.0",
|
||||
"qrcode",
|
||||
"seed",
|
||||
"serde",
|
||||
"shared",
|
||||
|
@ -23,5 +23,6 @@ unic-langid = "0.9"
|
||||
strum_macros = "0.20"
|
||||
strum = "0.20"
|
||||
enum-map = "1"
|
||||
qrcode = "0.12"
|
||||
|
||||
shared = { path = "../shared" }
|
||||
|
@ -4,14 +4,9 @@ pub mod pages;
|
||||
|
||||
use pages::list_links;
|
||||
use pages::list_users;
|
||||
use seed::attrs;
|
||||
use seed::button;
|
||||
use seed::input;
|
||||
use seed::label;
|
||||
use seed::{div, log, prelude::*, App, Url, C};
|
||||
use seed::{attrs, button, div, input, label, log, prelude::*, App, Url, C};
|
||||
use shared::apirequests::users::LoginUser;
|
||||
use shared::datatypes::Loadable;
|
||||
use shared::datatypes::User;
|
||||
use shared::datatypes::{Loadable, User};
|
||||
|
||||
use crate::i18n::{I18n, Lang};
|
||||
|
||||
@ -23,13 +18,14 @@ fn init(url: Url, orders: &mut impl Orders<Msg>) -> Model {
|
||||
orders.subscribe(Msg::UrlChanged);
|
||||
orders.send_msg(Msg::GetLoggedUser);
|
||||
|
||||
log!(url);
|
||||
log!(&url);
|
||||
|
||||
let lang = I18n::new(Lang::EnUS);
|
||||
|
||||
Model {
|
||||
index: 0,
|
||||
base_url: Url::new().add_path_part("app"),
|
||||
current_url: url.clone(),
|
||||
page: Page::init(url, orders, lang.clone()),
|
||||
i18n: lang,
|
||||
user: Loadable::Data(None),
|
||||
@ -46,6 +42,7 @@ fn init(url: Url, orders: &mut impl Orders<Msg>) -> Model {
|
||||
struct Model {
|
||||
index: usize,
|
||||
base_url: Url,
|
||||
current_url: Url,
|
||||
page: Page,
|
||||
i18n: i18n::I18n,
|
||||
user: Loadable<User>,
|
||||
@ -100,6 +97,7 @@ pub enum Msg {
|
||||
UserReceived(User),
|
||||
NoMessage,
|
||||
NotAuthenticated,
|
||||
Logout,
|
||||
Login,
|
||||
UsernameChanged(String),
|
||||
PasswordChanged(String),
|
||||
@ -122,31 +120,38 @@ fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
}
|
||||
Msg::NoMessage => (),
|
||||
Msg::GetLoggedUser => {
|
||||
orders.skip(); // No need to rerender
|
||||
model.user = Loadable::Loading;
|
||||
orders.perform_cmd(async {
|
||||
// create request
|
||||
let request = unwrap_or_return!(
|
||||
Request::new("/admin/json/get_logged_user/")
|
||||
.method(Method::Post)
|
||||
.json(&()),
|
||||
Msg::NotAuthenticated
|
||||
Msg::Logout
|
||||
);
|
||||
// perform and get response
|
||||
let response = unwrap_or_return!(fetch(request).await, Msg::NotAuthenticated);
|
||||
let response = unwrap_or_return!(fetch(request).await, Msg::Logout);
|
||||
// validate response status
|
||||
let response = unwrap_or_return!(response.check_status(), Msg::NotAuthenticated);
|
||||
let user: User = unwrap_or_return!(response.json().await, Msg::NotAuthenticated);
|
||||
let response = unwrap_or_return!(response.check_status(), Msg::Logout);
|
||||
let user: User = unwrap_or_return!(response.json().await, Msg::Logout);
|
||||
|
||||
Msg::UserReceived(user)
|
||||
});
|
||||
}
|
||||
Msg::UserReceived(user) => model.user = Loadable::Data(Some(user)),
|
||||
Msg::UserReceived(user) => {
|
||||
model.user = Loadable::Data(Some(user));
|
||||
model.page = Page::init(model.current_url.clone(), orders, model.i18n.clone());
|
||||
}
|
||||
Msg::NotAuthenticated => {
|
||||
if model.user.is_some() {
|
||||
model.user = Loadable::Data(None);
|
||||
logout(orders)
|
||||
}
|
||||
}
|
||||
Msg::Logout => {
|
||||
model.user = Loadable::Data(None);
|
||||
logout(orders)
|
||||
}
|
||||
Msg::Login => login_user(model, orders),
|
||||
Msg::UsernameChanged(s) => model.login_data.username = s,
|
||||
Msg::PasswordChanged(s) => model.login_data.password = s,
|
||||
@ -162,7 +167,7 @@ fn logout(orders: &mut impl Orders<Msg>) {
|
||||
}
|
||||
|
||||
fn login_user(model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
orders.skip(); // No need to rerender
|
||||
model.user = Loadable::Loading;
|
||||
let data = model.login_data.clone();
|
||||
|
||||
orders.perform_cmd(async {
|
||||
@ -245,13 +250,13 @@ impl<'a> Urls<'a> {
|
||||
fn view(model: &Model) -> Node<Msg> {
|
||||
div![
|
||||
C!["page"],
|
||||
if let Some(ref user) = *model.user {
|
||||
div![
|
||||
match model.user {
|
||||
Loadable::Data(Some(ref user)) => div![
|
||||
navigation::navigation(&model.i18n, &model.base_url, user),
|
||||
view_content(&model.page, &model.base_url)
|
||||
]
|
||||
} else {
|
||||
view_login(&model.i18n, model)
|
||||
],
|
||||
Loadable::Data(None) => view_login(&model.i18n, model),
|
||||
Loadable::Loading => div![C!("lds-ellipsis"), div!(), div!(), div!(), div!()],
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -2,9 +2,10 @@ use std::cell::RefCell;
|
||||
|
||||
use enum_map::EnumMap;
|
||||
use fluent::fluent_args;
|
||||
use qrcode::{render::svg, QrCode};
|
||||
use seed::{
|
||||
a, attrs, button, div, h1, img, input, log, prelude::*, section, span, table, td, th, tr, Url,
|
||||
C,
|
||||
a, attrs, button, div, h1, img, input, log, prelude::*, raw, section, span, table, td, th, tr,
|
||||
Url, C,
|
||||
};
|
||||
|
||||
use shared::{
|
||||
@ -508,7 +509,7 @@ fn view_link_table_filter_input<F: Fn(&str) -> String>(model: &Model, t: F) -> N
|
||||
]
|
||||
}
|
||||
|
||||
/// display a single link
|
||||
/// display a single table row containing one link
|
||||
fn view_link(l: &FullLink) -> Node<Msg> {
|
||||
// Ugly hack - this is needed to be able to move the l into the closures... l.clone() in place does not work.
|
||||
let link = LinkDelta::from(l.clone());
|
||||
@ -598,6 +599,10 @@ fn edit_or_create_link<F: Fn(&str) -> String>(l: &RefCell<LinkDelta>, t: F) -> N
|
||||
},
|
||||
input_ev(Ev::Input, |s| { Msg::Edit(EditMsg::EditCodeChanged(s)) }),
|
||||
],]
|
||||
],
|
||||
tr![
|
||||
th![t("qr-code")],
|
||||
td![raw!(&generate_qr_code(&format!("http://{}", &link.code)))]
|
||||
]
|
||||
],
|
||||
a![
|
||||
@ -611,6 +616,20 @@ fn edit_or_create_link<F: Fn(&str) -> String>(l: &RefCell<LinkDelta>, t: F) -> N
|
||||
]
|
||||
}
|
||||
|
||||
fn generate_qr_code(link: &str) -> String {
|
||||
if let Ok(qr) = QrCode::with_error_correction_level(&link, qrcode::EcLevel::L) {
|
||||
let svg = qr
|
||||
.render()
|
||||
.min_dimensions(100, 100)
|
||||
.dark_color(svg::Color("#000000"))
|
||||
.light_color(svg::Color("#ffffff"))
|
||||
.build();
|
||||
svg
|
||||
} else {
|
||||
"".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// a close button for dialogs
|
||||
fn close_button() -> Node<Msg> {
|
||||
div![
|
||||
|
Loading…
Reference in New Issue
Block a user