* Support for lang in URL as /fr/recipe/view/42
* Create a pages module in the frontend crate
This commit is contained in:
parent
b812525f4b
commit
418d31a127
12 changed files with 117 additions and 80 deletions
51
Cargo.lock
generated
51
Cargo.lock
generated
|
|
@ -330,9 +330,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.16"
|
version = "1.2.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c"
|
checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
|
@ -537,9 +537,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deranged"
|
name = "deranged"
|
||||||
version = "0.4.0"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
|
checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"powerfmt",
|
"powerfmt",
|
||||||
]
|
]
|
||||||
|
|
@ -1226,14 +1226,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
version = "0.1.61"
|
version = "0.1.62"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
|
checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android_system_properties",
|
"android_system_properties",
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
"iana-time-zone-haiku",
|
"iana-time-zone-haiku",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
|
"log",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-core",
|
"windows-core",
|
||||||
]
|
]
|
||||||
|
|
@ -1512,9 +1513,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.26"
|
version = "0.4.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
|
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchers"
|
name = "matchers"
|
||||||
|
|
@ -1829,7 +1830,7 @@ version = "0.2.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy 0.8.23",
|
"zerocopy 0.8.24",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1906,7 +1907,7 @@ checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_chacha 0.9.0",
|
"rand_chacha 0.9.0",
|
||||||
"rand_core 0.9.3",
|
"rand_core 0.9.3",
|
||||||
"zerocopy 0.8.23",
|
"zerocopy 0.8.24",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2165,9 +2166,9 @@ checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
version = "0.103.0"
|
version = "0.103.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f"
|
checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
|
|
@ -2664,9 +2665,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.19.0"
|
version = "3.19.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "488960f40a3fd53d72c2a29a58722561dee8afdd175bd88e3db4677d7b2ba600"
|
checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"getrandom 0.3.2",
|
"getrandom 0.3.2",
|
||||||
|
|
@ -2727,9 +2728,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.3.40"
|
version = "0.3.41"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9d9c75b47bdff86fa3334a3db91356b8d7d86a9b839dab7d0bdc5c3d3a077618"
|
checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deranged",
|
"deranged",
|
||||||
"itoa",
|
"itoa",
|
||||||
|
|
@ -2748,9 +2749,9 @@ checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time-macros"
|
name = "time-macros"
|
||||||
version = "0.2.21"
|
version = "0.2.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "29aa485584182073ed57fd5004aa09c371f021325014694e432313345865fd04"
|
checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-conv",
|
"num-conv",
|
||||||
"time-core",
|
"time-core",
|
||||||
|
|
@ -3194,9 +3195,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "whoami"
|
name = "whoami"
|
||||||
version = "1.5.2"
|
version = "1.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d"
|
checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"wasite",
|
"wasite",
|
||||||
|
|
@ -3462,11 +3463,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.8.23"
|
version = "0.8.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6"
|
checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy-derive 0.8.23",
|
"zerocopy-derive 0.8.24",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3482,9 +3483,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy-derive"
|
name = "zerocopy-derive"
|
||||||
version = "0.8.23"
|
version = "0.8.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154"
|
checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
||||||
4
TODO.md
4
TODO.md
|
|
@ -8,13 +8,15 @@
|
||||||
* Default number is the user setting user.default_servings
|
* Default number is the user setting user.default_servings
|
||||||
* A symbol show the native recipe servings number
|
* A symbol show the native recipe servings number
|
||||||
* Check position of message error in profile/sign in/sign up with flex grid layout
|
* Check position of message error in profile/sign in/sign up with flex grid layout
|
||||||
|
* Replace Rinja by Askama when Askma 0.13 is out (Rinja has been merged with Askama)
|
||||||
* Define the UI (mockups).
|
* Define the UI (mockups).
|
||||||
* Two CSS: one for desktop and one for mobile
|
* Two CSS: one for desktop and one for mobile
|
||||||
* Use CSS flex/grid to define a good design/layout
|
* Use CSS flex/grid to define a good design/layout
|
||||||
* CSS for dark mode + autodetect
|
* CSS for dark mode + autodetect
|
||||||
* CSS for toast and modal dialog
|
* CSS for toast and modal dialog
|
||||||
* Calendar: Choose the first day of the week
|
* Calendar: Choose the first day of the week
|
||||||
* i18n: prefix uri with the language: /fr/recipe/view/2
|
* i18n: prefix uri with the language: /fr/recipe/view/2 (do it for all intern href)
|
||||||
|
* Redirect with the correct prefix when the current language is changed
|
||||||
* Make a search page
|
* Make a search page
|
||||||
Use FTS5:
|
Use FTS5:
|
||||||
https://sqlite.org/fts5.html
|
https://sqlite.org/fts5.html
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
use std::{net::SocketAddr, path::Path};
|
use std::{net::SocketAddr, path::Path};
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
BoxError, Router,
|
BoxError, Router, ServiceExt,
|
||||||
error_handling::HandleErrorLayer,
|
error_handling::HandleErrorLayer,
|
||||||
extract::{ConnectInfo, Extension, FromRef, Request, State},
|
extract::{ConnectInfo, Extension, FromRef, Request, State},
|
||||||
http::StatusCode,
|
http::{StatusCode, Uri},
|
||||||
middleware::{self, Next},
|
middleware::{self, Next},
|
||||||
response::Response,
|
response::Response,
|
||||||
routing::{delete, get, patch, post, put},
|
routing::{delete, get, patch, post, put},
|
||||||
|
|
@ -14,6 +14,7 @@ use chrono::prelude::*;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use tower::layer::Layer;
|
||||||
use tower::{ServiceBuilder, buffer::BufferLayer, limit::RateLimitLayer};
|
use tower::{ServiceBuilder, buffer::BufferLayer, limit::RateLimitLayer};
|
||||||
use tower_http::{
|
use tower_http::{
|
||||||
services::{ServeDir, ServeFile},
|
services::{ServeDir, ServeFile},
|
||||||
|
|
@ -290,13 +291,20 @@ async fn main() {
|
||||||
.with_state(state)
|
.with_state(state)
|
||||||
.nest_service("/favicon.ico", ServeFile::new("static/favicon.ico"))
|
.nest_service("/favicon.ico", ServeFile::new("static/favicon.ico"))
|
||||||
.nest_service("/static", ServeDir::new("static"))
|
.nest_service("/static", ServeDir::new("static"))
|
||||||
.layer(TraceLayer::new_for_http())
|
.layer(TraceLayer::new_for_http());
|
||||||
.into_make_service_with_connect_info::<SocketAddr>();
|
|
||||||
|
let url_rewriting_middleware = tower::util::MapRequestLayer::new(url_rewriting);
|
||||||
|
let app_with_url_rewriting = url_rewriting_middleware.layer(app);
|
||||||
|
|
||||||
let addr = SocketAddr::from(([0, 0, 0, 0], port));
|
let addr = SocketAddr::from(([0, 0, 0, 0], port));
|
||||||
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
|
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
|
||||||
|
|
||||||
axum::serve(listener, app).await.unwrap();
|
axum::serve(
|
||||||
|
listener,
|
||||||
|
app_with_url_rewriting.into_make_service_with_connect_info::<SocketAddr>(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn user_authentication(
|
async fn user_authentication(
|
||||||
|
|
@ -312,54 +320,65 @@ async fn user_authentication(
|
||||||
Ok(next.run(req).await)
|
Ok(next.run(req).await)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct Lang(Option<String>);
|
||||||
|
|
||||||
|
fn url_rewriting(mut req: Request) -> Request {
|
||||||
|
// Here we are extracting the language from the url then rewriting it.
|
||||||
|
// For example:
|
||||||
|
// "/fr/recipe/view/1"
|
||||||
|
// lang = "fr" and uri rewritten as = "/recipe/view/1"
|
||||||
|
let lang_and_new_uri = 'lang_and_new_uri: {
|
||||||
|
if let Some(path_query) = req.uri().path_and_query() {
|
||||||
|
let mut parts = path_query.path().split('/');
|
||||||
|
let _ = parts.next(); // Empty part due to the first '/'.
|
||||||
|
if let Some(lang) = parts.next() {
|
||||||
|
let available_codes = translation::available_codes();
|
||||||
|
if available_codes.contains(&lang) {
|
||||||
|
let mut rest: String = String::from("");
|
||||||
|
for part in parts {
|
||||||
|
rest.push('/');
|
||||||
|
rest.push_str(part);
|
||||||
|
}
|
||||||
|
if let Some(query) = path_query.query() {
|
||||||
|
rest.push('?');
|
||||||
|
rest.push_str(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(new_uri) = rest.parse::<Uri>() {
|
||||||
|
break 'lang_and_new_uri Some((lang.to_string(), new_uri));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some((lang, new_uri)) = lang_and_new_uri {
|
||||||
|
*req.uri_mut() = new_uri;
|
||||||
|
req.extensions_mut().insert(Lang(Some(lang)));
|
||||||
|
} else {
|
||||||
|
req.extensions_mut().insert(Lang(None));
|
||||||
|
}
|
||||||
|
|
||||||
|
req
|
||||||
|
}
|
||||||
|
|
||||||
/// The language of the current HTTP request is defined in the current order:
|
/// The language of the current HTTP request is defined in the current order:
|
||||||
/// - Extraction from the url: like in '/fr/recipe/view/42' (Not yet implemented).
|
/// - Extraction from the url: like in '/fr/recipe/view/42'
|
||||||
/// - Get from the user database record.
|
/// - Get from the user database record.
|
||||||
/// - Get from the cookie.
|
/// - Get from the cookie.
|
||||||
/// - Get from the HTTP header `accept-language`.
|
/// - Get from the HTTP header `accept-language`.
|
||||||
/// - Set as `translation::DEFAULT_LANGUAGE_CODE`.
|
/// - Set as `translation::DEFAULT_LANGUAGE_CODE`.
|
||||||
async fn translation(
|
async fn translation(
|
||||||
|
Extension(lang): Extension<Lang>,
|
||||||
Extension(user): Extension<Option<model::User>>,
|
Extension(user): Extension<Option<model::User>>,
|
||||||
mut req: Request,
|
mut req: Request,
|
||||||
next: Next,
|
next: Next,
|
||||||
) -> Result<Response> {
|
) -> Result<Response> {
|
||||||
// Here we are extracting the language from the url then rewriting it.
|
let language = if let Some(lang) = lang.0 {
|
||||||
// For example:
|
lang
|
||||||
// "/fr/recipe/view/1"
|
} else if let Some(user) = user {
|
||||||
// lang = "fr" and uri rewritten as = "/recipe/view/1"
|
|
||||||
// Disable because it doesn't work at this level, see:
|
|
||||||
// https://docs.rs/axum/latest/axum/middleware/index.html#rewriting-request-uri-in-middleware
|
|
||||||
|
|
||||||
// let lang_and_new_uri = 'lang_from_uri: {
|
|
||||||
// if let Some(path_query) = req.uri().path_and_query() {
|
|
||||||
// event!(Level::INFO, "path: {:?}", path_query.path());
|
|
||||||
// let mut parts = path_query.path().split('/');
|
|
||||||
// let _ = parts.next(); // Empty part due to the first '/'.
|
|
||||||
// if let Some(lang) = parts.next() {
|
|
||||||
// let available_codes = translation::available_codes();
|
|
||||||
// if available_codes.contains(&lang) {
|
|
||||||
// let mut rest: String = String::from("");
|
|
||||||
// for part in parts {
|
|
||||||
// rest.push('/');
|
|
||||||
// rest.push_str(part);
|
|
||||||
// }
|
|
||||||
// // let uri_builder = Uri::builder()
|
|
||||||
// if let Ok(new_uri) = rest.parse::<Uri>() {
|
|
||||||
// event!(Level::INFO, "path rewrite: {:?}", new_uri.path());
|
|
||||||
// break 'lang_from_uri Some((lang.to_string(), new_uri));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// None
|
|
||||||
// };
|
|
||||||
// let language = if let Some((lang, uri)) = lang_and_new_uri {
|
|
||||||
// *req.uri_mut() = uri; // Replace the URI without the language.
|
|
||||||
// event!(Level::INFO, "URI: {:?}", req.uri());
|
|
||||||
// lang
|
|
||||||
// } else
|
|
||||||
|
|
||||||
let language = if let Some(user) = user {
|
|
||||||
user.lang
|
user.lang
|
||||||
} else {
|
} else {
|
||||||
let available_codes = translation::available_codes();
|
let available_codes = translation::available_codes();
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@ use rinja::Template;
|
||||||
// use tracing::{event, Level};
|
// use tracing::{event, Level};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
Result,
|
||||||
data::{db, model},
|
data::{db, model},
|
||||||
html_templates::*,
|
html_templates::*,
|
||||||
translation::{self, Sentence},
|
translation::{self, Sentence},
|
||||||
Result,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[debug_handler]
|
#[debug_handler]
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,6 @@ def main [host: string, destination: string, ssh_key: path] {
|
||||||
}
|
}
|
||||||
|
|
||||||
cd frontend
|
cd frontend
|
||||||
# source frontend/deploy.nu
|
|
||||||
# main true
|
|
||||||
trunk build --release
|
trunk build --release
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,10 @@ use crate::utils::selector;
|
||||||
|
|
||||||
mod calendar;
|
mod calendar;
|
||||||
mod error;
|
mod error;
|
||||||
mod home;
|
|
||||||
mod modal_dialog;
|
mod modal_dialog;
|
||||||
mod on_click;
|
mod on_click;
|
||||||
mod recipe_edit;
|
mod pages;
|
||||||
mod recipe_scheduler;
|
mod recipe_scheduler;
|
||||||
mod recipe_view;
|
|
||||||
mod request;
|
mod request;
|
||||||
mod shopping_list;
|
mod shopping_list;
|
||||||
mod toast;
|
mod toast;
|
||||||
|
|
@ -24,8 +22,14 @@ mod utils;
|
||||||
pub fn main() -> Result<(), JsValue> {
|
pub fn main() -> Result<(), JsValue> {
|
||||||
console_error_panic_hook::set_once();
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
|
let lang = utils::get_current_lang();
|
||||||
|
|
||||||
let location = window().location().pathname()?;
|
let location = window().location().pathname()?;
|
||||||
let path: Vec<&str> = location.split('/').skip(1).collect();
|
let path: Vec<&str> = location
|
||||||
|
.split('/')
|
||||||
|
.skip(1)
|
||||||
|
.skip_while(|part| *part == lang)
|
||||||
|
.collect();
|
||||||
|
|
||||||
let is_user_logged = selector::<HtmlElement>("html")
|
let is_user_logged = selector::<HtmlElement>("html")
|
||||||
.dataset()
|
.dataset()
|
||||||
|
|
@ -36,14 +40,14 @@ pub fn main() -> Result<(), JsValue> {
|
||||||
match path[..] {
|
match path[..] {
|
||||||
["recipe", "edit", id] => {
|
["recipe", "edit", id] => {
|
||||||
let id = id.parse::<i64>().unwrap(); // TODO: remove unwrap.
|
let id = id.parse::<i64>().unwrap(); // TODO: remove unwrap.
|
||||||
recipe_edit::setup_page(id)
|
pages::recipe_edit::setup_page(id)
|
||||||
}
|
}
|
||||||
["recipe", "view", id] => {
|
["recipe", "view", id] => {
|
||||||
let id = id.parse::<i64>().unwrap(); // TODO: remove unwrap.
|
let id = id.parse::<i64>().unwrap(); // TODO: remove unwrap.
|
||||||
recipe_view::setup_page(id, is_user_logged)
|
pages::recipe_view::setup_page(id, is_user_logged)
|
||||||
}
|
}
|
||||||
// Home.
|
// Home.
|
||||||
[""] => home::setup_page(is_user_logged),
|
[""] => pages::home::setup_page(is_user_logged),
|
||||||
_ => log!("Path unknown: ", location),
|
_ => log!("Path unknown: ", location),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
3
frontend/src/pages/mod.rs
Normal file
3
frontend/src/pages/mod.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod home;
|
||||||
|
pub mod recipe_edit;
|
||||||
|
pub mod recipe_view;
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use chrono::{Datelike, Days, Months, NaiveDate};
|
use chrono::{Datelike, Days, Months, NaiveDate};
|
||||||
use common::ron_api;
|
use common::ron_api;
|
||||||
use gloo::storage::{LocalStorage, Storage};
|
use gloo::storage::{LocalStorage, Storage};
|
||||||
use ron::ser::{to_string_pretty, PrettyConfig};
|
use ron::ser::{PrettyConfig, to_string_pretty};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,16 @@ where
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_current_lang() -> String {
|
||||||
|
selector::<Element>("html")
|
||||||
|
.get_attribute("lang")
|
||||||
|
.unwrap()
|
||||||
|
.split("-")
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_locale() -> Locale {
|
pub fn get_locale() -> Locale {
|
||||||
let lang_and_territory = selector::<Element>("html")
|
let lang_and_territory = selector::<Element>("html")
|
||||||
.get_attribute("lang")
|
.get_attribute("lang")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue