feat: handle local urls
feat: debug mode (auto-refreshes pages) fix: date ordering feat: add poor person's jQuery improvement: rename startLoading to showLoadingOverlay fix: do not load initial page twice improvement: allow arbitrary spaces between filename and date in files.txt
This commit is contained in:
		| @@ -1 +1,2 @@ | ||||
| readme.md 2022-03-03 Tickle | ||||
| readme.md   2022-28-06 Tickle | ||||
| examples.md 2022-28-06 Examples | ||||
							
								
								
									
										73
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								index.html
									
									
									
									
									
								
							| @@ -153,12 +153,47 @@ | ||||
|     <main id="Body"></main> | ||||
|     <div id="Loading"></div> | ||||
|     <script type="module"> | ||||
|       //@ts-check | ||||
|  | ||||
|       const is_debug_mode = /^localhost|127.0.0.1/.test( | ||||
|         window.location.hostname | ||||
|       ); | ||||
|  | ||||
|       /** | ||||
|        * markdown parser. Remove if you don't use markdown | ||||
|        */ | ||||
|       // @ts-ignore | ||||
|       import { micromark } from "https://esm.sh/micromark@3?bundle"; | ||||
|  | ||||
|       /** | ||||
|        * A small utility to query elements and get back an array | ||||
|        */ | ||||
|       const $ = (parent, selector) => [ | ||||
|         ...(!selector | ||||
|           ? document.querySelectorAll(parent) | ||||
|           : parent.querySelectorAll(selector)), | ||||
|       ]; | ||||
|  | ||||
|       /** | ||||
|        * Assumes a provided url is external if it begins by a known protocol | ||||
|        * @param {string} url | ||||
|        */ | ||||
|       const isExternal = (url) => | ||||
|         /^(https?|mailto|tel|ftp|ipfs|dat):/.test(url); | ||||
|  | ||||
|       const rewriteLocalUrls = (container) => { | ||||
|         $(container, "a").forEach((a) => { | ||||
|           const href = a.getAttribute("href"); | ||||
|           if (href && !isExternal(href)) { | ||||
|             console.log({ href }); | ||||
|             const rewrittenHref = "#/" + href.replace(/^\.?\//, ""); | ||||
|             a.setAttribute("href", rewrittenHref); | ||||
|             console.log(a); | ||||
|             console.log(rewrittenHref); | ||||
|           } | ||||
|         }); | ||||
|       }; | ||||
|  | ||||
|       /** | ||||
|        * useful to check for transitions while developing styles, if the loading screen disappears too fast | ||||
|        * | ||||
| @@ -177,10 +212,12 @@ | ||||
|        */ | ||||
|       const mainTitle = document.title; | ||||
|  | ||||
|       const startLoading = () => document.body.classList.add("is-loading"); | ||||
|       const stopLoading = () => document.body.classList.remove("is-loading"); | ||||
|       const showLoadingOverlay = () => | ||||
|         document.body.classList.add("is-loading"); | ||||
|       const hideLoadingOverlay = () => | ||||
|         document.body.classList.remove("is-loading"); | ||||
|  | ||||
|       const getCurrentPage = () => { | ||||
|       const getCurrentHashUrl = () => { | ||||
|         const [path, searchStr] = ( | ||||
|           window.location.hash[1] === "/" ? window.location.hash.slice(2) : "" | ||||
|         ).split("?"); | ||||
| @@ -189,12 +226,14 @@ | ||||
|       }; | ||||
|  | ||||
|       const onHashChange = (evt) => { | ||||
|         const { path, params } = getCurrentPage(); | ||||
|         const { path, params } = getCurrentHashUrl(); | ||||
|         if (!path) { | ||||
|           return false; | ||||
|         } | ||||
|         startLoading(); | ||||
|         return fetch(`./${path}`) | ||||
|         showLoadingOverlay(); | ||||
|         return fetch( | ||||
|           is_debug_mode ? `./${path}?rand=${Math.random()}` : `./${path}` | ||||
|         ) | ||||
|           .then((response) => response.text()) | ||||
|           .then(wait) | ||||
|           .then((text) => { | ||||
| @@ -205,8 +244,9 @@ | ||||
|               Body.innerHTML = `<pre>${text}</pre>`; | ||||
|             } else { | ||||
|               Body.innerHTML = micromark(text); | ||||
|               rewriteLocalUrls(Body); | ||||
|             } | ||||
|             stopLoading(); | ||||
|             hideLoadingOverlay(); | ||||
|           }); | ||||
|       }; | ||||
|  | ||||
| @@ -216,7 +256,8 @@ | ||||
|        * Loads the article list, parses it, creates the menu items | ||||
|        */ | ||||
|       const start = () => { | ||||
|         startLoading(); | ||||
|         let hasAutoloadedFirstPage = false; | ||||
|         showLoadingOverlay(); | ||||
|         fetch("./files.txt") | ||||
|           .then((response) => response.text()) | ||||
|           .then((lines) => { | ||||
| @@ -225,7 +266,7 @@ | ||||
|               .map((line, index) => { | ||||
|                 const today = new Date().toISOString().split("T")[0]; | ||||
|                 const result = line.match( | ||||
|                   /(?<name>.+)\.(?<ext>\w{2,3})(?:\s(?<date>[\d-]+)?(?<title>.+))?/ | ||||
|                   /(?<name>.+)\.(?<ext>\w{2,3})(?:\s+(?<date>[\d-]+)?(?<title>.+))?/ | ||||
|                 ); | ||||
|                 if (!result) { | ||||
|                   console.log(`could not parse line ${index}: [${line}]`); | ||||
| @@ -235,20 +276,22 @@ | ||||
|                   groups: { name, ext, date = today, title = name }, | ||||
|                 } = result; | ||||
|                 const href = `/${name}.${ext}`; | ||||
|                 if (!getCurrentPage().path) { | ||||
|                 if (!getCurrentHashUrl().path) { | ||||
|                   hasAutoloadedFirstPage = true; | ||||
|                   window.location.hash = `#${href}`; | ||||
|                 } | ||||
|                 console.log({ name, href, date, title }); | ||||
|                 return { name, href, date, title }; | ||||
|                 const date_unix = new Date(date).getTime(); | ||||
|                 return { name, href, date, title, date_unix }; | ||||
|               }) | ||||
|               .filter(Boolean) | ||||
|               .sort(({ date: a }, { date: b }) => a - b) | ||||
|               .sort(({ date_unix: a }, { date_unix: b }) => a - b) | ||||
|               .map( | ||||
|                 ({ href, title }) => `<a data-link href="#${href}">${title}</a>` | ||||
|               ) | ||||
|               .join(`\n`); | ||||
|  | ||||
|             onHashChange(); | ||||
|             if (!hasAutoloadedFirstPage) { | ||||
|               onHashChange(); | ||||
|             } | ||||
|           }); | ||||
|       }; | ||||
|  | ||||
|   | ||||
| @@ -31,8 +31,8 @@ We have a [neat little UI to help you do all of that](https://git.poto.cafe/yagi | ||||
|  | ||||
| Here are more detailed explanations, for different knowledge levels. | ||||
|  | ||||
| - [I do not care about tech stuff, I just want to publish](/#/tutorial-publishers.md) | ||||
| - [I can write some code, give me detailed explanations](/#/tutorial-hackers.md) | ||||
| - [I do not care about tech stuff, I just want to publish](tutorial-publishers.md) | ||||
| - [I can write some code, give me detailed explanations](tutorial-hackers.md) | ||||
|  | ||||
| It's important to know that Tickle is an *idea*. Think of it as a specification. We have a few examples listed [here](examples.md) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user