From 1bbe6617d99e45492091b474111883cc5b1903b1 Mon Sep 17 00:00:00 2001 From: mxdanger <32040254+mxdanger@users.noreply.github.com> Date: Tue, 25 Jul 2023 23:39:11 -0700 Subject: [PATCH 01/16] UX improvements Related to #612 --- web/_js/main/draw.js | 5 +++-- web/_js/main/infoblock.js | 4 ++-- web/about.html | 2 ++ web/index.html | 12 ++++++------ 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/web/_js/main/draw.js b/web/_js/main/draw.js index 29f928bd5..c2b407fff 100644 --- a/web/_js/main/draw.js +++ b/web/_js/main/draw.js @@ -69,7 +69,7 @@ const periodClipboard = { const drawBackButton = document.createElement("a") drawBackButton.className = "btn btn-outline-primary" drawBackButton.id = "drawBackButton" -drawBackButton.textContent = "Exit Draw Mode" +drawBackButton.textContent = "Exit Drawing" const baseInputAddon = document.createElement("span") baseInputAddon.className = "input-group-text" @@ -106,7 +106,8 @@ function initDraw() { showListButton.insertAdjacentHTML("afterend", '') showListButton.parentElement.appendChild(drawBackButton) showListButton.remove() - + drawButton.remove() + // Opens draw menu wrapper.classList.remove('listHidden') bsOffcanvasDraw.show() diff --git a/web/_js/main/infoblock.js b/web/_js/main/infoblock.js index 5493ac09f..ad5c8dd6c 100644 --- a/web/_js/main/infoblock.js +++ b/web/_js/main/infoblock.js @@ -54,7 +54,7 @@ function createInfoBlock(entry, isPreview) { linkNameElement.textContent = entry.name headerElement.appendChild(linkElement) linkElement.appendChild(linkNameElement) - linkElement.insertAdjacentHTML("beforeend", '') + linkElement.insertAdjacentHTML("beforeend", '') element.appendChild(headerElement) const bodyElement = document.createElement("div") @@ -172,7 +172,7 @@ function createInfoBlock(entry, isPreview) { // Adds edit button only if element is not deleted if (!isPreview && (!entry.diff || entry.diff !== "delete")) { const editElement = document.createElement("a") - editElement.textContent = "Edit" + editElement.innerHTML = ' Edit' editElement.className = "btn btn-sm btn-outline-primary" editElement.href = "./?mode=draw&id=" + entry.id + formatHash(false) editElement.title = "Edit " + entry.name diff --git a/web/about.html b/web/about.html index b360de054..f52a52842 100644 --- a/web/about.html +++ b/web/about.html @@ -27,6 +27,8 @@ + + diff --git a/web/index.html b/web/index.html index bfe5bbcf8..07ba680a1 100644 --- a/web/index.html +++ b/web/index.html @@ -137,7 +137,8 @@ @@ -198,8 +199,7 @@
Atlas Entries List
- Draw - +
- +
@@ -327,11 +327,11 @@
Need Help?
- +
- +
From dbb5d0970d8321a6c39d33b8682ef9c0408b1014 Mon Sep 17 00:00:00 2001 From: Hans5958 Date: Wed, 26 Jul 2023 19:01:06 +0700 Subject: [PATCH 02/16] First attempt on filter-first atlas Last time it was period-first (shown by period, then filter for search), now it is filter-first --- web/_js/config.js | 1 - web/_js/main/draw.js | 39 +++--- web/_js/main/infoblock.js | 28 +++- web/_js/main/main.js | 56 +++----- web/_js/main/overlap.js | 14 +- web/_js/main/time.js | 75 ++++++++-- web/_js/main/view.js | 287 ++++++++++++++++++++------------------ 7 files changed, 281 insertions(+), 219 deletions(-) diff --git a/web/_js/config.js b/web/_js/config.js index a332c00ae..7a8076616 100644 --- a/web/_js/config.js +++ b/web/_js/config.js @@ -327,7 +327,6 @@ window.defaultVariation = defaultVariation let defaultPeriod = variationsConfig[defaultVariation].default window.defaultPeriod = defaultPeriod -console.log(window.defaultPeriod); const useNumericalId = true window.useNumericalId = useNumericalId diff --git a/web/_js/main/draw.js b/web/_js/main/draw.js index c2b407fff..00df682fb 100644 --- a/web/_js/main/draw.js +++ b/web/_js/main/draw.js @@ -112,7 +112,7 @@ function initDraw() { wrapper.classList.remove('listHidden') bsOffcanvasDraw.show() - window.render = render + window.renderHighlight = renderHighlight window.renderBackground = renderBackground window.updateHovering = updateHovering @@ -126,12 +126,12 @@ function initDraw() { let highlightUncharted = highlightUnchartedEl.checked - renderBackground(atlas) + renderBackground(atlasDisplay) applyView() container.style.cursor = "crosshair" - render(path) + renderHighlight(path) container.addEventListener("mousedown", e => { lastPos = [ @@ -169,7 +169,7 @@ function initDraw() { const coords = getCanvasCoords(e.clientX, e.clientY) path.push(coords) - render(path) + renderHighlight(path) undoHistory = [] redoButton.disabled = true @@ -186,13 +186,13 @@ function initDraw() { container.addEventListener("mousemove", e => { if (!dragging && drawing && path.length > 0) { const coords = getCanvasCoords(e.clientX, e.clientY) - render([...path, coords]) + renderHighlight([...path, coords]) } }) container.addEventListener("mouseout", function () { if (!dragging && drawing && path.length > 0) { - render(path) + renderHighlight(path) } }) @@ -229,19 +229,19 @@ function initDraw() { undoButton.addEventListener("click", e => { undo() const coords = getCanvasCoords(e.clientX, e.clientY) - render([...path, coords]) + renderHighlight([...path, coords]) }) redoButton.addEventListener("click", e => { redo() const coords = getCanvasCoords(e.clientX, e.clientY) - render([...path, coords]) + renderHighlight([...path, coords]) }) resetButton.addEventListener("click", e => { reset() const coords = getCanvasCoords(e.clientX, e.clientY) - render([...path, coords]) + renderHighlight([...path, coords]) }) resetButton.addEventListener("blur", function () { @@ -270,7 +270,7 @@ function initDraw() { highlightUnchartedEl.addEventListener("click", function () { highlightUncharted = this.checked - render(path) + renderHighlight(path) }) function generateExportObject() { @@ -392,7 +392,7 @@ function initDraw() { } function preview() { - let infoElement = createInfoBlock(generateExportObject(), true) + let infoElement = createInfoBlock(generateExportObject(), 1) objectsContainer.replaceChildren() objectsContainer.appendChild(infoElement) closeObjectsListButton.classList.remove("d-none") @@ -484,17 +484,17 @@ function initDraw() { closeObjectsListButton.classList.add("d-none") } - function renderBackground() { + function renderBackground(atlas) { backgroundContext.clearRect(0, 0, highlightCanvas.width, highlightCanvas.height) backgroundContext.fillStyle = "rgba(0, 0, 0, 1)" - //backgroundContext.fillRect(0, 0, canvas.width, canvas.height) + //backgroundContext.fillRect(0, 0, canvas.width, renderBackgroundcanvas.height) - for (let i = 0; i < atlas.length; i++) { - - const path = atlas[i].path + for (const entry of Object.values(atlas)) { + const path = entry.path + backgroundContext.beginPath() if (path[0]) { @@ -511,7 +511,7 @@ function initDraw() { } } - function render(path) { + function renderHighlight(path) { if (!Array.isArray(path)) return @@ -556,8 +556,7 @@ function initDraw() { const getEntry = id => { if (!id) return - const entries = atlasAll.filter(entry => entry.id.toString() === id.toString()) - if (entries.length === 1) return entries[0] + return atlasAll[id] } function addFieldButton(inputButton, inputGroup, array, index, name) { @@ -1225,7 +1224,7 @@ function updatePeriodGroups() { function updatePath(newPath, newUndoHistory) { path = newPath || path if (path.length > 3) center = calculateCenter(path) - render(path) + renderHighlight(path) undoButton.disabled = path.length === 0; // Maybe make it undo the cancel action in the future undoHistory = newUndoHistory || [] redoButton.disabled = (!undoHistory.length) diff --git a/web/_js/main/infoblock.js b/web/_js/main/infoblock.js index ad5c8dd6c..4414b722d 100644 --- a/web/_js/main/infoblock.js +++ b/web/_js/main/infoblock.js @@ -31,7 +31,10 @@ function createInfoListItem(name, value) { return entryInfoListElement } -function createInfoBlock(entry, isPreview) { +// mode 0 = normal +// mode 1 = preview +// mode 2 = entry list but none on atlas +function createInfoBlock(entry, mode = 0) { const element = document.createElement("div") element.className = "card mb-2 overflow-hidden shadow" @@ -40,12 +43,23 @@ function createInfoBlock(entry, isPreview) { const linkElement = document.createElement("a") linkElement.className = "text-decoration-none d-flex justify-content-between text-body" - if (isPreview) linkElement.href = "#" - else { - linkElement.href = formatHash(entry.id, null, null, null, false, false, false) + if (mode === 1) linkElement.href = "#" + else if (mode === 2) { + const [nearestPeriod, nearestVariation] = getNearestPeriod(entry, currentPeriod, currentVariation) + const hash = formatHash(entry.id, nearestPeriod, nearestPeriod, nearestVariation, false, false, false) + linkElement.href = hash linkElement.addEventListener('click', e => { e.preventDefault() - location.hash = formatHash(entry.id, null, null, null, false, false, false) + location.hash = hash + window.dispatchEvent(new HashChangeEvent("hashchange")) + }) + + } else { + const hash = formatHash(entry.id, null, null, null, false, false, false) + linkElement.href = hash + linkElement.addEventListener('click', e => { + e.preventDefault() + location.hash = hash window.dispatchEvent(new HashChangeEvent("hashchange")) }) } @@ -92,7 +106,7 @@ function createInfoBlock(entry, isPreview) { } // Entry data submitted to preview does not include center or path - if (!isPreview) { + if (mode === 0) { const [x, y] = entry?.center listElement.appendChild(createInfoListItem("Position: ", `${Math.floor(x)}, ${Math.floor(y)}`)) @@ -170,7 +184,7 @@ function createInfoBlock(entry, isPreview) { element.appendChild(idElementContainer) // Adds edit button only if element is not deleted - if (!isPreview && (!entry.diff || entry.diff !== "delete")) { + if (mode === 0 && (!entry.diff || entry.diff !== "delete")) { const editElement = document.createElement("a") editElement.innerHTML = ' Edit' editElement.className = "btn btn-sm btn-outline-primary" diff --git a/web/_js/main/main.js b/web/_js/main/main.js index 7191d1aeb..1fdf5c76a 100644 --- a/web/_js/main/main.js +++ b/web/_js/main/main.js @@ -72,8 +72,6 @@ function updateHash(...args) { if (location.hash !== newLocation.hash) history.replaceState({}, "", newLocation) } -let atlas = null -window.atlas = atlas let atlasAll = null window.atlasAll = atlasAll @@ -106,9 +104,10 @@ async function init() { // For Reviewing Reddit Changes // const atlasRef = '../tools/temp-atlas.json' - const atlasRef = params.get('atlas') || './atlas.json' - const atlasResp = await fetch(atlasRef) - atlasAll = updateAtlasAll(await atlasResp.json()) + const atlasAllUrl = params.get('atlas') || './atlas.json' + const atlasAllResp = await fetch(atlasAllUrl) + atlasAll = generateAtlasAll(await atlasAllResp.json()) + // console.log(atlas, atlasOrder) const hash = window.location.hash.substring(1) const [, hashPeriod, hashX, hashY, hashZoom] = hash.split('/') @@ -151,43 +150,27 @@ async function init() { const liveAtlasRef = params.get('liveatlas') || `https://${prodDomain}/atlas.json` const liveAtlasResp = await fetch(liveAtlasRef) let liveAtlas = await liveAtlasResp.json() - liveAtlas = updateAtlasAll(liveAtlas) + liveAtlas = generateAtlasAll(liveAtlas) - const liveAtlasReduced = liveAtlas.reduce((atlas, entry) => { - delete entry._index - atlas[entry.id] = entry - return atlas - }, {}) // Mark added/edited entries - atlasAll = atlasAll.map(function (entry) { - delete entry._index - if (!liveAtlasReduced[entry.id]) { + for (const entry of Object.values(atlasAll)) { + if (!liveAtlas[entry.id]) { entry.diff = "add" - } else if (JSON.stringify(entry) !== JSON.stringify(liveAtlasReduced[entry.id])) { + } else { + if (JSON.stringify({ ...entry, _index: undefined }) === JSON.stringify({ ...liveAtlas[entry.id], _index: undefined })) continue entry.diff = "edit" } - return entry - }) + } - // Mark removed entries - const atlasReduced = atlasAll.reduce((atlas, entry) => { - delete entry._index - atlas[entry.id] = entry - return atlas - }, {}) - const removedEntries = liveAtlas.filter(entry => !atlasReduced[entry.id]).map(entry => { - delete entry._index - entry.diff = "delete" - return entry - }) - atlasAll.push(...removedEntries) + console.log(mode.includes('only')) - if (mode.includes("only")) { - atlasAll = atlasAll.filter(entry => entry.diff) + if (mode.includes('only')) { + for (const key of Object.keys(atlasAll)) { + if (atlasAll[key].diff) continue + delete atlasAll[key] + } } - atlas = generateAtlasForPeriod() - } catch (error) { console.warn("Diff mode failed to load, reverting to normal view.", error) } finally { @@ -506,7 +489,8 @@ async function init() { } -function updateAtlasAll(atlas = atlasAll) { +function generateAtlasAll(atlas = atlasAll) { + const newAtlas = {} for (const index in atlas) { const entry = atlas[index] entry._index = index @@ -528,8 +512,10 @@ function updateAtlasAll(atlas = atlasAll) { } entry.path = currentPath entry.center = currentCenter + newAtlas[entry.id] = entry } - return atlas + // console.log(newAtlas) + return newAtlas } // Announcement system diff --git a/web/_js/main/overlap.js b/web/_js/main/overlap.js index 98c487745..a20941ec8 100644 --- a/web/_js/main/overlap.js +++ b/web/_js/main/overlap.js @@ -9,21 +9,15 @@ function initOverlap() { window.renderBackground = renderBackground - // const hovered = [] + updateAtlas() - resetEntriesList() - renderBackground(atlas) - render() + // const hovered = [] document.addEventListener('timeupdate', () => { - atlasDisplay = atlas.slice() - resetEntriesList() - renderBackground(atlasDisplay) - render() + updateAtlas() }) applyView() - render() updateLines() if (window.location.hash) { @@ -37,7 +31,7 @@ function initOverlap() { backgroundContext.fillStyle = "rgba(255, 255, 255, 1)" backgroundContext.fillRect(0, 0, highlightCanvas.width, highlightCanvas.height) - for (const entry of atlas) { + for (const entry of Object.values(atlas)) { const path = entry.path diff --git a/web/_js/main/time.js b/web/_js/main/time.js index ff8a62bbf..0463db8db 100644 --- a/web/_js/main/time.js +++ b/web/_js/main/time.js @@ -32,6 +32,9 @@ let currentPeriod = defaultPeriod window.currentVariation = currentVariation window.currentPeriod = currentPeriod +let atlasDisplay = {} +window.atlasDisplay = atlasDisplay + // SETUP if (variationsConfig[currentVariation].versions.length === 1) bottomBar.classList.add('no-time-slider') @@ -163,8 +166,6 @@ async function updateTime(newPeriod = currentPeriod, newVariation = currentVaria await updateBackground(newPeriod, newVariation) - atlas = generateAtlasForPeriod(newPeriod, newVariation) - dispatchTimeUpdateEvent(newPeriod, newVariation, atlas) delete document.body.dataset.canvasLoading tooltip.dataset.forceVisible = "" @@ -175,24 +176,30 @@ async function updateTime(newPeriod = currentPeriod, newVariation = currentVaria } -function generateAtlasForPeriod(newPeriod = currentPeriod, newVariation = currentVariation) { +function generateAtlasDisplay(prevAtlas, prevAtlasOrder, newPeriod = currentPeriod, newVariation = currentVariation) { + + const newAtlas = {} + const newAtlasOrderDisplayed = [] + const newAtlasOrderNotDisplayed = [] + + for (const id of prevAtlasOrder) { + + newAtlasOrderNotDisplayed.push(id) + const entry = prevAtlas[id] - const atlas = [] - for (const entry of atlasAll) { let chosenIndex const validPeriods2 = Object.keys(entry.path) - for (const i in validPeriods2) { + periodCheck: for (const i in validPeriods2) { const validPeriods = validPeriods2[i].split(', ') for (const j in validPeriods) { const [start, end, variation] = parsePeriod(validPeriods[j]) if (isOnPeriod(start, end, variation, newPeriod, newVariation)) { chosenIndex = i - break + break periodCheck } } - if (chosenIndex !== undefined) break } if (chosenIndex === undefined) continue @@ -201,14 +208,18 @@ function generateAtlasForPeriod(newPeriod = currentPeriod, newVariation = curren if (pathChosen === undefined) continue - atlas.push({ + newAtlas[id] = { ...entry, path: pathChosen, center: centerChosen, - }) + } + + newAtlasOrderNotDisplayed.pop() + newAtlasOrderDisplayed.push(id) + } - return atlas + return [newAtlas, [...newAtlasOrderDisplayed, ...newAtlasOrderNotDisplayed]] } @@ -321,4 +332,44 @@ function downloadCanvas() { document.body.appendChild(linkEl) linkEl.click() document.body.removeChild(linkEl) -} \ No newline at end of file +} + +function getNearestPeriod(entry, targetPeriod, targetVariation) { + + const entryPathPeriods = Object.keys(entry.path) + + let nearestScore, nearestPeriod, nearestVariation + + function updateNearest(newScore, newPeriod, newVariation) { + if (newScore >= nearestScore) return + nearestScore = newScore + nearestPeriod = newPeriod + nearestVariation = newVariation + } + + checkEntryPathPeriod: for (const entryPathPeriod of entryPathPeriods) { + const pathPeriods = entryPathPeriod.split(', ') + + for (const j in pathPeriods) { + const [pathStart, pathEnd, pathVariation] = parsePeriod(pathPeriods[j]) + if (isOnPeriod(pathStart, pathEnd, pathVariation, targetPeriod, targetVariation)) { + updateNearest(0, targetPeriod, targetVariation) + } else { + if (pathVariation !== targetVariation) { + updateNearest(Infinity, pathStart, pathVariation) + break checkEntryPathPeriod + } else { + if (Math.abs(pathStart - targetPeriod) < Math.abs(pathEnd - targetPeriod)) { + updateNearest(Math.abs(pathStart - targetPeriod), pathStart, pathVariation) + } else { + updateNearest(Math.abs(pathEnd - targetPeriod), pathStart, pathVariation) + } + } + } + } + + } + + return [ nearestPeriod, nearestVariation ] + +} diff --git a/web/_js/main/view.js b/web/_js/main/view.js index 5c82c52ec..8e4b6063b 100644 --- a/web/_js/main/view.js +++ b/web/_js/main/view.js @@ -43,7 +43,11 @@ objectEditNav.className = "btn btn-outline-primary" objectEditNav.id = "objectEditNav" objectEditNav.textContent = "Edit" -let atlasDisplay +let atlas = null +window.atlas = atlas + +let atlasOrder = [] +window.atlasOrder = atlasOrder const entriesLimit = 50 let entriesOffset = 0 @@ -72,11 +76,11 @@ let lastPos = [0, 0] let fixed = false; // Fix hovered items in place, so that clicking on links is possible searchInput.addEventListener("input", function () { - resetEntriesList() + updateAtlas() }) sortInput.addEventListener("input", function () { - resetEntriesList() + updateAtlas() }) offcanvasDraw.addEventListener('show.bs.offcanvas', () => { @@ -112,7 +116,7 @@ offcanvasList.addEventListener('shown.bs.offcanvas', e => { wrapper.classList.remove('listTransitioning') updateHovering(e) applyView() - render() + renderHighlight() updateLines() }) @@ -127,7 +131,7 @@ offcanvasList.addEventListener('hidden.bs.offcanvas', e => { wrapper.classList.remove('listTransitioning') updateHovering(e) applyView() - render() + renderHighlight() updateLines() }) @@ -145,7 +149,7 @@ function clearObjectsList() { objectsContainer.replaceChildren() updateLines() fixed = false - render() + renderHighlight() objectEditNav.remove() updateHash(false) document.title = pageTitle @@ -159,7 +163,7 @@ function toggleFixed(e, tapped) { fixed = !fixed if (!fixed) { updateHovering(e, tapped) - render() + renderHighlight() } entriesList.classList.add("disableHover") objectsListOverflowNotice.classList.add("d-none") @@ -177,7 +181,7 @@ objectsContainer.addEventListener("scroll", () => { window.addEventListener("resize", () => { applyView() - render() + renderHighlight() updateLines() }) @@ -260,9 +264,9 @@ function renderBackground(atlas) { backgroundContext.fillStyle = "rgba(0, 0, 0, 0.6)" backgroundContext.fillRect(0, 0, backgroundCanvas.width, backgroundCanvas.height) - for (let i = 0; i < atlas.length; i++) { + for (const entry of Object.values(atlas)) { - const path = atlas[i].path + const path = entry.path backgroundContext.beginPath() @@ -279,7 +283,7 @@ function renderBackground(atlas) { backgroundContext.closePath() let bgStrokeStyle - switch (atlas[i].diff) { + switch (entry.diff) { case "add": bgStrokeStyle = "rgba(0, 255, 0, 1)" backgroundContext.lineWidth = 2 @@ -299,45 +303,39 @@ function renderBackground(atlas) { backgroundContext.strokeStyle = bgStrokeStyle backgroundContext.stroke() backgroundContext.lineWidth = 1 - } -} -function buildObjectsList(filter, sort) { - atlasDisplay = atlas.slice() - - if (filter) { - atlasDisplay = atlas.filter(entry => { - return ( - entry.name.toLowerCase().includes(filter.toLowerCase()) - || entry.description?.toLowerCase().includes(filter.toLowerCase()) - || Object.values(entry.links).flat().some(str => str.toLowerCase().includes(filter)) - || entry.id.toString() === filter - ) - }) - document.getElementById("atlasSize").innerHTML = "Found " + atlasDisplay.length + " entries." - } else { - document.getElementById("atlasSize").innerHTML = "The Atlas contains " + atlasDisplay.length + " entries." } - renderBackground(atlasDisplay) - render() +} - sort ||= defaultSort - document.getElementById("sort").value = sort +function filterAtlas(prevAtlas) { - //console.log(sort) + const sort = sortInput.value || defaultSort + const search = searchInput?.value.toLowerCase() + let newAtlas = Object.assign({}, prevAtlas) + let newAtlasOrder = [] - let sortFunction + document.getElementById("atlasSize").innerHTML = "" + + if (search) { + for (const [id, entry] of Object.entries(prevAtlas)) { + if (!( + entry.name.toLowerCase().includes(search.toLowerCase()) || + entry.description?.toLowerCase().includes(search.toLowerCase()) || + Object.values(entry.links).flat().some(str => str.toLowerCase().includes(search)) || + id.toString() === search + )) delete newAtlas[id] + } + } + + // document.getElementById("sort").value = sort - //console.log(sort) + let sortFunction switch (sort) { case "shuffle": - sortFunction = null - if (entriesOffset === 0) { - shuffle() - } + sortFunction = () => Math.random() - 0.5 break case "alphaAsc": sortFunction = (a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()) @@ -369,10 +367,36 @@ function buildObjectsList(filter, sort) { break } + newAtlasOrder = Object.keys(newAtlas) if (sortFunction) { - atlasDisplay.sort(sortFunction) + newAtlasOrder = newAtlasOrder.sort((a, b) => sortFunction(prevAtlas[a], prevAtlas[b])) } + // console.log(newAtlas, newAtlasOrder) + + return [newAtlas, newAtlasOrder] + +} + +function updateAtlas() { + ;[atlas, atlasOrder] = filterAtlas(atlasAll) + ;[atlasDisplay, atlasOrder] = generateAtlasDisplay(atlas, atlasOrder, currentPeriod, currentVariation) + const atlasSizeEl = document.getElementById("atlasSize") + if (Object.keys(atlas).length === Object.keys(atlasAll).length) { + atlasSizeEl.innerHTML = Object.keys(atlasAll).length + " entries in total." + } else { + atlasSizeEl.innerHTML = "Found " + Object.keys(atlas).length + " entries." + } + atlasSizeEl.innerHTML += " Displaying " + Object.keys(atlasDisplay).length + " entries." + resetEntriesList() + renderBackground(atlasDisplay) + renderHighlight(atlasDisplay) +} + +function buildObjectsList() { + + let i = 0 + moreEntriesButton.removeEventListener('click', showMoreEntries) showMoreEntries = () => { @@ -380,58 +404,67 @@ function buildObjectsList(filter, sort) { entriesList.removeChild(moreEntriesButton) } - for (let i = entriesOffset; i < entriesOffset + entriesLimit; i++) { + let entriesLeft = entriesLimit + let element - if (i >= atlasDisplay.length) break - - const element = createInfoBlock(atlasDisplay[i]) - const entry = atlasDisplay[i] - - element.addEventListener("mouseenter", function () { - if (fixed || dragging) return - objectsContainer.replaceChildren() - - previousScaleZoomOrigin ??= [...scaleZoomOrigin] - previousZoom ??= zoom - setView(entry.center[0], entry.center[1], setZoomByPath(entry.path)) - - hovered = [entry] - render() - hovered[0].element = this - updateLines() - - }) - - element.addEventListener("click", e => { - toggleFixed(e) - if (!fixed) return - previousScaleZoomOrigin ??= [...scaleZoomOrigin] - previousZoom ??= zoom - applyView() - }) - - element.addEventListener("mouseleave", () => { - if (fixed || dragging) return - - scaleZoomOrigin = [...previousScaleZoomOrigin] - zoom = previousZoom - previousScaleZoomOrigin = undefined - previousZoom = undefined - applyView() + while (entriesLeft > 0 && atlasOrder.length > i) { + + if (atlasDisplay[atlasOrder[i]]) { + // console.log(i, entriesLeft) - hovered = [] - updateLines() - render() - }) + const entry = atlasDisplay[atlasOrder[i]] + element = createInfoBlock(entry) + + element.addEventListener("mouseenter", function () { + if (fixed || dragging) return + objectsContainer.replaceChildren() + + previousScaleZoomOrigin ??= [...scaleZoomOrigin] + previousZoom ??= zoom + setView(entry.center[0], entry.center[1], setZoomByPath(entry.path)) + + hovered = [entry] + renderHighlight() + hovered[0].element = this + updateLines() + + }) + + element.addEventListener("click", e => { + fixed = true + if (!fixed) return + previousScaleZoomOrigin ??= [...scaleZoomOrigin] + previousZoom ??= zoom + applyView() + }) + + element.addEventListener("mouseleave", () => { + if (fixed || dragging) return + + scaleZoomOrigin = [...previousScaleZoomOrigin] + zoom = previousZoom + previousScaleZoomOrigin = undefined + previousZoom = undefined + applyView() + + hovered = [] + updateLines() + renderHighlight() + }) + } else { + const entry = atlas[atlasOrder[i]] + element = createInfoBlock(entry, 2) + } + + i += 1 + entriesLeft -= 1 entriesList.appendChild(element) } - entriesOffset += entriesLimit - - if (atlasDisplay.length > entriesOffset) { - moreEntriesButton.innerHTML = "Show " + Math.min(entriesLimit, atlasDisplay.length - entriesOffset) + " more" + if (atlasOrder.length > i) { + moreEntriesButton.innerHTML = "Show " + Math.min(entriesLimit, atlasOrder.length - i) + " more" entriesList.appendChild(moreEntriesButton) } @@ -451,18 +484,15 @@ function shuffle() { } } -function resetEntriesList() { +async function resetEntriesList() { entriesOffset = 0 entriesList.replaceChildren() entriesList.appendChild(moreEntriesButton) - const sort = sortInput.value || defaultSort - const search = searchInput?.value.toLowerCase() - - buildObjectsList(search, sort) + buildObjectsList() } -async function render() { +async function renderHighlight() { highlightContext.clearRect(0, 0, highlightCanvas.width, highlightCanvas.height) @@ -478,10 +508,8 @@ async function render() { container.style.cursor = "default" } - for (let i = 0; i < hovered.length; i++) { - const path = hovered[i].path highlightContext.beginPath() @@ -507,27 +535,27 @@ async function render() { highlightContext.globalCompositeOperation = "source-out" highlightContext.drawImage(backgroundCanvas, 0, 0) - if (hovered.length === 1 && hovered[0].path.length && hovered[0].overrideImage) { - const undisputableHovered = hovered[0] - // Find the left-topmost point of all the paths - const entryPosition = getPositionOfEntry(undisputableHovered) - if (entryPosition) { - const [startX, startY] = entryPosition - const overrideImage = new Image() - const loadingPromise = new Promise((res, rej) => { - overrideImage.onerror = rej - overrideImage.onload = res - }) - overrideImage.src = "imageOverrides/" + undisputableHovered.overrideImage - try { - await loadingPromise - highlightContext.globalCompositeOperation = "source-over" - highlightContext.drawImage(overrideImage, startX, startY) - } catch (ex) { - console.error("Cannot override image.", ex) - } - } - } + // if (hovered.length === 1 && hovered[0].path.length && hovered[0].overrideImage) { + // const undisputableHovered = hovered[0] + // // Find the left-topmost point of all the paths + // const entryPosition = getPositionOfEntry(undisputableHovered) + // if (entryPosition) { + // const [startX, startY] = entryPosition + // const overrideImage = new Image() + // const loadingPromise = new Promise((res, rej) => { + // overrideImage.onerror = rej + // overrideImage.onload = res + // }) + // overrideImage.src = "imageOverrides/" + undisputableHovered.overrideImage + // try { + // await loadingPromise + // highlightContext.globalCompositeOperation = "source-over" + // highlightContext.drawImage(overrideImage, startX, startY) + // } catch (ex) { + // console.error("Cannot override image.", ex) + // } + // } + // } for (let i = 0; i < hovered.length; i++) { @@ -593,7 +621,7 @@ function updateHovering(e, tapped) { if (!(pos[0] <= canvasSize.x + canvasOffset.x + 200 && pos[0] >= canvasOffset.x - 200 && pos[1] <= canvasSize.y + canvasOffset.y + 200 && pos[1] >= canvasOffset.x - 200)) return const newHovered = [] - for (const entry of atlasDisplay) { + for (const entry of Object.values(atlasDisplay)) { if (pointIsInPolygon(pos, entry.path)) newHovered.push(entry) } @@ -639,7 +667,7 @@ function updateHovering(e, tapped) { objectsListOverflowNotice.classList.add("d-none") entriesList.classList.remove("disableHover") } - render() + renderHighlight() } window.addEventListener("hashchange", updateViewFromHash) @@ -678,14 +706,10 @@ function updateViewFromHash() { // Highlight entry from hash - const entries = atlas.filter(e => { - return e.id.toString() === hashEntryId - }) - - if (entries.length !== 1) return + const entry = atlasDisplay[hashEntryId] + console.log(entry) + if (!entry) return - const entry = entries[0] - document.title = entry.name + " on " + pageTitle if ((!entry.diff || entry.diff !== "delete")) { @@ -713,7 +737,7 @@ function updateViewFromHash() { entriesList.classList.add("disableHover") hovered = [entry] - render() + renderHighlight() hovered[0].element = infoElement updateLines() } @@ -741,13 +765,10 @@ function setZoomByPath(path) { function initView() { - buildObjectsList(null, null) - renderBackground(atlas) - render() - + updateAtlas() + document.addEventListener('timeupdate', () => { - atlasDisplay = atlas.slice() - resetEntriesList() + updateAtlas() }) // parse linked atlas entry id from link hash @@ -758,22 +779,20 @@ function initView() { }*/ applyView() - render() updateLines() } function initExplore() { - window.updateHovering = updateHovering - window.render = () => { } + window.renderHighlight = () => { } function updateHovering(e, tapped) { if (dragging || (fixed && !tapped)) return updateCoordsDisplay(e) } - renderBackground(atlas) + renderBackground({}) applyView() From d7fb7d7971c74f2dcc75fcce24a6ef8cac458c27 Mon Sep 17 00:00:00 2001 From: Hans5958 Date: Thu, 27 Jul 2023 14:41:57 +0700 Subject: [PATCH 03/16] Remove image overrides system It is unused, and I think it can be substituted with the layer system --- web/_js/main/view.js | 22 ------------------- .../Put the image overrides in this directory | 0 2 files changed, 22 deletions(-) delete mode 100644 web/imageOverrides/Put the image overrides in this directory diff --git a/web/_js/main/view.js b/web/_js/main/view.js index 8e4b6063b..580c5cff9 100644 --- a/web/_js/main/view.js +++ b/web/_js/main/view.js @@ -535,28 +535,6 @@ async function renderHighlight() { highlightContext.globalCompositeOperation = "source-out" highlightContext.drawImage(backgroundCanvas, 0, 0) - // if (hovered.length === 1 && hovered[0].path.length && hovered[0].overrideImage) { - // const undisputableHovered = hovered[0] - // // Find the left-topmost point of all the paths - // const entryPosition = getPositionOfEntry(undisputableHovered) - // if (entryPosition) { - // const [startX, startY] = entryPosition - // const overrideImage = new Image() - // const loadingPromise = new Promise((res, rej) => { - // overrideImage.onerror = rej - // overrideImage.onload = res - // }) - // overrideImage.src = "imageOverrides/" + undisputableHovered.overrideImage - // try { - // await loadingPromise - // highlightContext.globalCompositeOperation = "source-over" - // highlightContext.drawImage(overrideImage, startX, startY) - // } catch (ex) { - // console.error("Cannot override image.", ex) - // } - // } - // } - for (let i = 0; i < hovered.length; i++) { const path = hovered[i].path diff --git a/web/imageOverrides/Put the image overrides in this directory b/web/imageOverrides/Put the image overrides in this directory deleted file mode 100644 index e69de29bb..000000000 From fe1b6b222a4c1401d1bc0b86a364ea6b0f8d65f6 Mon Sep 17 00:00:00 2001 From: Hans5958 Date: Thu, 27 Jul 2023 14:43:37 +0700 Subject: [PATCH 04/16] Remove console logs --- web/_js/main/draw.js | 2 -- web/_js/main/main.js | 2 -- web/_js/main/view.js | 1 - 3 files changed, 5 deletions(-) diff --git a/web/_js/main/draw.js b/web/_js/main/draw.js index 00df682fb..7952cedad 100644 --- a/web/_js/main/draw.js +++ b/web/_js/main/draw.js @@ -386,8 +386,6 @@ function initDraw() { } githubPostButton.href = githubPostUrl - console.log(githubPostUrl) - exportModal.show() } diff --git a/web/_js/main/main.js b/web/_js/main/main.js index 1fdf5c76a..febffdacd 100644 --- a/web/_js/main/main.js +++ b/web/_js/main/main.js @@ -162,8 +162,6 @@ async function init() { } } - console.log(mode.includes('only')) - if (mode.includes('only')) { for (const key of Object.keys(atlasAll)) { if (atlasAll[key].diff) continue diff --git a/web/_js/main/view.js b/web/_js/main/view.js index 580c5cff9..f47bd2197 100644 --- a/web/_js/main/view.js +++ b/web/_js/main/view.js @@ -685,7 +685,6 @@ function updateViewFromHash() { // Highlight entry from hash const entry = atlasDisplay[hashEntryId] - console.log(entry) if (!entry) return document.title = entry.name + " on " + pageTitle From e10906de6770ecb41e96c7d62959fb9517617855 Mon Sep 17 00:00:00 2001 From: Hans5958 Date: Thu, 27 Jul 2023 16:22:40 +0700 Subject: [PATCH 05/16] Avoid doing view parameters on edit buttons --- web/_js/main/infoblock.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/_js/main/infoblock.js b/web/_js/main/infoblock.js index 4414b722d..0af96eb53 100644 --- a/web/_js/main/infoblock.js +++ b/web/_js/main/infoblock.js @@ -188,7 +188,7 @@ function createInfoBlock(entry, mode = 0) { const editElement = document.createElement("a") editElement.innerHTML = ' Edit' editElement.className = "btn btn-sm btn-outline-primary" - editElement.href = "./?mode=draw&id=" + entry.id + formatHash(false) + editElement.href = "./?mode=draw&id=" + entry.id + formatHash(false, null, null, null, false, false, false) editElement.title = "Edit " + entry.name idElementContainer.appendChild(editElement) } From 45430f766fcfa4cb8548f5d73da70dfc31190163 Mon Sep 17 00:00:00 2001 From: Hans5958 Date: Thu, 27 Jul 2023 17:17:20 +0700 Subject: [PATCH 06/16] Make clicking undisplayed entries list work --- web/_js/main/infoblock.js | 7 ++++--- web/_js/main/time.js | 19 ++++++++++--------- web/_js/main/view.js | 37 ++++++++++++++++++++++++++++--------- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/web/_js/main/infoblock.js b/web/_js/main/infoblock.js index 0af96eb53..7c11626bc 100644 --- a/web/_js/main/infoblock.js +++ b/web/_js/main/infoblock.js @@ -44,16 +44,17 @@ function createInfoBlock(entry, mode = 0) { const linkElement = document.createElement("a") linkElement.className = "text-decoration-none d-flex justify-content-between text-body" if (mode === 1) linkElement.href = "#" + else if (mode === 2) { - const [nearestPeriod, nearestVariation] = getNearestPeriod(entry, currentPeriod, currentVariation) + const [nearestPeriod, nearestVariation, nearestKey] = getNearestPeriod(entry, currentPeriod, currentVariation) const hash = formatHash(entry.id, nearestPeriod, nearestPeriod, nearestVariation, false, false, false) linkElement.href = hash linkElement.addEventListener('click', e => { e.preventDefault() location.hash = hash - window.dispatchEvent(new HashChangeEvent("hashchange")) + // window.dispatchEvent(new HashChangeEvent("hashchange")) }) - + } else { const hash = formatHash(entry.id, null, null, null, false, false, false) linkElement.href = hash diff --git a/web/_js/main/time.js b/web/_js/main/time.js index 0463db8db..6f31cb661 100644 --- a/web/_js/main/time.js +++ b/web/_js/main/time.js @@ -336,19 +336,20 @@ function downloadCanvas() { function getNearestPeriod(entry, targetPeriod, targetVariation) { - const entryPathPeriods = Object.keys(entry.path) + const pathKeys = Object.keys(entry.path) - let nearestScore, nearestPeriod, nearestVariation + let nearestScore, nearestPeriod, nearestVariation, nearestKey - function updateNearest(newScore, newPeriod, newVariation) { + function updateNearest(newScore, newPeriod, newVariation, newKey) { if (newScore >= nearestScore) return nearestScore = newScore nearestPeriod = newPeriod nearestVariation = newVariation + nearestKey = newKey } - checkEntryPathPeriod: for (const entryPathPeriod of entryPathPeriods) { - const pathPeriods = entryPathPeriod.split(', ') + checkEntryPathPeriod: for (const pathKey of pathKeys) { + const pathPeriods = pathKey.split(', ') for (const j in pathPeriods) { const [pathStart, pathEnd, pathVariation] = parsePeriod(pathPeriods[j]) @@ -356,13 +357,13 @@ function getNearestPeriod(entry, targetPeriod, targetVariation) { updateNearest(0, targetPeriod, targetVariation) } else { if (pathVariation !== targetVariation) { - updateNearest(Infinity, pathStart, pathVariation) + updateNearest(Infinity, pathStart, pathVariation, pathKey) break checkEntryPathPeriod } else { if (Math.abs(pathStart - targetPeriod) < Math.abs(pathEnd - targetPeriod)) { - updateNearest(Math.abs(pathStart - targetPeriod), pathStart, pathVariation) + updateNearest(Math.abs(pathStart - targetPeriod), pathStart, pathVariation, pathKey) } else { - updateNearest(Math.abs(pathEnd - targetPeriod), pathStart, pathVariation) + updateNearest(Math.abs(pathEnd - targetPeriod), pathStart, pathVariation, pathKey) } } } @@ -370,6 +371,6 @@ function getNearestPeriod(entry, targetPeriod, targetVariation) { } - return [ nearestPeriod, nearestVariation ] + return [ nearestPeriod, nearestVariation, nearestKey ] } diff --git a/web/_js/main/view.js b/web/_js/main/view.js index f47bd2197..3c601963d 100644 --- a/web/_js/main/view.js +++ b/web/_js/main/view.js @@ -412,7 +412,7 @@ function buildObjectsList() { if (atlasDisplay[atlasOrder[i]]) { // console.log(i, entriesLeft) - const entry = atlasDisplay[atlasOrder[i]] + let entry = atlasDisplay[atlasOrder[i]] element = createInfoBlock(entry) element.addEventListener("mouseenter", function () { @@ -421,18 +421,17 @@ function buildObjectsList() { previousScaleZoomOrigin ??= [...scaleZoomOrigin] previousZoom ??= zoom - setView(entry.center[0], entry.center[1], setZoomByPath(entry.path)) + setView(entry.center[0], entry.center[1], calculateZoomFromPath(entry.path)) hovered = [entry] renderHighlight() hovered[0].element = this updateLines() - + }) element.addEventListener("click", e => { fixed = true - if (!fixed) return previousScaleZoomOrigin ??= [...scaleZoomOrigin] previousZoom ??= zoom applyView() @@ -452,8 +451,28 @@ function buildObjectsList() { renderHighlight() }) } else { - const entry = atlas[atlasOrder[i]] + let entry = atlas[atlasOrder[i]] element = createInfoBlock(entry, 2) + + element.addEventListener("click", async e => { + const [nearestPeriod, nearestVariation] = getNearestPeriod(entry, currentPeriod, currentVariation) + + await updateTime(nearestPeriod, nearestVariation, true) + + entry = atlasDisplay[entry.id] + element = createInfoBlock(entry) + hovered = [{ ...entry, element }] + fixed = true + previousScaleZoomOrigin = undefined + previousZoom = undefined + + renderHighlight() + window.dispatchEvent(new HashChangeEvent("hashchange")) + + setView(entry.center[0], entry.center[1], calculateZoomFromPath(entry.path)) + updateLines() + + }) } i += 1 @@ -707,20 +726,20 @@ function updateViewFromHash() { setView( isNaN(hashX) ? entry.center[0] : Number(hashX), isNaN(hashY) ? entry.center[1] : Number(hashY), - isNaN(hashZoom) ? setZoomByPath(entry.path) : Number(hashZoom) + isNaN(hashZoom) ? calculateZoomFromPath(entry.path) : Number(hashZoom) ) closeObjectsListButton.classList.remove("d-none") entriesList.classList.add("disableHover") - hovered = [entry] + hovered = [{...entry, element: infoElement}] renderHighlight() - hovered[0].element = infoElement updateLines() } -function setZoomByPath(path) { +function calculateZoomFromPath(path) { + let zoom let boundingBox = [canvasSize.x + canvasOffset.x, canvasOffset.x, canvasSize.y + canvasOffset.y, canvasOffset.y] path?.forEach(([x, y]) => { boundingBox[0] = Math.min(boundingBox[0], x) From 5df2937765bc91c5d8e6d327ca2be5100382c734 Mon Sep 17 00:00:00 2001 From: Hans5958 Date: Thu, 27 Jul 2023 17:46:01 +0700 Subject: [PATCH 07/16] Make clicking undisplayed entries list work 2 Also make updateViewFromHash work again --- web/_js/main/infoblock.js | 5 ----- web/_js/main/view.js | 17 +++++++---------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/web/_js/main/infoblock.js b/web/_js/main/infoblock.js index 7c11626bc..0e74f8880 100644 --- a/web/_js/main/infoblock.js +++ b/web/_js/main/infoblock.js @@ -49,11 +49,6 @@ function createInfoBlock(entry, mode = 0) { const [nearestPeriod, nearestVariation, nearestKey] = getNearestPeriod(entry, currentPeriod, currentVariation) const hash = formatHash(entry.id, nearestPeriod, nearestPeriod, nearestVariation, false, false, false) linkElement.href = hash - linkElement.addEventListener('click', e => { - e.preventDefault() - location.hash = hash - // window.dispatchEvent(new HashChangeEvent("hashchange")) - }) } else { const hash = formatHash(entry.id, null, null, null, false, false, false) diff --git a/web/_js/main/view.js b/web/_js/main/view.js index 3c601963d..9a69a9619 100644 --- a/web/_js/main/view.js +++ b/web/_js/main/view.js @@ -455,6 +455,7 @@ function buildObjectsList() { element = createInfoBlock(entry, 2) element.addEventListener("click", async e => { + e.preventDefault() const [nearestPeriod, nearestVariation] = getNearestPeriod(entry, currentPeriod, currentVariation) await updateTime(nearestPeriod, nearestVariation, true) @@ -465,13 +466,9 @@ function buildObjectsList() { fixed = true previousScaleZoomOrigin = undefined previousZoom = undefined - - renderHighlight() - window.dispatchEvent(new HashChangeEvent("hashchange")) - - setView(entry.center[0], entry.center[1], calculateZoomFromPath(entry.path)) - updateLines() + const hash = formatHash(entry.id, nearestPeriod, nearestPeriod, nearestVariation, entry.center[0], entry.center[1], calculateZoomFromPath(entry.path)) + location.hash = hash }) } @@ -669,7 +666,7 @@ function updateHovering(e, tapped) { window.addEventListener("hashchange", updateViewFromHash) -function updateViewFromHash() { +async function updateViewFromHash() { const hash = window.location.hash.substring(1); //Remove hash prefix let [hashEntryId, hashPeriod, hashX, hashY, hashZoom] = hash.split('/') @@ -691,7 +688,7 @@ function updateViewFromHash() { targetPeriod = defaultPeriod targetVariation = defaultVariation } - updateTime(targetPeriod, targetVariation, true) + await updateTime(targetPeriod, targetVariation) setView( isNaN(hashX) ? scaleZoomOrigin[0] : Number(hashX), @@ -722,7 +719,6 @@ function updateViewFromHash() { objectsContainer.replaceChildren() objectsContainer.appendChild(infoElement) - renderBackground(atlas) setView( isNaN(hashX) ? entry.center[0] : Number(hashX), isNaN(hashY) ? entry.center[1] : Number(hashY), @@ -733,7 +729,8 @@ function updateViewFromHash() { entriesList.classList.add("disableHover") hovered = [{...entry, element: infoElement}] - renderHighlight() + renderBackground(atlasDisplay) + renderHighlight(atlasDisplay) updateLines() } From 128e8eabb99141fb1a922a1e594e3471c504fd55 Mon Sep 17 00:00:00 2001 From: Hans5958 Date: Thu, 27 Jul 2023 17:50:59 +0700 Subject: [PATCH 08/16] Refactoring --- web/_js/main/main.js | 10 +++++----- web/_js/main/overlap.js | 2 +- web/_js/main/view.js | 36 ++++++++++++++++++------------------ 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/web/_js/main/main.js b/web/_js/main/main.js index febffdacd..7d759eb28 100644 --- a/web/_js/main/main.js +++ b/web/_js/main/main.js @@ -236,7 +236,7 @@ async function init() { zoom = 1 zoomOrigin = [0, 0] scaleZoomOrigin = [0, 0] - updateLines() + renderLines() applyView() }) @@ -365,7 +365,7 @@ async function init() { } window.addEventListener("mousemove", e => { - // updateLines() + // renderLines() mousemove(e.clientX, e.clientY) if (dragging) { e.preventDefault() @@ -398,7 +398,7 @@ async function init() { scaleZoomOrigin[0] += deltaX / zoom scaleZoomOrigin[1] += deltaY / zoom - updateLines() + renderLines() applyView() } @@ -441,7 +441,7 @@ async function init() { zoomOrigin[1] = scaleZoomOrigin[1] * zoom applyView() - updateLines() + renderLines() } window.addEventListener("mouseup", e => { @@ -467,7 +467,7 @@ async function init() { function touchend(e) { if (e.touches.length === 0) { mouseup() - setTimeout(() => updateLines(), 0) + renderLines() dragging = false } else if (e.touches.length === 1) { diff --git a/web/_js/main/overlap.js b/web/_js/main/overlap.js index a20941ec8..c53ae5817 100644 --- a/web/_js/main/overlap.js +++ b/web/_js/main/overlap.js @@ -18,7 +18,7 @@ function initOverlap() { }) applyView() - updateLines() + renderLines() if (window.location.hash) { updateViewFromHash() diff --git a/web/_js/main/view.js b/web/_js/main/view.js index 9a69a9619..0bea20bd1 100644 --- a/web/_js/main/view.js +++ b/web/_js/main/view.js @@ -117,7 +117,7 @@ offcanvasList.addEventListener('shown.bs.offcanvas', e => { updateHovering(e) applyView() renderHighlight() - updateLines() + renderLines() }) offcanvasList.addEventListener('hide.bs.offcanvas', () => { @@ -132,7 +132,7 @@ offcanvasList.addEventListener('hidden.bs.offcanvas', e => { updateHovering(e) applyView() renderHighlight() - updateLines() + renderLines() }) closeObjectsListButton.addEventListener("click", clearObjectsList) @@ -142,17 +142,17 @@ bottomBar.addEventListener("mouseover", () => { }) function clearObjectsList() { + renderLines() + renderHighlight() + hovered = [] + fixed = false + document.title = pageTitle closeObjectsListButton.classList.add("d-none") objectsListOverflowNotice.classList.add("d-none") entriesList.classList.remove("disableHover") - hovered = [] objectsContainer.replaceChildren() - updateLines() - fixed = false - renderHighlight() objectEditNav.remove() updateHash(false) - document.title = pageTitle } function toggleFixed(e, tapped) { @@ -169,24 +169,24 @@ function toggleFixed(e, tapped) { objectsListOverflowNotice.classList.add("d-none") } -window.addEventListener("resize", updateLines) -window.addEventListener("mousemove", updateLines) -window.addEventListener("dblClick", updateLines) -window.addEventListener("wheel", updateLines) +window.addEventListener("resize", renderLines) +window.addEventListener("mousemove", renderLines) +window.addEventListener("dblClick", renderLines) +window.addEventListener("wheel", renderLines) objectsContainer.addEventListener("scroll", () => { - updateLines() + renderLines() }) window.addEventListener("resize", () => { applyView() renderHighlight() - updateLines() + renderLines() }) -function updateLines() { +async function renderLines() { // Line border linesCanvas.width = linesCanvas.clientWidth @@ -426,7 +426,7 @@ function buildObjectsList() { hovered = [entry] renderHighlight() hovered[0].element = this - updateLines() + renderLines() }) @@ -447,7 +447,7 @@ function buildObjectsList() { applyView() hovered = [] - updateLines() + renderLines() renderHighlight() }) } else { @@ -731,7 +731,7 @@ async function updateViewFromHash() { hovered = [{...entry, element: infoElement}] renderBackground(atlasDisplay) renderHighlight(atlasDisplay) - updateLines() + renderLines() } function calculateZoomFromPath(path) { @@ -772,7 +772,7 @@ function initView() { }*/ applyView() - updateLines() + renderLines() } From 02aac8d1c3625c686c668ec5f5faebb429472e47 Mon Sep 17 00:00:00 2001 From: Hans5958 Date: Thu, 27 Jul 2023 22:18:17 +0700 Subject: [PATCH 09/16] Readd marking of removed entries --- web/_js/main/main.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/web/_js/main/main.js b/web/_js/main/main.js index 7d759eb28..e2c8321db 100644 --- a/web/_js/main/main.js +++ b/web/_js/main/main.js @@ -149,19 +149,27 @@ async function init() { try { const liveAtlasRef = params.get('liveatlas') || `https://${prodDomain}/atlas.json` const liveAtlasResp = await fetch(liveAtlasRef) - let liveAtlas = await liveAtlasResp.json() - liveAtlas = generateAtlasAll(liveAtlas) + let liveAtlasAll = await liveAtlasResp.json() + liveAtlasAll = generateAtlasAll(liveAtlasAll) // Mark added/edited entries for (const entry of Object.values(atlasAll)) { - if (!liveAtlas[entry.id]) { + if (!liveAtlasAll[entry.id]) { entry.diff = "add" } else { - if (JSON.stringify({ ...entry, _index: undefined }) === JSON.stringify({ ...liveAtlas[entry.id], _index: undefined })) continue + if (JSON.stringify({ ...entry, _index: undefined }) === JSON.stringify({ ...liveAtlasAll[entry.id], _index: undefined })) continue entry.diff = "edit" } } + // Mark removed entries + for (const entry of Object.values(liveAtlasAll)) { + if (!atlasAll[entry.id]) { + entry.diff = "delete" + atlasAll[entry.id] = entry + } + } + if (mode.includes('only')) { for (const key of Object.keys(atlasAll)) { if (atlasAll[key].diff) continue From aa6c225afd6550adb5eb78fd9ac655e7b809d0d4 Mon Sep 17 00:00:00 2001 From: Hans5958 Date: Thu, 27 Jul 2023 22:21:19 +0700 Subject: [PATCH 10/16] Refactoring --- web/_js/main/main.js | 9 +++------ web/_js/main/view.js | 42 ++++++++++++------------------------------ 2 files changed, 15 insertions(+), 36 deletions(-) diff --git a/web/_js/main/main.js b/web/_js/main/main.js index e2c8321db..007477531 100644 --- a/web/_js/main/main.js +++ b/web/_js/main/main.js @@ -105,8 +105,7 @@ async function init() { // For Reviewing Reddit Changes // const atlasRef = '../tools/temp-atlas.json' const atlasAllUrl = params.get('atlas') || './atlas.json' - const atlasAllResp = await fetch(atlasAllUrl) - atlasAll = generateAtlasAll(await atlasAllResp.json()) + atlasAll = generateAtlasAll(await (await fetch(atlasAllUrl)).json()) // console.log(atlas, atlasOrder) const hash = window.location.hash.substring(1) @@ -147,10 +146,8 @@ async function init() { initExplore() } else if (mode.startsWith("diff")) { try { - const liveAtlasRef = params.get('liveatlas') || `https://${prodDomain}/atlas.json` - const liveAtlasResp = await fetch(liveAtlasRef) - let liveAtlasAll = await liveAtlasResp.json() - liveAtlasAll = generateAtlasAll(liveAtlasAll) + const liveAtlasUrl = params.get('liveatlas') || `https://${prodDomain}/atlas.json` + let liveAtlasAll = generateAtlasAll(await (await fetch(liveAtlasUrl)).json()) // Mark added/edited entries for (const entry of Object.values(atlasAll)) { diff --git a/web/_js/main/view.js b/web/_js/main/view.js index 0bea20bd1..dabfa1716 100644 --- a/web/_js/main/view.js +++ b/web/_js/main/view.js @@ -158,7 +158,7 @@ function clearObjectsList() { function toggleFixed(e, tapped) { if (!fixed && hovered.length === 0) { entriesList.classList.remove("disableHover") - return 0 + return } fixed = !fixed if (!fixed) { @@ -393,9 +393,10 @@ function updateAtlas() { renderHighlight(atlasDisplay) } -function buildObjectsList() { - - let i = 0 +async function resetEntriesList() { + entriesOffset = 0 + entriesList.replaceChildren() + entriesList.appendChild(moreEntriesButton) moreEntriesButton.removeEventListener('click', showMoreEntries) showMoreEntries = () => { @@ -407,12 +408,12 @@ function buildObjectsList() { let entriesLeft = entriesLimit let element - while (entriesLeft > 0 && atlasOrder.length > i) { + while (entriesLeft > 0 && atlasOrder.length > entriesOffset) { - if (atlasDisplay[atlasOrder[i]]) { + if (atlasDisplay[atlasOrder[entriesOffset]]) { // console.log(i, entriesLeft) - let entry = atlasDisplay[atlasOrder[i]] + let entry = atlasDisplay[atlasOrder[entriesOffset]] element = createInfoBlock(entry) element.addEventListener("mouseenter", function () { @@ -451,7 +452,7 @@ function buildObjectsList() { renderHighlight() }) } else { - let entry = atlas[atlasOrder[i]] + let entry = atlas[atlasOrder[entriesOffset]] element = createInfoBlock(entry, 2) element.addEventListener("click", async e => { @@ -472,40 +473,21 @@ function buildObjectsList() { }) } - i += 1 + entriesOffset += 1 entriesLeft -= 1 entriesList.appendChild(element) } - if (atlasOrder.length > i) { - moreEntriesButton.innerHTML = "Show " + Math.min(entriesLimit, atlasOrder.length - i) + " more" + if (atlasOrder.length > entriesOffset) { + moreEntriesButton.innerHTML = "Show " + Math.min(entriesLimit, atlasOrder.length - entriesOffset) + " more" entriesList.appendChild(moreEntriesButton) } } moreEntriesButton.addEventListener('click', showMoreEntries) showMoreEntries() - -} - -function shuffle() { - //console.log("shuffled atlas") - for (let i = atlasDisplay.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)) - const temp = atlasDisplay[i] - atlasDisplay[i] = atlasDisplay[j] - atlasDisplay[j] = temp - } -} - -async function resetEntriesList() { - entriesOffset = 0 - entriesList.replaceChildren() - entriesList.appendChild(moreEntriesButton) - - buildObjectsList() } async function renderHighlight() { From b14b9ab2ebc8a4fc7131ade26b18d41039ba06fc Mon Sep 17 00:00:00 2001 From: Hans5958 Date: Thu, 27 Jul 2023 23:09:04 +0700 Subject: [PATCH 11/16] Refactoring again --- web/_js/main/draw.js | 8 ++++---- web/_js/main/infoblock.js | 27 +++++++++++++-------------- web/_js/main/time.js | 15 +++++++-------- web/_js/main/view.js | 6 +++--- 4 files changed, 27 insertions(+), 29 deletions(-) diff --git a/web/_js/main/draw.js b/web/_js/main/draw.js index 7952cedad..7610633c3 100644 --- a/web/_js/main/draw.js +++ b/web/_js/main/draw.js @@ -390,7 +390,7 @@ function initDraw() { } function preview() { - let infoElement = createInfoBlock(generateExportObject(), 1) + let infoElement = createInfoBlock(generateExportObject(), 2) objectsContainer.replaceChildren() objectsContainer.appendChild(infoElement) closeObjectsListButton.classList.remove("d-none") @@ -788,7 +788,7 @@ function initDraw() { } else { document.getElementById("offcanvasDrawLabel").textContent = "New Entry" - pathWithPeriods.push([formatPeriod(currentPeriod, currentPeriod, currentVariation), []]) + pathWithPeriods.push([formatPeriod(currentPeriod, null, currentVariation), []]) // Builds multi-input list addWebsiteFields("", 0, [0]) @@ -814,14 +814,14 @@ function initDraw() { }) periodsAdd.addEventListener('click', () => { - pathWithPeriods.push([formatPeriod(currentPeriod, currentPeriod, currentVariation), []]) + pathWithPeriods.push([formatPeriod(currentPeriod, null, currentVariation), []]) initPeriodGroups() }) drawBackButton.href = "./" + formatHash(entry?.id) document.addEventListener('timeupdate', event => { - drawBackButton.href = "./" + formatHash(entry?.id, event.detail.period, event.detail.period, event.detail.variation) + drawBackButton.href = "./" + formatHash(entry?.id, event.detail.period, event.detail.variation) }) } diff --git a/web/_js/main/infoblock.js b/web/_js/main/infoblock.js index 0e74f8880..b3daf8d97 100644 --- a/web/_js/main/infoblock.js +++ b/web/_js/main/infoblock.js @@ -32,8 +32,8 @@ function createInfoListItem(name, value) { } // mode 0 = normal -// mode 1 = preview -// mode 2 = entry list but none on atlas +// mode 1 = entry list but none on atlas +// mode 2 = preview function createInfoBlock(entry, mode = 0) { const element = document.createElement("div") element.className = "card mb-2 overflow-hidden shadow" @@ -43,22 +43,21 @@ function createInfoBlock(entry, mode = 0) { const linkElement = document.createElement("a") linkElement.className = "text-decoration-none d-flex justify-content-between text-body" - if (mode === 1) linkElement.href = "#" - - else if (mode === 2) { - const [nearestPeriod, nearestVariation, nearestKey] = getNearestPeriod(entry, currentPeriod, currentVariation) - const hash = formatHash(entry.id, nearestPeriod, nearestPeriod, nearestVariation, false, false, false) - linkElement.href = hash - - } else { - const hash = formatHash(entry.id, null, null, null, false, false, false) + + const [nearestPeriod, nearestVariation] = getNearestPeriod(entry, currentPeriod, currentVariation) + + if (mode === 2) { + linkElement.href = "#" + } else { + const hash = formatHash(entry.id, nearestPeriod, nearestVariation, false, false, false) linkElement.href = hash - linkElement.addEventListener('click', e => { + if (mode === 0) linkElement.addEventListener('click', e => { e.preventDefault() location.hash = hash window.dispatchEvent(new HashChangeEvent("hashchange")) }) } + const linkNameElement = document.createElement("span") linkNameElement.className = "flex-grow-1 text-break" linkNameElement.textContent = entry.name @@ -180,11 +179,11 @@ function createInfoBlock(entry, mode = 0) { element.appendChild(idElementContainer) // Adds edit button only if element is not deleted - if (mode === 0 && (!entry.diff || entry.diff !== "delete")) { + if (mode < 2 && (!entry.diff || entry.diff !== "delete")) { const editElement = document.createElement("a") editElement.innerHTML = ' Edit' editElement.className = "btn btn-sm btn-outline-primary" - editElement.href = "./?mode=draw&id=" + entry.id + formatHash(false, null, null, null, false, false, false) + editElement.href = "./?mode=draw&id=" + entry.id + formatHash(false, nearestPeriod, nearestVariation, false, false, false) editElement.title = "Edit " + entry.name idElementContainer.appendChild(editElement) } diff --git a/web/_js/main/time.js b/web/_js/main/time.js index 6f31cb661..cc0fd09fb 100644 --- a/web/_js/main/time.js +++ b/web/_js/main/time.js @@ -73,7 +73,7 @@ const dispatchTimeUpdateEvent = (period = currentPeriod, variation = currentVari detail: { period: period, variation: variation, - periodString: formatPeriod(period, period, variation), + periodString: formatPeriod(period, null, variation), atlas: atlas } }) @@ -278,13 +278,13 @@ function parsePeriod(periodString) { function formatPeriod(targetStart, targetEnd, targetVariation, forUrl = false) { targetStart ??= currentPeriod - targetEnd ??= currentPeriod + targetEnd ??= undefined targetVariation ??= currentVariation let periodString, variationString variationString = variationsConfig[targetVariation].code if (targetStart > targetEnd) [targetStart, targetEnd] = [targetEnd, targetStart] - if (targetStart === targetEnd) { + if (targetStart === targetEnd || (targetStart && !targetEnd)) { if (forUrl && targetVariation === defaultVariation && targetStart === variationsConfig[defaultVariation].default) { periodString = "" } @@ -302,12 +302,11 @@ function setReferenceVal(reference, newValue) { else return reference ?? newValue } -function formatHash(targetEntry, targetPeriodStart, targetPeriodEnd, targetVariation, targetX, targetY, targetZoom) { +function formatHash(targetEntry, targetPeriod, targetVariation, targetX, targetY, targetZoom) { let hashData = window.location.hash.substring(1).split('/') targetEntry = setReferenceVal(targetEntry, hashData[0]) - targetPeriodStart = setReferenceVal(targetPeriodStart, currentPeriod) - targetPeriodEnd = setReferenceVal(targetPeriodEnd, currentPeriod) + targetPeriod = setReferenceVal(targetPeriod, currentPeriod) targetVariation = setReferenceVal(targetVariation, currentVariation) targetX = setReferenceVal(targetX, -scaleZoomOrigin[0]) targetY = setReferenceVal(targetY, -scaleZoomOrigin[1]) @@ -318,8 +317,8 @@ function formatHash(targetEntry, targetPeriodStart, targetPeriodEnd, targetVaria if (targetZoom) targetZoom = targetZoom.toFixed(3).replace(/\.?0+$/, '') const result = [targetEntry] - const targetPeriod = formatPeriod(targetPeriodStart, targetPeriodEnd, targetVariation, true) - result.push(targetPeriod, targetX, targetY, targetZoom) + const targetPeriodFormat = formatPeriod(targetPeriod, null, targetVariation, true) + result.push(targetPeriodFormat, targetX, targetY, targetZoom) if (!result.some(el => el || el === 0)) return '' return '#' + result.join('/').replace(/\/+$/, '') } diff --git a/web/_js/main/view.js b/web/_js/main/view.js index dabfa1716..14b4e2d66 100644 --- a/web/_js/main/view.js +++ b/web/_js/main/view.js @@ -453,7 +453,7 @@ async function resetEntriesList() { }) } else { let entry = atlas[atlasOrder[entriesOffset]] - element = createInfoBlock(entry, 2) + element = createInfoBlock(entry, 1) element.addEventListener("click", async e => { e.preventDefault() @@ -468,7 +468,7 @@ async function resetEntriesList() { previousScaleZoomOrigin = undefined previousZoom = undefined - const hash = formatHash(entry.id, nearestPeriod, nearestPeriod, nearestVariation, entry.center[0], entry.center[1], calculateZoomFromPath(entry.path)) + const hash = formatHash(entry.id, nearestPeriod, nearestVariation, entry.center[0], entry.center[1], calculateZoomFromPath(entry.path)) location.hash = hash }) } @@ -831,6 +831,6 @@ function initViewGlobal() { } document.addEventListener('timeupdate', event => { - drawButton.href = "./?mode=draw" + formatHash(null, event.detail.period, event.detail.period, event.detail.variation) + drawButton.href = "./?mode=draw" + formatHash(null, event.detail.period, event.detail.variation) }) } From 737aac490cc0647d24f9fe5f748eae41b1a6365e Mon Sep 17 00:00:00 2001 From: Julian Haslinger Date: Thu, 27 Jul 2023 22:56:10 +0200 Subject: [PATCH 12/16] feat: optimized canvas rerender for better performance --- web/_js/main/main.js | 9 ++++----- web/_js/main/view.js | 18 +++++++++++------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/web/_js/main/main.js b/web/_js/main/main.js index 7191d1aeb..84e00e277 100644 --- a/web/_js/main/main.js +++ b/web/_js/main/main.js @@ -59,7 +59,7 @@ function setView(targetX, targetY, targetZoom = zoom) { zoom = targetZoom scaleZoomOrigin = [ - canvasCenter.x - targetX, + canvasCenter.x - targetX, canvasCenter.y - targetY ] applyView() @@ -123,8 +123,8 @@ async function init() { //console.log(document.documentElement.clientWidth, document.documentElement.clientHeight) setView( - isNaN(hashX) ? 0 : Number(hashX), - isNaN(hashY) ? 0 : Number(hashY), + isNaN(hashX) ? 0 : Number(hashX), + isNaN(hashY) ? 0 : Number(hashY), isNaN(hashZoom) ? 1 : Number(hashZoom) ) @@ -384,7 +384,6 @@ async function init() { } window.addEventListener("mousemove", e => { - // updateLines() mousemove(e.clientX, e.clientY) if (dragging) { e.preventDefault() @@ -478,7 +477,7 @@ async function init() { }) window.addEventListener("touchend", touchend) - function mouseup(x, y) { + function mouseup() { dragging = false updateHash() } diff --git a/web/_js/main/view.js b/web/_js/main/view.js index 5c82c52ec..26a992189 100644 --- a/web/_js/main/view.js +++ b/web/_js/main/view.js @@ -166,7 +166,6 @@ function toggleFixed(e, tapped) { } window.addEventListener("resize", updateLines) -window.addEventListener("mousemove", updateLines) window.addEventListener("dblClick", updateLines) window.addEventListener("wheel", updateLines) @@ -175,7 +174,6 @@ objectsContainer.addEventListener("scroll", () => { }) window.addEventListener("resize", () => { - applyView() render() updateLines() @@ -183,7 +181,10 @@ window.addEventListener("resize", () => { }) function updateLines() { - + if (hovered.length === 0) { + linesContext.clearRect(0, 0, linesCanvas.width, linesCanvas.height) + return + } // Line border linesCanvas.width = linesCanvas.clientWidth linesCanvas.height = linesCanvas.clientHeight @@ -592,11 +593,15 @@ function updateHovering(e, tapped) { if (!(pos[0] <= canvasSize.x + canvasOffset.x + 200 && pos[0] >= canvasOffset.x - 200 && pos[1] <= canvasSize.y + canvasOffset.y + 200 && pos[1] >= canvasOffset.x - 200)) return - const newHovered = [] + let newHovered = [] for (const entry of atlasDisplay) { if (pointIsInPolygon(pos, entry.path)) newHovered.push(entry) } + newHovered = newHovered.sort(function (a, b) { + return calcPolygonArea(a.path) - calcPolygonArea(b.path) + }) + let changed = false if (hovered.length === newHovered.length) { @@ -612,9 +617,7 @@ function updateHovering(e, tapped) { if (!changed) return - hovered = newHovered.sort(function (a, b) { - return calcPolygonArea(a.path) - calcPolygonArea(b.path) - }) + hovered = newHovered objectsContainer.replaceChildren() @@ -639,6 +642,7 @@ function updateHovering(e, tapped) { objectsListOverflowNotice.classList.add("d-none") entriesList.classList.remove("disableHover") } + updateLines() render() } From e5aa91fa564c4a1678d1280c6839edc1db026d95 Mon Sep 17 00:00:00 2001 From: Julian Haslinger Date: Fri, 28 Jul 2023 01:20:21 +0200 Subject: [PATCH 13/16] fix: render lines call while updateHovering --- web/_js/main/view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/_js/main/view.js b/web/_js/main/view.js index bcf3c881c..47771a437 100644 --- a/web/_js/main/view.js +++ b/web/_js/main/view.js @@ -646,7 +646,7 @@ function updateHovering(e, tapped) { objectsListOverflowNotice.classList.add("d-none") entriesList.classList.remove("disableHover") } - updateLines() + renderLines() renderHighlight() } From 4c24a41bfe091304ab7eda5f8ad61ae52d29655e Mon Sep 17 00:00:00 2001 From: Hans5958 Date: Fri, 28 Jul 2023 12:21:21 +0700 Subject: [PATCH 14/16] Remove redundant event listener It has been covered in literally the next lines --- web/_js/main/view.js | 1 - 1 file changed, 1 deletion(-) diff --git a/web/_js/main/view.js b/web/_js/main/view.js index 47771a437..d4e166238 100644 --- a/web/_js/main/view.js +++ b/web/_js/main/view.js @@ -169,7 +169,6 @@ function toggleFixed(e, tapped) { objectsListOverflowNotice.classList.add("d-none") } -window.addEventListener("resize", renderLines) window.addEventListener("dblClick", renderLines) window.addEventListener("wheel", renderLines) From dbdad722e1a8a90437e832c01d3596aa046a8663 Mon Sep 17 00:00:00 2001 From: Hans5958 Date: Wed, 2 Aug 2023 14:30:34 +0700 Subject: [PATCH 15/16] Fix error on formatPeriod and getNearestPeriod --- web/_js/main/time.js | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/web/_js/main/time.js b/web/_js/main/time.js index f056931b0..d4f12ed23 100644 --- a/web/_js/main/time.js +++ b/web/_js/main/time.js @@ -310,13 +310,13 @@ function parsePeriod(periodString) { function formatPeriod(targetStart, targetEnd, targetVariation, forUrl = false) { targetStart ??= currentPeriod - targetEnd ??= undefined + targetEnd ??= targetStart targetVariation ??= currentVariation let periodString, variationString variationString = variationsConfig[targetVariation].code if (targetStart > targetEnd) [targetStart, targetEnd] = [targetEnd, targetStart] - if (targetStart === targetEnd || (targetStart && !targetEnd)) { + if (targetStart === targetEnd) { if (forUrl && targetVariation === defaultVariation && targetStart === variationsConfig[defaultVariation].default) { periodString = "" } @@ -379,24 +379,21 @@ function getNearestPeriod(entry, targetPeriod, targetVariation) { nearestKey = newKey } - checkEntryPathPeriod: for (const pathKey of pathKeys) { + checkPaths: for (const pathKey of pathKeys) { const pathPeriods = pathKey.split(', ') - for (const j in pathPeriods) { + checkPathPeriod: for (const j in pathPeriods) { const [pathStart, pathEnd, pathVariation] = parsePeriod(pathPeriods[j]) if (isOnPeriod(pathStart, pathEnd, pathVariation, targetPeriod, targetVariation)) { updateNearest(0, targetPeriod, targetVariation) + break checkPaths + } else if (pathVariation !== targetVariation) { + updateNearest(Infinity, pathStart, pathVariation, pathKey) + continue checkPathPeriod + } else if (Math.abs(pathStart - targetPeriod) < Math.abs(pathEnd - targetPeriod)) { + updateNearest(Math.abs(pathStart - targetPeriod), pathStart, pathVariation, pathKey) } else { - if (pathVariation !== targetVariation) { - updateNearest(Infinity, pathStart, pathVariation, pathKey) - break checkEntryPathPeriod - } else { - if (Math.abs(pathStart - targetPeriod) < Math.abs(pathEnd - targetPeriod)) { - updateNearest(Math.abs(pathStart - targetPeriod), pathStart, pathVariation, pathKey) - } else { - updateNearest(Math.abs(pathEnd - targetPeriod), pathStart, pathVariation, pathKey) - } - } + updateNearest(Math.abs(pathEnd - targetPeriod), pathStart, pathVariation, pathKey) } } From 571adb10c2a542a31b5ca8f57b43bc683299c8ca Mon Sep 17 00:00:00 2001 From: Hans5958 Date: Wed, 2 Aug 2023 14:31:01 +0700 Subject: [PATCH 16/16] Fix wrong link on displayed atlas entry --- web/_js/main/infoblock.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/web/_js/main/infoblock.js b/web/_js/main/infoblock.js index b3daf8d97..496069621 100644 --- a/web/_js/main/infoblock.js +++ b/web/_js/main/infoblock.js @@ -44,7 +44,11 @@ function createInfoBlock(entry, mode = 0) { const linkElement = document.createElement("a") linkElement.className = "text-decoration-none d-flex justify-content-between text-body" - const [nearestPeriod, nearestVariation] = getNearestPeriod(entry, currentPeriod, currentVariation) + let nearestPeriod = currentPeriod + let nearestVariation = currentVariation + if (!atlasDisplay[entry.id]) { + [nearestPeriod, nearestVariation] = getNearestPeriod(entry, currentPeriod, currentVariation) + } if (mode === 2) { linkElement.href = "#"