add live reloading to the client

This commit is contained in:
liquidex 2024-11-23 19:12:00 +01:00
parent 7169e65244
commit 5ce9cfc022
6 changed files with 38 additions and 18 deletions

View file

@ -103,9 +103,9 @@ async fn vfs_entry(
} }
} }
async fn system_page(target: &AsyncDir, path: &VPath) -> Response { async fn system_page(target: &AsyncDir, path: &VPath, status_code: StatusCode) -> Response {
if let Some(content) = target.content(path).await { if let Some(content) = target.content(path).await {
(StatusCode::NOT_FOUND, Html(content)).into_response() (status_code, Html(content)).into_response()
} else { } else {
( (
StatusCode::INTERNAL_SERVER_ERROR, StatusCode::INTERNAL_SERVER_ERROR,
@ -116,11 +116,11 @@ async fn system_page(target: &AsyncDir, path: &VPath) -> Response {
} }
async fn index(State(state): State<Arc<Server>>) -> Response { async fn index(State(state): State<Arc<Server>>) -> Response {
system_page(&state.target, system::INDEX).await system_page(&state.target, system::INDEX, StatusCode::OK).await
} }
async fn four_oh_four(State(state): State<Arc<Server>>) -> Response { async fn four_oh_four(State(state): State<Arc<Server>>) -> Response {
system_page(&state.target, system::FOUR_OH_FOUR).await system_page(&state.target, system::FOUR_OH_FOUR, StatusCode::NOT_FOUND).await
} }
async fn branch(RawQuery(named_id): RawQuery, State(state): State<Arc<Server>>) -> Response { async fn branch(RawQuery(named_id): RawQuery, State(state): State<Arc<Server>>) -> Response {
@ -175,8 +175,8 @@ async fn branch(RawQuery(named_id): RawQuery, State(state): State<Arc<Server>>)
} }
} }
system_page(&state.target, system::FOUR_OH_FOUR).await system_page(&state.target, system::FOUR_OH_FOUR, StatusCode::NOT_FOUND).await
} else { } else {
system_page(&state.target, system::B_DOCS).await system_page(&state.target, system::B_DOCS, StatusCode::OK).await
} }
} }

View file

@ -28,9 +28,7 @@ use crate::state::{FileId, Treehouse};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ParsedTree { pub struct ParsedTree {
root_key: String, root_key: String,
tree_path: String,
file_id: FileId, file_id: FileId,
target_path: VPathBuf,
} }
#[derive(Serialize)] #[derive(Serialize)]
@ -55,6 +53,7 @@ struct BaseTemplateData<'a> {
config: &'a Config, config: &'a Config,
import_map: String, import_map: String,
season: Option<Season>, season: Option<Season>,
dev: bool,
} }
#[derive(Serialize)] #[derive(Serialize)]
@ -117,15 +116,7 @@ fn parse_tree(
let root_key = tree_path.clone(); let root_key = tree_path.clone();
treehouse.roots.insert(root_key.clone(), roots); treehouse.roots.insert(root_key.clone(), roots);
Ok(( Ok((Some(ParsedTree { root_key, file_id }), diagnostics))
Some(ParsedTree {
root_key,
tree_path,
file_id,
target_path,
}),
diagnostics,
))
} }
Err(diagnostics) => Ok((None, diagnostics)), Err(diagnostics) => Ok((None, diagnostics)),
} }
@ -190,6 +181,7 @@ fn generate_simple_template(
import_map: serde_json::to_string_pretty(&sources.import_map) import_map: serde_json::to_string_pretty(&sources.import_map)
.expect("import map should be serializable to JSON"), .expect("import map should be serializable to JSON"),
season: Season::current(), season: Season::current(),
dev: cfg!(debug_assertions),
}; };
handlebars handlebars
.render(template_name, &base_template_data) .render(template_name, &base_template_data)
@ -239,6 +231,7 @@ fn generate_tree(
import_map: serde_json::to_string_pretty(&sources.import_map) import_map: serde_json::to_string_pretty(&sources.import_map)
.expect("import map should be serializable to JSON"), .expect("import map should be serializable to JSON"),
season: Season::current(), season: Season::current(),
dev: cfg!(debug_assertions),
}; };
let template_data = PageTemplateData { let template_data = PageTemplateData {

View file

@ -103,6 +103,12 @@ impl Treehouse {
} }
} }
impl Default for Treehouse {
fn default() -> Self {
Self::new()
}
}
pub struct TomlError { pub struct TomlError {
pub message: String, pub message: String,
pub span: Option<Range<usize>>, pub span: Option<Range<usize>>,

View file

@ -1,7 +1,6 @@
use std::fmt::{self, Debug}; use std::fmt::{self, Debug};
use dashmap::DashMap; use dashmap::DashMap;
use log::debug;
use super::{Dir, DirEntry, EditPath, VPath, VPathBuf}; use super::{Dir, DirEntry, EditPath, VPath, VPathBuf};

16
static/js/live-reload.js Normal file
View file

@ -0,0 +1,16 @@
// NOTE: The server never fulfills this request, it stalls forever.
// Once the connection is closed, we try to connect with the server until we establish a successful
// connection. Then we reload the page.
await fetch("/dev/live-reload/stall").catch(async () => {
while (true) {
try {
let response = await fetch("/dev/live-reload/back-up");
if (response.status == 200) {
window.location.reload();
break;
}
} catch (e) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
}
});

View file

@ -17,6 +17,12 @@ clever to do while browser vendors figure that out, we'll just have to do a cach
--}} --}}
<script type="importmap">{{{ import_map }}}</script> <script type="importmap">{{{ import_map }}}</script>
{{#if dev}}
<script type="module">
import "treehouse/live-reload.js";
</script>
{{/if}}
<script> <script>
const TREEHOUSE_SITE = `{{ config.site }}`; const TREEHOUSE_SITE = `{{ config.site }}`;