From cf1975230ca7495a06c91857c984b4aff7a520a9 Mon Sep 17 00:00:00 2001 From: Dominic Zimmer Date: Mon, 26 Oct 2020 01:58:31 +0100 Subject: [PATCH] Implement number ranges in href --- src/App.tsx | 3 -- src/Gallery.tsx | 96 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 83 insertions(+), 16 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index e663e99..f511a7b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,9 +9,6 @@ const App : React.FC<{}> = () => {
logo -

- Edit src/App.tsx and to reload. -

{ return newSet; } + +const stateToString: (s: Set) => (string) = (s: Set) => { + const numbers: Array = Array.from(s).sort((a, b) => a - b); + var cur = -1; + var length = 1; + var out: Array = []; + const output: (cur: number, length: number) => any = (cur, length) => { + var start = cur; + var end = cur + length - 1; + if (length === 1) { + out.push(start.toString()); + } else if (length === 2) { + out.push(start.toString()); + out.push(end.toString()); + } else { + out.push(`${start}-${end}`); + } + }; + for (var i: number = 0; i < numbers.length; i++) { + if (cur === -1) { + cur = numbers[i]; + } else { + if (numbers[i - 1] === numbers[i] - 1) { + length++; + } else { + output(cur, length); + cur = numbers[i]; + length = 1; + } + } + if (i === numbers.length - 1) { + output(cur, length); + } + } + return out.join(","); +}; + +const stringToState: (s: string) => (Set) = (s: string) => { + var out: Set = new Set(); + const REGEX = "(?^\\d+$)|(?^(?\\d+)-(?\\d+)$)"; + s.split(",").forEach((str: string) => { + var groups = str.match(REGEX)?.groups; + if (groups?.short) { + var short: number = parseInt(groups.short); + out.add(short); + } else if (groups?.long1 && groups?.long2) { + var long1: number = parseInt(groups.long1); + var long2: number = parseInt(groups.long2); + for (var i = long1; i <= long2; i++) out.add(i); + } + }); + return out; +}; + const loadSet: (() => Set) = () => { var href: string = document.location.href; - var afterHref: string = href.indexOf("#") === -1 ? "" : href.substring(href.indexOf("#") + 1); - var numbers = afterHref === "" ? [] : afterHref.split(",").filter(s => s !== "").map(i => parseInt(i)); - return new Set([...numbers]); + var afterHref: string = href === href.split("#")[0] ? "" : href.split("#")[1]; + var numbers = stringToState(afterHref); + return numbers; +}; + +const storeSet: ((set: Set) => void) = (collection) => { + + var href = document.location.href; + var pureHref: string = href.split("#")[0]; + var newstate = stateToString(collection); + document.location.href = `${pureHref}#${newstate}`; }; const Gallery: React.FC<{ size: number }> = ({ size }) => { @@ -23,21 +85,29 @@ const Gallery: React.FC<{ size: number }> = ({ size }) => { return setCollection(previousState => new Set([...Array.from(previousState), toRemove])); } - function getStateString() { - var s = Array.from(collection).sort((a, b) => a - b).join(",") - return s; - } + useEffect(() => storeSet(collection)); - useEffect(() => { - var href = document.location.href; - var pureHref = (href.indexOf("#") === -1) ? href : href.substring(0, href.indexOf("#")); - document.location.href = `${pureHref}#${getStateString()}`; - }); + const clickHandler: ((value: number) => ((eve: React.MouseEvent) => any)) = (value) => { + return (event: React.MouseEvent) => { + var element = event.currentTarget; + element.setAttribute("style", ""); + var opacity = 1.0; // initial opacity + var timer = setInterval(function () { + if (opacity <= 0.1) { + clearInterval(timer); + addToCollection(value); + } else { + element.setAttribute("style", `opacity: ${opacity};`); + } + opacity *= 0.9; + }, 7); + }; + }; return ( {Array.from(originalSet).filter(element => !collection.has(element)).map((value, key, theset) => - addToCollection(value)} /> + )} ) };