lavender.software webring #2
					 4 changed files with 213 additions and 7 deletions
				
			
		|  | @ -5,6 +5,7 @@ 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, | ||||||
|  | @ -35,13 +36,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() { | ||||||
|  |  | ||||||
							
								
								
									
										27
									
								
								build_src/webring.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								build_src/webring.rs
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | ||||||
|  | use std::{fs, path::Path}; | ||||||
|  | 
 | ||||||
|  | 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_webring(ctx: &BuildContext) -> Result<()> { | ||||||
|  |     log_info("Copying webring…"); | ||||||
|  |     copy_dir_recursive( | ||||||
|  |         ctx.source_dir.join("webring"), | ||||||
|  |         ctx.output_dir.join("webring"), | ||||||
|  |     )?; | ||||||
|  | 
 | ||||||
|  |     Ok(()) | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								src/webring/data.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/webring/data.json
									
									
									
									
									
										Normal 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/" | ||||||
|  |     } | ||||||
|  | ] | ||||||
							
								
								
									
										157
									
								
								src/webring/webring.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								src/webring/webring.js
									
									
									
									
									
										Normal file
									
								
							|  | @ -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 = ` | ||||||
|  | <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..."); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | })(); | ||||||
		Loading…
	
		Reference in a new issue