Skip to content

Commit

Permalink
chore(website): updated website to latest beta
Browse files Browse the repository at this point in the history
Anyone having trouble with updating their own app is advised to take a
look at the commit diff for this.
  • Loading branch information
arctic-hen7 committed Jan 2, 2023
1 parent 1e9fc70 commit d2a8377
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 174 deletions.
9 changes: 5 additions & 4 deletions website/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ readme = "./README.md"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
perseus = { version = "=0.4.0-beta.10", features = [ "translator-lightweight" ] }
perseus-macro = "=0.4.0-beta.10"
perseus = { version = "=0.4.0-beta.12", features = [ "translator-lightweight" ] }
sycamore = "0.8"
sycamore-macro = "0.8"
serde = { version = "1", features = [ "derive" ] }
Expand All @@ -23,13 +22,15 @@ lazy_static = "1"
web-sys = { version = "0.3", features = [ "Event", "EventTarget", "Element", "Window", "Document", "DomRect", "HtmlCollection", "IntersectionObserver", "IntersectionObserverInit", "IntersectionObserverEntry", "KeyboardEvent" ] }
wasm-bindgen = "0.2.82"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
[target.'cfg(engine)'.dependencies]
tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] }
walkdir = "2"
pulldown-cmark = "0.8"
regex = "1"
anyhow = "1"
thiserror = "1" # Needed to make Anyhow compatible with Perseus

[target.'cfg(target_arch = "wasm32")'.dependencies]
[target.'cfg(client)'.dependencies]
wee_alloc = "0.4"
js-sys = "0.3"
gloo-timers = "0.2"
5 changes: 1 addition & 4 deletions website/src/components/comparisons.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use perseus::Html;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use sycamore::prelude::view;
use sycamore::prelude::Scope;
use sycamore::prelude::View;
use sycamore::prelude::*;

/// A comparison for the comparisons table. Perseus itself also has an entry
/// here. Note that any changes to the properties measured here must also be
Expand Down
64 changes: 0 additions & 64 deletions website/src/error_pages.rs

This file was deleted.

106 changes: 106 additions & 0 deletions website/src/error_views.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use perseus::{errors::ClientError, prelude::*};
use sycamore::prelude::*;

// This site will be exported statically, so we only have control over 404 pages
// for broken links in the site itself
pub fn get_error_views<G: Html>() -> ErrorViews<G> {
ErrorViews::new(|cx, err, _err_info, _err_pos| {
match err {
// Errors from the server, like 404s; these are best displayed over the whole
// page
ClientError::ServerError {
status,
// This is fully formatted with newlines and tabs for the error and its causes
message: _,
} => match status {
// This one is usually handled separately
404 => (
view! { cx,
title { "Page not found" }
},
not_found_page(cx),
),
// If the status is 4xx, it's a client-side problem (which is weird, and might
// indicate tampering)
_ if (400..500).contains(&status) => (
view! { cx,
title { "Error" }
},
view! { cx,
p { "There was something wrong with the last request, please try reloading the page." }
},
),
// 5xx is a server error
_ => (
view! { cx,
title { "Error" }
},
view! { cx,
p { "Sorry, our server experienced an internal error. Please try reloading the page." }
},
),
},
// A panic (yes, you can handle them here!). After this error is displayed, the entire
// app will terminate, so buttons or other reactive elements are pointless.
//
// The argument here is the formatted panic message.
ClientError::Panic(_) => (
view! { cx,
title { "Critical error" }
},
view! { cx,
p { "Sorry, but a critical internal error has occurred. This has been automatically reported to our team, who'll get on it as soon as possible. In the mean time, please try reloading the page." }
},
),
// Network errors (but these could be caused by unexpected server rejections)
ClientError::FetchError(_) => (
view! { cx,
title { "Error" }
},
view! { cx,
p { "A network error occurred, do you have an internet connection? (If you do, try reloading the page.)" }
},
),

_ => (
view! { cx,
title { "Error" }
},
view! { cx,
p { (format!("An internal error has occurred: '{}'.", err)) }
},
),
}
})
}

fn not_found_page<G: Html>(cx: Scope) -> View<G> {
view! { cx,
div(class = "flex flex-col justify-center items-center h-screen") {
main(class = "flex flex-col border border-black rounded-lg max-w-xl m-4") {
h3(class = "text-2xl font-bold w-full pb-4 border-b border-black my-4") {
span(class = "pl-4") { "Page not found!" }
}
div(class = "p-4 pt-0 my-4") {
span { "That page doesn't seem to exist. If you came here from a link elsewhere on the site, you should report this as a bug " }
a(class = "underline text-indigo-500", href = "https://github.com/framesurge/perseus/issues/new/choose") { "here" }
span { ". If you came here another website, or a search engine, this page probably existed once, but has since been moved. Here are some pages you might like to try instead:" }
ul(class = "pl-6 mt-1 w-full") {
li {
a(class = "underline text-indigo-500", href = "") { "Home" }
}
li {
a(class = "underline text-indigo-500", href = "docs") { "Docs" }
}
li {
a(class = "underline text-indigo-500", href = "comparisons") { "Comparisons" }
}
li {
a(class = "underline text-indigo-500", href = "plugins") { "Plugins" }
}
}
}
}
}
}
}
45 changes: 37 additions & 8 deletions website/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
#[cfg(target_arch = "wasm32")]
#[cfg(client)]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;

mod components;
mod error_pages;
mod error_views;
mod templates;

use perseus::{Html, PerseusApp, PerseusRoot};
use perseus::prelude::*;

#[perseus::main_export]
pub fn main<G: Html>() -> PerseusApp<G> {
PerseusApp::new()
.template(templates::index::get_template)
.template(templates::comparisons::get_template)
.template(templates::docs::get_template)
.template(templates::plugins::get_template)
.error_pages(error_pages::get_error_pages)
.template(templates::index::get_template())
.template(templates::comparisons::get_template())
.template(templates::docs::get_template())
.template(templates::plugins::get_template())
.error_views(error_views::get_error_views())
.locales_and_translations_manager("en-US", &[])
.index_view(|cx| {
sycamore::view! { cx,
Expand All @@ -33,3 +33,32 @@ pub fn main<G: Html>() -> PerseusApp<G> {
}
})
}

/// A universal representation of error messages that can occur in the app. This
/// is fully compatible with the Perseus state generation system.
#[cfg(engine)]
#[derive(thiserror::Error, Debug)]
#[error(transparent)]
struct Error(#[from] Box<dyn std::error::Error + Send + Sync>);
// This is not designed to be used as a 'proper' `From<E>` implementation, it's
// designed to be used in `some_function().map_err(Error::from)?`, which allows
// converting any error type straight into this for convenience.
//
// Perseus requires you to be explicit about your errors, mainly to avoid
// potentially leaking sensitive details to clients, which could be caused by
// this sort of blind conversion. Hence, (and due to internal Rust constraints
// on `?`), Perseus deliberatly avoids exposing this kind of function itself.
#[cfg(engine)]
impl Error {
#[inline]
fn from<E: std::error::Error + Send + Sync + 'static>(value: E) -> Self {
Error(value.into())
}
}
#[cfg(engine)]
impl From<String> for Error {
fn from(msg: String) -> Self {
let boxed: Box<dyn std::error::Error + Send + Sync> = msg.into();
boxed.into()
}
}
Loading

0 comments on commit d2a8377

Please sign in to comment.