import React, { Fragment, useEffect, useState } from 'react'; import './App.css'; import GalleryCard from './GalleryCard'; const defaultSet: any = (size: number) => { const newSet = new Set(); for (var i: number = 1; i <= size; i++) newSet.add(i); 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 === 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 }) => { const originalSet: Set = defaultSet(size); const [collection, setCollection] = useState(loadSet()); function addToCollection(toRemove: number) { return setCollection(previousState => new Set([...Array.from(previousState), toRemove])); } useEffect(() => storeSet(collection)); 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) => )} ) }; export default Gallery;