diff --git a/build_src/main.rs b/build_src/main.rs index f535406..1b10439 100644 --- a/build_src/main.rs +++ b/build_src/main.rs @@ -5,6 +5,7 @@ type Result = std::result::Result>; mod assets; mod main_page; +mod webring; pub struct BuildContext { source_dir: PathBuf, @@ -35,13 +36,17 @@ fn build() { let ctx = Arc::new(ctx); - [main_page::main_page, assets::copy_assets] - .iter() - .map(|f| { - let ctx = Arc::clone(&ctx); - std::thread::spawn(move || f(&ctx).unwrap()) - }) - .for_each(|t| t.join().unwrap()); + [ + main_page::main_page, + assets::copy_assets, + webring::copy_webring, + ] + .iter() + .map(|f| { + let ctx = Arc::clone(&ctx); + std::thread::spawn(move || f(&ctx).unwrap()) + }) + .for_each(|t| t.join().unwrap()); } fn main() { diff --git a/build_src/webring.rs b/build_src/webring.rs new file mode 100644 index 0000000..9daf6d0 --- /dev/null +++ b/build_src/webring.rs @@ -0,0 +1,27 @@ +use std::{fs, path::Path}; + +use crate::*; + +fn copy_dir_recursive(src: impl AsRef, dst: impl AsRef) -> 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_webring(ctx: &BuildContext) -> Result<()> { + log_info("Copying webring…"); + copy_dir_recursive( + ctx.source_dir.join("webring"), + ctx.output_dir.join("webring"), + )?; + + Ok(()) +} diff --git a/src/webring/data.json b/src/webring/data.json new file mode 100644 index 0000000..52620a0 --- /dev/null +++ b/src/webring/data.json @@ -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/" + } +] diff --git a/src/webring/webring.js b/src/webring/webring.js new file mode 100644 index 0000000..cef8050 --- /dev/null +++ b/src/webring/webring.js @@ -0,0 +1,157 @@ +(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 = ` +
+
+

This website is a part of the Lavender Software webring

+
+ + + +
+
+
+`; + + 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..."); + } + +})();