1
Fork 0
This commit is contained in:
Bauke 2021-11-26 14:08:13 +01:00
parent 7918707dd9
commit 72fd3351b3
Signed by: Bauke
GPG Key ID: C1C0F29952BCF558
19 changed files with 184 additions and 341 deletions

View File

@ -7,25 +7,13 @@ version = "1.0.0"
edition = "2018"
repository = "https://git.holllo.cc/Bauke/bauke.xyz"
license = "AGPL-3.0-or-later"
build = "source/build.rs"
[[bin]]
name = "bauke-xyz"
path = "source/main.rs"
[dependencies]
gloo-console = "0.2.0"
gloo-timers = "0.2.1"
log = "0.4.14"
rand = "0.8.4"
userstyles = { git = "https://git.holllo.cc/Bauke/userstyles" }
wasm-logger = "0.2.0"
yew = "0.18.0"
yew-router = "0.15.0"
[dependencies.getrandom]
version = "0.2.3"
features = ["js"]
[build-dependencies]
askama = "0.10.5"
color-eyre = "0.5.11"
rsass = "0.22.2"
userstyles = { git = "https://git.holllo.cc/Bauke/userstyles" }

View File

@ -1,9 +0,0 @@
[build]
dist = "public"
[serve]
no_autoreload = false
port = 5500
[clean]
dist = "public"

2
askama.toml Normal file
View File

@ -0,0 +1,2 @@
[general]
dirs = ["source/templates"]

View File

@ -1,21 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>bauke.xyz</title>
<link data-trunk rel="sass" href="source/scss/modern-normalize.scss" />
<link data-trunk rel="sass" href="source/scss/index.scss" />
<link data-trunk rel="copy-file" href="source/netlify/_redirects" />
<link data-trunk rel="copy-dir" href="target/userstyles" />
</head>
<body>
<noscript>
This website requires JavaScript and WebAssembly to work.
</noscript>
</body>
</html>

View File

@ -3,7 +3,7 @@
"version": "0.0.0",
"license": "AGPL-3.0-or-later",
"scripts": {
"deploy": "trunk clean && cargo build -q && trunk build --release && yarn deploy:netlify",
"deploy": "cargo run --release -q && yarn deploy:netlify",
"deploy:netlify": "netlify deploy --prod --dir 'public/' -s bauke.xyz",
"test": "stylelint 'source/**/*.scss'"
},

View File

@ -1,23 +0,0 @@
/// Build script for the website.
fn main() {
println!("cargo:rerun-if-changed=source/**");
let build_dir = std::path::PathBuf::from("target");
for target in userstyles::ALL_USERSTYLES {
let style = userstyles::Userstyle::load(target).unwrap();
let style_name = style.metadata.name.to_lowercase().replace(" ", "-");
let style_dir = build_dir.join("userstyles");
std::fs::create_dir_all(&style_dir).unwrap();
let style_file = style_dir.join(format!("{}.user.css", style_name));
let formatted = style.format();
std::fs::write(style_file, formatted).unwrap();
if let Some(image) = style.image {
let image_file = style_dir.join(format!("{}.png", style_name));
std::fs::write(image_file, image).unwrap();
}
}
}

View File

@ -1,10 +0,0 @@
/// Contains the main page `<footer>` component.
mod page_footer;
/// Contains the main page `<header>` component.
mod page_header;
/// Contains the main page `<main>` component.
mod page_main;
pub(crate) use page_footer::PageFooter;
pub(crate) use page_header::PageHeader;
pub(crate) use page_main::PageMain;

View File

@ -1,29 +0,0 @@
use yew::prelude::*;
/// The main page `<footer>` element.
pub(crate) struct PageFooter;
impl Component for PageFooter {
type Message = ();
type Properties = ();
fn create(_props: Self::Properties, _link: ComponentLink<Self>) -> Self {
log::trace!("Creating PageFooter");
Self
}
fn update(&mut self, _msg: Self::Message) -> ShouldRender {
unimplemented!()
}
fn change(&mut self, _props: Self::Properties) -> ShouldRender {
false
}
fn view(&self) -> Html {
html! {
<footer class="page-footer"></footer>
}
}
}

View File

@ -1,31 +0,0 @@
use yew::prelude::*;
/// The main page `<header>` element.
pub(crate) struct PageHeader;
impl Component for PageHeader {
type Message = ();
type Properties = ();
fn create(_props: Self::Properties, _link: ComponentLink<Self>) -> Self {
log::trace!("Creating PageHeader");
Self
}
fn update(&mut self, _msg: Self::Message) -> ShouldRender {
unimplemented!()
}
fn change(&mut self, _props: Self::Properties) -> ShouldRender {
false
}
fn view(&self) -> Html {
html! {
<header class="page-header">
<h1>{"bauke.xyz"}</h1>
</header>
}
}
}

