add: cache breaker "build code"
This commit is contained in:
parent
25579c5195
commit
9778230e3f
6 changed files with 32 additions and 22 deletions
|
@ -97,8 +97,10 @@ globalThis.init_editor = () => {
|
|||
});
|
||||
|
||||
window.addEventListener("beforeunload", (e) => {
|
||||
e.preventDefault();
|
||||
return null;
|
||||
if (!globalThis.ALLOW_LEAVE) {
|
||||
e.preventDefault();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -104,6 +104,8 @@
|
|||
.then(res => res.json())
|
||||
.then((res) => {
|
||||
if (res.ok) {
|
||||
globalThis.ALLOW_LEAVE = true;
|
||||
|
||||
if (!rm) {
|
||||
document.cookie = `Atto-Message=\"Entry updated\"; path=/`;
|
||||
document.cookie = \"Atto-Message-Good=true; path=/\";
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
.then(res => res.json())
|
||||
.then((res) => {
|
||||
if (res.ok) {
|
||||
globalThis.ALLOW_LEAVE = true;
|
||||
document.cookie = `Atto-Message=\"Entry created! Your edit code: <code>${res.payload[1]}</code>.\"; path=/`;
|
||||
document.cookie = \"Atto-Message-Good=true; path=/\";
|
||||
window.location.href = `/${res.payload[0]}`;
|
||||
|
|
|
@ -8,15 +8,15 @@
|
|||
(meta ("http-equiv" "X-UA-Compatible") ("content" "ie=edge"))
|
||||
|
||||
(link ("rel" "icon") ("href" "/public/favicon.svg"))
|
||||
(link ("rel" "stylesheet") ("href" "{{ tetratto }}/css/utility.css"))
|
||||
(link ("rel" "stylesheet") ("href" "/public/style.css"))
|
||||
(link ("rel" "stylesheet") ("href" "{{ tetratto }}/css/utility.css?v={{ build_code }}"))
|
||||
(link ("rel" "stylesheet") ("href" "/public/style.css?v={{ build_code }}"))
|
||||
|
||||
(meta ("name" "theme-color") ("content" "#fbc27f"))
|
||||
(meta ("name" "description") ("content" "{{ name }}"))
|
||||
(meta ("property" "og:type") ("content" "website"))
|
||||
(meta ("property" "og:site_name") ("content" "{{ name }}"))
|
||||
|
||||
(script ("src" "/public/app.js") ("defer"))
|
||||
(script ("src" "/public/app.js?v={{ build_code }}") ("defer"))
|
||||
|
||||
(text "{% block head %}{% endblock %}"))
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ use nanoneo::core::element::Render;
|
|||
use std::{collections::HashMap, env::var, net::SocketAddr, process::exit, sync::Arc};
|
||||
use tera::{Tera, Value};
|
||||
use tetratto_core::sdk::DataClient;
|
||||
use tetratto_shared::hash::salt;
|
||||
use tokio::sync::RwLock;
|
||||
use tower_http::{
|
||||
catch_panic::CatchPanicLayer,
|
||||
|
@ -14,7 +15,7 @@ use tower_http::{
|
|||
};
|
||||
use tracing::{Level, info};
|
||||
|
||||
pub(crate) type InnerState = (DataClient, Tera);
|
||||
pub(crate) type InnerState = (DataClient, Tera, String);
|
||||
pub(crate) type State = Arc<RwLock<InnerState>>;
|
||||
|
||||
fn render_markdown(value: &Value, _: &HashMap<String, Value>) -> tera::Result<Value> {
|
||||
|
@ -93,7 +94,7 @@ async fn main() {
|
|||
// create app
|
||||
let app = Router::new()
|
||||
.merge(routes::routes())
|
||||
.layer(Extension(Arc::new(RwLock::new((database, tera)))))
|
||||
.layer(Extension(Arc::new(RwLock::new((database, tera, salt())))))
|
||||
.layer(axum::extract::DefaultBodyLimit::max(
|
||||
var("BODY_LIMIT")
|
||||
.unwrap_or("8388608".to_string())
|
||||
|
|
|
@ -36,7 +36,7 @@ pub fn routes() -> Router {
|
|||
.route("/api/v1/entries/{slug}", post(edit_request))
|
||||
}
|
||||
|
||||
fn default_context(data: &DataClient) -> Context {
|
||||
fn default_context(data: &DataClient, build_code: &str) -> Context {
|
||||
let mut ctx = Context::new();
|
||||
ctx.insert(
|
||||
"name",
|
||||
|
@ -47,14 +47,15 @@ fn default_context(data: &DataClient) -> Context {
|
|||
"what_page_slug",
|
||||
&std::env::var("WHAT_SLUG").unwrap_or("what".to_string()),
|
||||
);
|
||||
ctx.insert("build_code", &build_code);
|
||||
ctx
|
||||
}
|
||||
|
||||
// pages
|
||||
async fn not_found_request(Extension(data): Extension<State>) -> impl IntoResponse {
|
||||
let (ref data, ref tera) = *data.read().await;
|
||||
let (ref data, ref tera, ref build_code) = *data.read().await;
|
||||
|
||||
let mut ctx = default_context(&data);
|
||||
let mut ctx = default_context(&data, &build_code);
|
||||
ctx.insert(
|
||||
"error",
|
||||
&Error::GeneralNotFound("page".to_string()).to_string(),
|
||||
|
@ -63,15 +64,18 @@ async fn not_found_request(Extension(data): Extension<State>) -> impl IntoRespon
|
|||
}
|
||||
|
||||
async fn index_request(Extension(data): Extension<State>) -> impl IntoResponse {
|
||||
let (ref data, ref tera) = *data.read().await;
|
||||
Html(tera.render("index.lisp", &default_context(&data)).unwrap())
|
||||
let (ref data, ref tera, ref build_code) = *data.read().await;
|
||||
Html(
|
||||
tera.render("index.lisp", &default_context(&data, &build_code))
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
async fn view_request(
|
||||
Extension(data): Extension<State>,
|
||||
Path(slug): Path<String>,
|
||||
) -> impl IntoResponse {
|
||||
let (ref data, ref tera) = *data.read().await;
|
||||
let (ref data, ref tera, ref build_code) = *data.read().await;
|
||||
let entry = match data
|
||||
.query(&SimplifiedQuery {
|
||||
query: AppDataSelectQuery::KeyIs(format!("entries('{}')", slug)),
|
||||
|
@ -84,7 +88,7 @@ async fn view_request(
|
|||
AppDataQueryResult::Many(_) => unreachable!(),
|
||||
},
|
||||
Err(_) => {
|
||||
let mut ctx = default_context(&data);
|
||||
let mut ctx = default_context(&data, &build_code);
|
||||
ctx.insert(
|
||||
"error",
|
||||
&Error::GeneralNotFound("entry".to_string()).to_string(),
|
||||
|
@ -106,7 +110,7 @@ async fn view_request(
|
|||
AppDataQueryResult::Many(_) => unreachable!(),
|
||||
},
|
||||
Err(e) => {
|
||||
let mut ctx = default_context(&data);
|
||||
let mut ctx = default_context(&data, &build_code);
|
||||
ctx.insert("error", &e.to_string());
|
||||
|
||||
return Html(tera.render("error.lisp", &ctx).unwrap());
|
||||
|
@ -115,14 +119,14 @@ async fn view_request(
|
|||
|
||||
// count view
|
||||
if let Err(e) = data.update(views_id, (views + 1).to_string()).await {
|
||||
let mut ctx = default_context(&data);
|
||||
let mut ctx = default_context(&data, &build_code);
|
||||
ctx.insert("error", &e.to_string());
|
||||
|
||||
return Html(tera.render("error.lisp", &ctx).unwrap());
|
||||
}
|
||||
|
||||
// ...
|
||||
let mut ctx = default_context(&data);
|
||||
let mut ctx = default_context(&data, &build_code);
|
||||
|
||||
ctx.insert("entry", &entry);
|
||||
ctx.insert("views", &views);
|
||||
|
@ -134,7 +138,7 @@ async fn editor_request(
|
|||
Extension(data): Extension<State>,
|
||||
Path(slug): Path<String>,
|
||||
) -> impl IntoResponse {
|
||||
let (ref data, ref tera) = *data.read().await;
|
||||
let (ref data, ref tera, ref build_code) = *data.read().await;
|
||||
let entry = match data
|
||||
.query(&SimplifiedQuery {
|
||||
query: AppDataSelectQuery::KeyIs(format!("entries('{}')", slug)),
|
||||
|
@ -147,7 +151,7 @@ async fn editor_request(
|
|||
AppDataQueryResult::Many(_) => unreachable!(),
|
||||
},
|
||||
Err(_) => {
|
||||
let mut ctx = default_context(&data);
|
||||
let mut ctx = default_context(&data, &build_code);
|
||||
ctx.insert(
|
||||
"error",
|
||||
&Error::GeneralNotFound("entry".to_string()).to_string(),
|
||||
|
@ -158,7 +162,7 @@ async fn editor_request(
|
|||
};
|
||||
|
||||
// ...
|
||||
let mut ctx = default_context(&data);
|
||||
let mut ctx = default_context(&data, &build_code);
|
||||
ctx.insert("entry", &entry);
|
||||
|
||||
Html(tera.render("edit.lisp", &ctx).unwrap())
|
||||
|
@ -191,7 +195,7 @@ async fn create_request(
|
|||
Extension(data): Extension<State>,
|
||||
Json(req): Json<CreateEntry>,
|
||||
) -> impl IntoResponse {
|
||||
let (ref data, _) = *data.read().await;
|
||||
let (ref data, _, _) = *data.read().await;
|
||||
|
||||
// check lengths
|
||||
if req.slug.len() < 2 {
|
||||
|
@ -268,7 +272,7 @@ async fn edit_request(
|
|||
Path(slug): Path<String>,
|
||||
Json(req): Json<EditEntry>,
|
||||
) -> impl IntoResponse {
|
||||
let (ref data, _) = *data.read().await;
|
||||
let (ref data, _, _) = *data.read().await;
|
||||
|
||||
let (id, mut entry) = match data
|
||||
.query(&SimplifiedQuery {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue