Merge pull request 'lavender.software webring' (#2) from patch/webring into main

Reviewed-on: lavender/lavender.software#2
This commit is contained in:
Charlotte Som 2022-03-05 15:00:47 +00:00
commit 1e1dfbc18a
7 changed files with 230 additions and 24 deletions

View file

@ -30,3 +30,5 @@ dist/ $ git pull --rebase
dist/ $ git push dist/ $ git push
dist/ $ # Your changes should now be live at lavender.software dist/ $ # Your changes should now be live at lavender.software
``` ```
If deploying this site, you may also want to examine the sample `nginx-site.conf` file.

View file

@ -1,21 +1,5 @@
use std::{fs, path::Path};
use crate::*; use crate::*;
fn copy_dir_recursive(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> std::io::Result<()> {
fs::create_dir_all(&dst)?;
for entry in fs::read_dir(src)? {
let entry = entry?;
let ty = entry.file_type()?;
if ty.is_dir() {
copy_dir_recursive(entry.path(), dst.as_ref().join(entry.file_name()))?;
} else {
fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?;
}
}
Ok(())
}
pub fn copy_assets(ctx: &BuildContext) -> Result<()> { pub fn copy_assets(ctx: &BuildContext) -> Result<()> {
log_info("Copying assets…"); log_info("Copying assets…");
copy_dir_recursive(ctx.source_dir.join("assets"), ctx.output_dir.join("assets"))?; copy_dir_recursive(ctx.source_dir.join("assets"), ctx.output_dir.join("assets"))?;

View file

@ -1,10 +1,11 @@
use siru::prelude::*; use siru::prelude::*;
use std::{convert::TryInto, path::PathBuf, sync::Arc, time::Duration}; use std::{convert::TryInto, fs, path::Path, path::PathBuf, sync::Arc, time::Duration};
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>; type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
mod assets; mod assets;
mod main_page; mod main_page;
mod webring;
pub struct BuildContext { pub struct BuildContext {
source_dir: PathBuf, source_dir: PathBuf,
@ -26,6 +27,20 @@ impl SiruFS for BuildContext {
} }
} }
pub fn copy_dir_recursive(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> std::io::Result<()> {
fs::create_dir_all(&dst)?;
for entry in fs::read_dir(src)? {
let entry = entry?;
let ty = entry.file_type()?;
if ty.is_dir() {
copy_dir_recursive(entry.path(), dst.as_ref().join(entry.file_name()))?;
} else {
fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?;
}
}
Ok(())
}
fn build() { fn build() {
let ctx = BuildContext { let ctx = BuildContext {
source_dir: "src".try_into().unwrap(), source_dir: "src".try_into().unwrap(),
@ -35,13 +50,17 @@ fn build() {
let ctx = Arc::new(ctx); let ctx = Arc::new(ctx);
[main_page::main_page, assets::copy_assets] [
.iter() main_page::main_page,
.map(|f| { assets::copy_assets,
let ctx = Arc::clone(&ctx); webring::copy_webring,
std::thread::spawn(move || f(&ctx).unwrap()) ]
}) .iter()
.for_each(|t| t.join().unwrap()); .map(|f| {
let ctx = Arc::clone(&ctx);
std::thread::spawn(move || f(&ctx).unwrap())
})
.for_each(|t| t.join().unwrap());
} }
fn main() { fn main() {

11
build_src/webring.rs Normal file
View file

@ -0,0 +1,11 @@
use crate::*;
pub fn copy_webring(ctx: &BuildContext) -> Result<()> {
log_info("Copying webring…");
copy_dir_recursive(
ctx.source_dir.join("webring"),
ctx.output_dir.join("webring"),
)?;
Ok(())
}

11
nginx-site.conf Normal file
View file

@ -0,0 +1,11 @@
# assuming the dist repo lives at /srv/http/lavender.software
location / {
alias /srv/http/lavender.software/;
}
error_page 404 /404.html
location = /webring/data.json {
add_header Access-Control-Allow-Origin *;
}

17
src/webring/data.json Normal file
View file

@ -0,0 +1,17 @@
[
{
"id": "annie",
"name": "annieversary",
"url": "https://versary.town/"
},
{
"id": "charlotte",
"name": "charlotte",
"url": "https://char.lt/"
},
{
"id": "mira",
"name": "mira",
"url": "https://boxin.space/"
}
]

View file

@ -0,0 +1,162 @@
(function () {
function getUID() {
var array = new Uint8Array(8);
window.crypto.getRandomValues(array);
return Array.from(array)
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
}
const params = document.currentScript.dataset;
const UID = getUID();
const css = `
#--lavender-cssreset-${UID} {
all: unset;
}
#--lavender-webring-container-${UID} {
background-color: rgb(28, 23, 36);
background-blend-mode: multiply;
position: relative;
background-color: ${params.backgroundColor || "purple"};
color: ${params.textColor || "white"};
text-shadow: 0px 1px 1px ${params.textShadowColor || "black"};
padding: 1px;
font-size: 16px;
font-family: sans-serif;
margin: 10px 0px;
}
#--lavender-webring-container-${UID} a {
color: inherit !important;
}
#--lavender-webring-container-${UID}::before {
display: block;
content: ' ';
top: 0; left: 0; bottom: 0; right: 0;
position: absolute;
box-sizing: border-box;
pointer-events: none;
border: 5px outset;
opacity: 0.25;
border-color: white black black white;
}
#--lavender-webring-container-${UID} #--lavender-webring-title-${UID} {
margin: 10px 10px 0px;
text-align: center;
font-style: italic;
}
#--lavender-webring-container-${UID} #--lavender-webring-item-container-${UID} {
display: flex;
justify-content: space-around;
}
@media (max-width: 600px) {
#--lavender-webring-container-${UID} #--lavender-webring-item-container-${UID} {
flex-direction: column;
}
}
#--lavender-webring-container-${UID} .--lavender-webring-items-${UID} {
font-size: 14px;
display: block;
text-align: center;
padding: 0px;
margin: 10px 10px 8px;
flex: 1;
}
#--lavender-webring-container-${UID} #--lavender-webring-item-1-${UID}::before {
display: inline;
content: '\\2190\\00a0';
}
#--lavender-webring-container-${UID} #--lavender-webring-item-3-${UID}::after {
display: inline;
content: '\\00a0\\2192';
}
`;
const webring_content = `
<div id="--lavender-cssreset-${UID}">
<div id="--lavender-webring-container-${UID}">
<p id="--lavender-webring-title-${UID}">This website is a part of the Lavender Software webring</p>
<div id="--lavender-webring-item-container-${UID}">
<a class="--lavender-webring-items-${UID}" id="--lavender-webring-item-1-${UID}"></a>
<a class="--lavender-webring-items-${UID}" id="--lavender-webring-item-2-${UID}"></a>
<a class="--lavender-webring-items-${UID}" id="--lavender-webring-item-3-${UID}"></a>
</div>
</div>
</div>
`;
function renderIdx(data, element, idx) {
idx = (idx + data.length) % data.length;
datum = data[idx];
element.textContent = datum.name;
element.href = datum.url;
}
function getElementByPostfixedId(path) {
return document.getElementById(path + "-" + UID);
}
function renderContent(currentScript, data) {
const params = currentScript.dataset;
var headstyle = document.createElement("style");
headstyle.innerHTML = css;
document.head.appendChild(headstyle);
currentScript.insertAdjacentHTML("afterend", webring_content);
const container = getElementByPostfixedId("--lavender-webring-container");
const item1 = getElementByPostfixedId("--lavender-webring-item-1");
const item2 = getElementByPostfixedId("--lavender-webring-item-2");
const item3 = getElementByPostfixedId("--lavender-webring-item-3");
const id = params.siteId;
var idindex = -1;
for (var i = 0; i < data.length; i++) {
if (data[i].id == id) {
idindex = i;
}
}
if (idindex == -1) {
item2.textContent =
"this site was not found in the list. please check that you don't have any typos in the id!";
return;
}
if ("hideTitle" in params) {
getElementByPostfixedId("--lavender-webring-title").style.display =
"none";
}
renderIdx(data, item1, idindex - 1);
renderIdx(data, item2, idindex);
renderIdx(data, item3, idindex + 1);
}
const currentScript = document.currentScript;
if (currentScript) {
fetch("https://lavender.software/webring/data.json")
.then(function (response) {
return response.json();
})
.then(function (data) {
renderContent(currentScript, data);
});
} else {
console.log("cannot locate document.currentScript element. aborting...");
}
})();