View File

@ -1,43 +0,0 @@
use yew::prelude::*;
/// The main page `<main>` element.
pub(crate) struct PageMain;
impl Component for PageMain {
type Message = ();
type Properties = ();
fn create(_props: Self::Properties, _link: ComponentLink<Self>) -> Self {
log::trace!("Creating PageMain");
Self
}
fn update(&mut self, _msg: Self::Message) -> ShouldRender {
unimplemented!()
}
fn change(&mut self, _props: Self::Properties) -> ShouldRender {
false
}
fn view(&self) -> Html {
html! {
<main class="page-main">
<div class="contact-links">
<a target="_blank" href="mailto:me@bauke.xyz">
{"me@bauke.xyz"}
</a>
<a target="_blank" href="https://matrix.to/#/@baukexyz:matrix.org">
{"@baukexyz:matrix.org"}
</a>
<a target="_blank" href="https://mastodon.social/@bauke">
{"@bauke@mastodon.social"}
</a>
</div>
</main>
}
}
}

View File

@ -1,72 +1,106 @@
#![forbid(unsafe_code)]
#![warn(missing_docs, clippy::missing_docs_in_private_items)]
use std::{fs, path::PathBuf, process::Command};
//! # [bauke.xyz](https://bauke.xyz)
use askama::Template;
use yew::prelude::*;
use yew_router::router::Router;
mod templates;
/// Components collection.
pub(crate) mod components;
/// Routes collection.
pub(crate) mod routes;
fn main() -> color_eyre::Result<()> {
color_eyre::install()?;
/// All routes.
#[derive(Clone, yew_router::Switch)]
pub(crate) enum Route {
#[to = "/userstyles"]
Userstyles,
#[to = "/{}"]
NotFound(String),
#[to = "/"]
Home,
}
let build_dir = PathBuf::from("target");
/// The main component.
pub(crate) struct Model;
for target in userstyles::ALL_USERSTYLES {
let style = userstyles::Userstyle::load(target)?;
let style_name = style.metadata.name.to_lowercase().replace(" ", "-");
impl Component for Model {
type Message = ();
type Properties = ();
let style_dir = build_dir.join("userstyles");
fs::create_dir_all(&style_dir)?;
fn create(_props: Self::Properties, _link: ComponentLink<Self>) -> Self {
Self
}
let style_file = style_dir.join(format!("{}.user.css", style_name));
let formatted = style.format();
fs::write(style_file, formatted)?;
fn update(&mut self, _msg: Self::Message) -> ShouldRender {
unimplemented!()
}
fn change(&mut self, _props: Self::Properties) -> ShouldRender {
false
}
fn view(&self) -> Html {
html! {
<Router<Route, ()>
render = Router::render(|route: Route| {
match route {
Route::NotFound(_) => html! {
<main class="error-404">
<p>{"🤷"}</p>
</main>
},
Route::Home => html! {
<routes::HomeRoute />
},
Route::Userstyles => html! {
<routes::UserstylesRoute />
}
}
})
/>
if let Some(image) = style.image {
let image_file = style_dir.join(format!("{}.png", style_name));
fs::write(image_file, image)?;
}
}
}
/// Our main function.
pub(crate) fn main() {
wasm_logger::init(wasm_logger::Config::new(log::Level::Debug));
log::debug!("Initializing Yew");
yew::start_app::<Model>();
let public_dir = PathBuf::from("public");
let source_dir = PathBuf::from("source");
let styles = userstyles::ALL_USERSTYLES
.iter()
.map(|target| userstyles::Userstyle::load(target))
.flatten()
.collect::<Vec<_>>();
let templates_to_render: Vec<(Box<dyn Template>, PathBuf)> = vec![
(
Box::new(templates::Index {
page_title: "bauke.xyz".to_string(),
}),
public_dir.join("index.html"),
),
(
Box::new(templates::Userstyles {
page_title: "bauke.xyz".to_string(),
styles,
}),
public_dir.join("userstyles/index.html"),
),
];
for (template, path) in templates_to_render {
fs::create_dir_all(&path.parent().unwrap())?;
let rendered = template.render()?;
fs::write(path, rendered)?;
}
let css_dir = public_dir.join("css");
fs::create_dir_all(&css_dir)?;
let scss_dir = source_dir.join("scss");
let scss_to_render = vec![
(scss_dir.join("index.scss"), css_dir.join("index.css")),
(
scss_dir.join("modern-normalize.scss"),
css_dir.join("modern-normalize.css"),
),
];
for (source, destination) in scss_to_render {
let rendered = rsass::compile_scss_path(
&source,
rsass::output::Format {
style: rsass::output::Style::Expanded,
precision: 5,
},
)?;
fs::write(destination, rendered)?;
}
let files_to_copy = vec![(
source_dir.join("netlify/_redirects"),
public_dir.join("_redirects"),
)];
for (source, destination) in files_to_copy {
fs::copy(source, destination)?;
}
let dirs_to_copy = vec![(build_dir.join("userstyles"), public_dir)];
for (source, destination) in dirs_to_copy {
Command::new("cp")
.arg("-r")
.arg(source)
.arg(destination)
.output()?;
}
Ok(())
}

View File

@ -1,35 +0,0 @@
use yew::prelude::*;
use crate::components::{PageFooter, PageHeader, PageMain};
/// The route for `/`.
pub(crate) struct HomeRoute;
impl Component for HomeRoute {
type Message = ();
type Properties = ();
fn create(_props: Self::Properties, _link: ComponentLink<Self>) -> Self {
log::trace!("Creating HomeRoute");
Self
}
fn update(&mut self, _msg: Self::Message) -> ShouldRender {
unimplemented!()
}
fn change(&mut self, _props: Self::Properties) -> ShouldRender {
false
}
fn view(&self) -> Html {
html! {
<>
<PageHeader />
<PageMain />
<PageFooter />
</>
}
}
}

View File

@ -1,7 +0,0 @@
/// The route for `/`.
mod home;
/// The route for `/userstyles`.
mod userstyles;
pub(crate) use self::userstyles::UserstylesRoute;
pub(crate) use home::HomeRoute;

View File

@ -1,57 +0,0 @@
use yew::prelude::*;
use crate::components::PageHeader;
/// The route for `/userstyles`.
pub(crate) struct UserstylesRoute;
impl Component for UserstylesRoute {
type Message = ();
type Properties = ();
fn create(_props: Self::Properties, _link: ComponentLink<Self>) -> Self {
log::trace!("Creating UserstylesRoute");
Self
}
fn update(&mut self, _msg: Self::Message) -> ShouldRender {
unimplemented!()
}
fn change(&mut self, _props: Self::Properties) -> ShouldRender {
false
}
fn view(&self) -> Html {
let styles = userstyles::ALL_USERSTYLES
.iter()
.map(|target| userstyles::Userstyle::load(target))
.flatten()
.map(|style| {
let style_name = style.metadata.name.to_lowercase().replace(" ", "-");
html! {
<div class="style">
<div class="header">
<img src=format!("/userstyles/{}.png", style_name) />
<h2>{style.metadata.name}</h2>
<a target="_blank" href={style.metadata.update_url}>{"Install"}</a>
</div>
<p>{style.metadata.description}</p>
</div>
}
})
.collect::<Vec<_>>();
html! {
<>
<PageHeader />
<main class="page-main userstyles">
{styles}
</main>
</>
}
}
}

View File

@ -14,6 +14,7 @@
&:hover {
background-color: #fff;
border-color: #fff;
color: #000;
}
}

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ page_title }}</title>
<link rel="stylesheet" href="/css/modern-normalize.css">
{% block head %}{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>

View File

@ -0,0 +1,27 @@
{% extends "base.html" %}
{% block head %}
<link rel="stylesheet" href="/css/index.css">
{% endblock %}
{% block body %}
<header class="page-header">
<h1>bauke.xyz</h1>
</header>
<main class="page-main">
<div class="contact-links">
<a target="_blank" href="mailto:me@bauke.xyz">
me@bauke.xyz
</a>
<a target="_blank" href="https://matrix.to/#/@baukexyz:matrix.org">
@baukexyz:matrix.org
</a>
<a target="_blank" href="https://mastodon.social/@bauke">
@bauke@mastodon.social
</a>
</div>
</main>
{% endblock %}

14
source/templates/mod.rs Normal file
View File

@ -0,0 +1,14 @@
use askama::Template;
#[derive(Debug, Template)]
#[template(path = "index.html")]
pub struct Index {
pub page_title: String,
}
#[derive(Debug, Template)]
#[template(path = "userstyles.html")]
pub struct Userstyles {
pub page_title: String,
pub styles: Vec<userstyles::Userstyle>,
}

View File

@ -0,0 +1,25 @@
{% extends "base.html" %}
{% block head %}
<link rel="stylesheet" href="/css/index.css">
{% endblock %}
{% block body %}
<header class="page-header">
<h1>bauke.xyz</h1>
</header>
<main class="page-main userstyles">
{% for style in styles %}
<div class="style">
<div class="header">
<img src="{{ format!("/userstyles/{}.png", style.metadata.name.to_lowercase().replace(" ", "-"))|safe }}" />
<h2>{{ style.metadata.name }}</h2>
<a target="_blank" href="{{ style.metadata.update_url|safe }}">Install</a>
</div>
<p>{{ style.metadata.description }}</p>
</div>
{% endfor %}
</main>
{% endblock %}