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 main_page; | ||||
| mod webring; | ||||
| 
 | ||||
| pub struct BuildContext { | ||||
|     source_dir: PathBuf, | ||||
|  | @ -35,7 +36,11 @@ fn build() { | |||
| 
 | ||||
|     let ctx = Arc::new(ctx); | ||||
| 
 | ||||
|     [main_page::main_page, assets::copy_assets] | ||||
|     [ | ||||
|         main_page::main_page, | ||||
|         assets::copy_assets, | ||||
|         webring::copy_webring, | ||||
|     ] | ||||
|     .iter() | ||||
|     .map(|f| { | ||||
|         let ctx = Arc::clone(&ctx); | ||||
|  |  | |||
							
								
								
									
										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