|
|
|
|
|
|
|
|
|
|
|
var timer; |
|
var artTypes = ['🎨','🧑','🏞️']; |
|
var imgTypeShown = 0; |
|
var log = ''; |
|
var editMostUsedMode = false; |
|
var windowWidth = 0; |
|
var gutterStartPosX, mouseStartPosX, gutterEndPercentX |
|
var style, stylesheet, imgHoverRule; |
|
var tagsConcatenated = new Set(); |
|
var editedArtists = new Set(); |
|
|
|
|
|
|
|
|
|
function startUp() { |
|
updateTagsConcatenated(); |
|
updateFooter(); |
|
loadEditedArtists(); |
|
insertArtists(); |
|
insertCheckboxesFromArtistsData(); |
|
insertCheckboxesFromCategories(); |
|
loadCheckboxesState(); |
|
showHideCategories(); |
|
loadOptionsState(); |
|
loadFavoritesState(); |
|
hideAllArtists(); |
|
unhideBasedOnPermissiveSetting(); |
|
updateArtistsCountPerTag('start'); |
|
rotatePromptsImages(); |
|
sortArtists(); |
|
sortTags(); |
|
loadMostUsedTags(); |
|
updateArtistsCountPerCategory(); |
|
showHideLowCountTags(); |
|
getStyleRuleForDrag(); |
|
} |
|
|
|
function updateTagsConcatenated() { |
|
|
|
for (var i=0, il=tagCategories.length; i<il; i++) { |
|
for (var j=1, jl=tagCategories[i].length; j<jl; j++) { |
|
|
|
|
|
let tag = tagCategories[i][j].replace(/, added-(\d|-)*/g,''); |
|
tagsConcatenated.add(tag); |
|
} |
|
} |
|
let tagsConcatenatedArray = Array.from(tagsConcatenated).sort(function (a, b) { |
|
return a.toLowerCase().localeCompare(b.toLowerCase()); |
|
}); |
|
tagsConcatenated = new Set(tagsConcatenatedArray); |
|
} |
|
|
|
function updateFooter() { |
|
let proto = window.location.protocol; |
|
if (proto.startsWith('http')) { |
|
var footer = document.getElementsByTagName('footer')[0]; |
|
var el1 = document.createElement('span'); |
|
el1.textContent = ''; |
|
|
|
|
|
} |
|
} |
|
|
|
function loadEditedArtists() { |
|
const arr = JSON.parse(localStorage.getItem('editedArtists')) || []; |
|
editedArtists = new Set(arr); |
|
let proto = window.location.protocol; |
|
let anyChanges = false; |
|
for (let i=0, il=artistsData.length; i<il; i++) { |
|
|
|
let artist = artistsData[i]; |
|
let artistFound = Array.from(editedArtists).find(editedA => editedA[0] === artist[0] && editedA[1] === artist[1]); |
|
if(artistFound) { |
|
|
|
let match = true; |
|
for (let j=0, jl=artist.length; j<jl; j++) { |
|
if (artist[j] !== artistFound[j]) { |
|
match = false; |
|
} |
|
} |
|
if(match) { |
|
anyChanges = true; |
|
editedArtists.delete(artistFound); |
|
} else { |
|
if (!proto.startsWith('http')) { |
|
|
|
artistsData[i] = artistFound; |
|
} |
|
} |
|
} |
|
} |
|
if(anyChanges) { |
|
localStorage.setItem('editedArtists', JSON.stringify(Array.from(editedArtists))); |
|
} |
|
} |
|
|
|
function insertArtists() { |
|
|
|
let missingFiles = ''; |
|
var container = document.getElementById('image-container'); |
|
let imagePromises = artistsData.map((artist) => { |
|
var last = artist[0]; |
|
var first = artist[1]; |
|
var tags1 = artist[2].replaceAll('|', ' ').toLowerCase(); |
|
var tags2 = artist[2].replaceAll('|', ', '); |
|
|
|
|
|
tags1 = tags1.replace(/(^|\s)(\d)/g, '$1qqqq-$2'); |
|
|
|
|
|
tags2 = tags2.replace(/, added-(\d|-)*/g,''); |
|
var itemDiv = document.createElement('div'); |
|
itemDiv.className = 'image-item ' + tags1; |
|
if(artist[3]) { |
|
itemDiv.dataset.deprecated = true; |
|
} |
|
var itemHeader = document.createElement('span'); |
|
var h3 = document.createElement('h3'); |
|
itemHeader.appendChild(h3); |
|
var firstN = document.createElement('span'); |
|
var lastN = document.createElement('span'); |
|
firstN.className = 'firstN'; |
|
lastN.className = 'lastN'; |
|
firstN.textContent = `${first}`; |
|
lastN.textContent = `${last}`; |
|
h3.appendChild(firstN); |
|
h3.appendChild(lastN); |
|
h3.title = 'copy to clipboard'; |
|
var h4 = document.createElement('h4'); |
|
h4.textContent = tags2; |
|
h4.title = 'copy to clipboard'; |
|
itemHeader.appendChild(h4); |
|
itemDiv.appendChild(itemHeader); |
|
var box = document.createElement('div'); |
|
var imgTools = document.createElement('div'); |
|
imgTools.className = 'imgTools'; |
|
var artPrev = document.createElement('div'); |
|
artPrev.className = 'art_prev'; |
|
var artPrevSpan = document.createElement('span'); |
|
artPrevSpan.textContent = '🧑'; |
|
artPrev.appendChild(artPrevSpan); |
|
imgTools.appendChild(artPrev); |
|
var artStar = document.createElement('div'); |
|
artStar.className = 'art_star'; |
|
var artStarSpan = document.createElement('span'); |
|
artStarSpan.textContent = '⭐️'; |
|
artStar.appendChild(artStarSpan); |
|
imgTools.appendChild(artStar); |
|
var artNext = document.createElement('div'); |
|
artNext.className = 'art_next'; |
|
var artNextSpan = document.createElement('span'); |
|
artNextSpan.textContent = '🏞️'; |
|
artNext.appendChild(artNextSpan); |
|
imgTools.appendChild(artNext); |
|
var artEdit = document.createElement('div'); |
|
artEdit.className = 'art_edit'; |
|
var artEditSpan = document.createElement('span'); |
|
artEditSpan.textContent = '✍️'; |
|
artEdit.appendChild(artEditSpan); |
|
imgTools.appendChild(artEdit); |
|
box.appendChild(imgTools); |
|
var imgBox = document.createElement('div'); |
|
imgBox.className = 'imgBox'; |
|
var imgArtwork = document.createElement('img'); |
|
var imgPortrait = document.createElement('img'); |
|
var imgLandscape = document.createElement('img'); |
|
imgArtwork.alt = `${first} ${last}` + ' - artwork'; |
|
imgPortrait.alt = `${first} ${last}` + ' - portrait'; |
|
imgLandscape.alt = `${first} ${last}` + ' - landscape'; |
|
imgArtwork.className = 'img_artwork'; |
|
imgPortrait.className = 'img_portrait hidden'; |
|
imgLandscape.className = 'img_landscape hidden'; |
|
let src = 'images/SDXL_1_0_thumbs/'; |
|
if(first == '') { |
|
src += last.replaceAll(' ', '_'); |
|
} else { |
|
src += first.replaceAll(' ', '_') + '_' + last.replaceAll(' ', '_'); |
|
} |
|
|
|
src = encodeURI(src.normalize("NFD")); |
|
imgBox.appendChild(imgArtwork); |
|
imgBox.appendChild(imgPortrait); |
|
imgBox.appendChild(imgLandscape); |
|
box.appendChild(imgBox); |
|
itemDiv.appendChild(box); |
|
container.appendChild(itemDiv); |
|
if(artist[3]) { |
|
var deprecatedSpan = document.createElement('span'); |
|
deprecatedSpan.textContent = 'this artist is unknown to SDXL - more info in the help ⁉️' |
|
deprecatedSpan.className = 'deprecated'; |
|
imgBox.appendChild(deprecatedSpan); |
|
return Promise.allSettled([ |
|
new Promise((resolve, reject) => { |
|
imgArtwork.style.display = 'none'; |
|
imgArtwork.src = 'images/SDXL_1_0_thumbs/1x1.webp'; |
|
}), |
|
new Promise((resolve, reject) => { |
|
imgPortrait.style.display = 'none'; |
|
imgPortrait.src = 'images/SDXL_1_0_thumbs/1x1.webp'; |
|
}), |
|
new Promise((resolve, reject) => { |
|
imgLandscape.style.display = 'none'; |
|
imgLandscape.src = 'images/SDXL_1_0_thumbs/1x1.webp'; |
|
}) |
|
]); |
|
} else { |
|
|
|
return Promise.allSettled([ |
|
new Promise((resolve, reject) => { |
|
imgArtwork.onload = resolve; |
|
imgArtwork.onerror = () => { |
|
missingFiles += '<li>' + first + '_' + last + '-artwork.webp</li>'; |
|
reject(); |
|
}; |
|
imgArtwork.src = src + '-artwork.webp'; |
|
}), |
|
new Promise((resolve, reject) => { |
|
imgPortrait.onload = resolve; |
|
imgPortrait.onerror = () => { |
|
missingFiles += '<li>' + first + '_' + last + '-portrait.webp</li>'; |
|
reject(); |
|
}; |
|
imgPortrait.src = src + '-portrait.webp'; |
|
}), |
|
new Promise((resolve, reject) => { |
|
imgLandscape.onload = resolve; |
|
imgLandscape.onerror = () => { |
|
missingFiles += '<li>' + first + '_' + last + '-landscape.webp</li>'; |
|
reject(); |
|
}; |
|
imgLandscape.src = src + '-landscape.webp'; |
|
}) |
|
]); |
|
} |
|
}); |
|
let report = document.getElementById('missing_images_report'); |
|
Promise.allSettled(imagePromises).then(() => { |
|
if(missingFiles.indexOf('webp')>0) { |
|
report.innerHTML = missingFiles; |
|
} else { |
|
report.innerHTML = '<li>No thumbnails files are missing! Enlarged images are loaded on hover. If any are missing, they\'ll be listed here at that time.</li>' |
|
} |
|
}); |
|
} |
|
|
|
function insertCheckboxesFromArtistsData() { |
|
var uniqueTags = new Set(); |
|
artistsData.forEach(function(artist) { |
|
var tags = artist[2].split('|'); |
|
tags.forEach(function(tag) { |
|
uniqueTags.add(tag.toLowerCase()); |
|
}); |
|
}); |
|
var uTags = Array.from(uniqueTags); |
|
var toggles = document.getElementById('toggles'); |
|
for(i=0,il=uTags.length;i<il;i++) { |
|
if(uTags[i].length > 0) { |
|
|
|
var label = document.createElement('label'); |
|
var el = document.createElement('i'); |
|
el.className = 'most_used_indicator'; |
|
el.textContent = '+'; |
|
var input = document.createElement('input'); |
|
input.type = 'checkbox'; |
|
input.name = uTags[i]; |
|
input.value = uTags[i]; |
|
input.checked = true; |
|
var span1 = document.createElement('span'); |
|
span1.textContent = uTags[i]; |
|
var span2 = document.createElement('span'); |
|
span2.className = 'count'; |
|
label.appendChild(el); |
|
label.appendChild(input); |
|
label.appendChild(span1); |
|
label.appendChild(span2); |
|
toggles.appendChild(label); |
|
} |
|
} |
|
} |
|
|
|
function insertCheckboxesFromCategories() { |
|
var useCategories = document.querySelector('input[name="use_categories"]').checked; |
|
for(i=0,il=tagCategories.length;i<il;i++) { |
|
let name = tagCategories[i][0]; |
|
var label = document.createElement('label'); |
|
label.dataset.categoryName = name; |
|
label.className = 'category'; |
|
var input = document.createElement('input'); |
|
input.type = 'checkbox'; |
|
input.name = name; |
|
input.value = name; |
|
input.checked = true; |
|
var span1 = document.createElement('span'); |
|
span1.textContent = name; |
|
var span2 = document.createElement('span'); |
|
span2.className = 'count'; |
|
label.appendChild(input); |
|
label.appendChild(span1); |
|
label.appendChild(span2); |
|
toggles.appendChild(label); |
|
} |
|
} |
|
|
|
function loadCheckboxesState() { |
|
let state = JSON.parse(localStorage.getItem('tagsChecked')) || {}; |
|
let allChecked = true; |
|
for (let name in state) { |
|
if (document.querySelector('input[name="'+name+'"]')) { |
|
document.querySelector('input[name="'+name+'"]').checked = state[name]; |
|
if(name != 'mode' && name != 'use_categories') { |
|
if(!state[name]) { |
|
allChecked = false; |
|
} |
|
} |
|
} |
|
} |
|
if(!allChecked) { |
|
document.querySelector('input[name="check-all"]').checked = false; |
|
} |
|
} |
|
|
|
function storeCheckboxState(checkbox) { |
|
let state = JSON.parse(localStorage.getItem('tagsChecked')) || {}; |
|
state[checkbox.name] = checkbox.checked; |
|
localStorage.setItem('tagsChecked', JSON.stringify(state)); |
|
} |
|
|
|
function storeCheckboxStateAll(isChecked) { |
|
let state = {}; |
|
var checkboxes = document.querySelectorAll('input[type="checkbox"]'); |
|
checkboxes.forEach(function(checkbox) { |
|
let isTop = checkbox.parentNode.classList.contains('top_control'); |
|
if(!isTop || checkbox.name == 'favorite') { |
|
|
|
if(isChecked) { |
|
state[checkbox.name] = true; |
|
} else { |
|
state[checkbox.name] = false; |
|
} |
|
} |
|
}); |
|
localStorage.setItem('tagsChecked', JSON.stringify(state)); |
|
} |
|
|
|
function loadOptionsState() { |
|
let state = JSON.parse(localStorage.getItem('tagsChecked')) || {}; |
|
if(state['prompt']) { |
|
document.getElementById('options_prompts').querySelectorAll('.selected')[0].classList.remove('selected'); |
|
document.getElementById(state['prompt']).classList.add('selected'); |
|
if(state['prompt'] == 'promptA') { |
|
imgTypeShown = 0; |
|
} else if(state['prompt'] == 'promptP') { |
|
imgTypeShown = 1; |
|
} else if(state['prompt'] == 'promptL') { |
|
imgTypeShown = 2; |
|
} |
|
} else { |
|
|
|
imgTypeShown = 0; |
|
} |
|
if(state['artistSort']) { |
|
document.getElementById('options_artist_sort').querySelectorAll('.selected')[0].classList.remove('selected'); |
|
document.getElementById(state['artistSort']).classList.add('selected'); |
|
} else { |
|
|
|
} |
|
if(state['tagSort']) { |
|
document.getElementById('options_tag_sort').querySelectorAll('.selected')[0].classList.remove('selected'); |
|
document.getElementById(state['tagSort']).classList.add('selected'); |
|
} else { |
|
|
|
} |
|
} |
|
|
|
function highlightSelectedOption(selected) { |
|
if(selected == 'prev' || selected == 'next') { |
|
if(selected == 'prev') { |
|
imgTypeShown--; |
|
if(imgTypeShown < 0) { imgTypeShown = 2; } |
|
} else if(selected == 'next') { |
|
imgTypeShown++; |
|
if(imgTypeShown > 2) { imgTypeShown = 0; } |
|
} |
|
var links = document.getElementById('options_prompts').querySelectorAll('.link'); |
|
links.forEach(function(link) { |
|
link.classList.remove('selected'); |
|
}); |
|
if(imgTypeShown == 0) { |
|
document.getElementById('promptA').classList.add('selected'); |
|
doAlert('Showing artwork',0); |
|
} else if(imgTypeShown == 1) { |
|
document.getElementById('promptP').classList.add('selected'); |
|
doAlert('Showing portraits',0); |
|
} else if(imgTypeShown == 2) { |
|
document.getElementById('promptL').classList.add('selected'); |
|
doAlert('Showing landscapes',0); |
|
} |
|
} else { |
|
if(selected == 'promptA') { |
|
imgTypeShown = 0; |
|
doAlert('Showing artwork',0); |
|
} else if(selected == 'promptP') { |
|
imgTypeShown = 1; |
|
doAlert('Showing portraits',0); |
|
} else if(selected == 'promptL') { |
|
imgTypeShown = 2; |
|
doAlert('Showing landscapes',0); |
|
} |
|
var links = document.getElementById(selected).parentNode.querySelectorAll('.link'); |
|
links.forEach(function(link) { |
|
link.classList.remove('selected'); |
|
}); |
|
document.getElementById(selected).classList.add('selected'); |
|
} |
|
} |
|
|
|
function storeOptionsState() { |
|
let state = JSON.parse(localStorage.getItem('tagsChecked')) || {}; |
|
if(document.getElementById('promptA').classList.contains('selected')) { |
|
state['prompt'] = 'promptA'; |
|
} else if(document.getElementById('promptP').classList.contains('selected')) { |
|
state['prompt'] = 'promptP'; |
|
} else { |
|
state['prompt'] = 'promptL'; |
|
} |
|
if(document.getElementById('sortAR').classList.contains('selected')) { |
|
state['artistSort'] = 'sortAR'; |
|
} else { |
|
state['artistSort'] = 'sortAA'; |
|
} |
|
if(document.getElementById('sortTC').classList.contains('selected')) { |
|
state['tagSort'] = 'sortTC'; |
|
} else { |
|
state['tagSort'] = 'sortTA'; |
|
} |
|
localStorage.setItem('tagsChecked', JSON.stringify(state)); |
|
} |
|
|
|
function rotatePromptsImages() { |
|
|
|
let images = document.querySelectorAll('.imgBox img'); |
|
images.forEach(function(image) { |
|
image.classList.add('hidden'); |
|
}); |
|
|
|
if(imgTypeShown == 0) { |
|
images = document.querySelectorAll('.img_artwork'); |
|
} else if(imgTypeShown == 1) { |
|
images = document.querySelectorAll('.img_portrait'); |
|
} else if(imgTypeShown == 2) { |
|
images = document.querySelectorAll('.img_landscape'); |
|
} |
|
images.forEach(function(image) { |
|
image.classList.remove('hidden'); |
|
}); |
|
|
|
let artIndex = 0; |
|
artIndex = imgTypeShown-1; |
|
if(artIndex < 0) { artIndex = 2; } |
|
let prevButtons = document.querySelectorAll('.art_prev span'); |
|
prevButtons.forEach(function(span) { |
|
span.textContent = artTypes[artIndex]; |
|
}); |
|
artIndex = imgTypeShown+1; |
|
if(artIndex > 2) { artIndex = 0; } |
|
let nextButtons = document.querySelectorAll('.art_next span'); |
|
nextButtons.forEach(function(span) { |
|
span.textContent = artTypes[artIndex]; |
|
}); |
|
} |
|
|
|
function updateArtistsCountPerTag(whoCalled) { |
|
var permissiveCheckbox = document.querySelector('input[name="mode"]'); |
|
var deprecatedCheckbox = document.querySelector('input[name="deprecated"]'); |
|
var checkboxes = document.querySelectorAll('input[type="checkbox"]'); |
|
var divs = document.querySelectorAll('.image-item'); |
|
var hiddenDivs = document.querySelectorAll('.image-item.hidden'); |
|
var deprecatedDivs = document.querySelectorAll('.image-item[data-deprecated="true"]'); |
|
var count = 0; |
|
if(permissiveCheckbox.checked || whoCalled == 'start') { |
|
|
|
checkboxes.forEach(function(checkbox) { |
|
let isTop = checkbox.parentNode.classList.contains('top_control'); |
|
if(!isTop) { |
|
var theClass = checkbox.name.replace(/(^|\s)(\d)/g, '$1qqqq-$2'); |
|
var matchingDivs = document.querySelectorAll('.image-item.' + theClass); |
|
let filteredDivs = Array.from(matchingDivs).filter(mat => { |
|
return !Array.from(deprecatedDivs).some(dep => dep === mat); |
|
}); |
|
if(deprecatedCheckbox.checked) { |
|
count = filteredDivs.length; |
|
} else { |
|
count = matchingDivs.length; |
|
} |
|
checkbox.parentNode.classList.remove('no_matches'); |
|
checkbox.parentNode.querySelector('input').disabled = false; |
|
|
|
if(count) { |
|
checkbox.parentNode.querySelector('.count').textContent = ' - ' + count.toLocaleString(); |
|
} else { |
|
checkbox.parentNode.querySelector('.count').textContent = ' - ' + 'edited'; |
|
} |
|
} |
|
}); |
|
updateArtistsCountPerCategory(); |
|
} |
|
if(!permissiveCheckbox.checked) { |
|
checkboxes.forEach(function(checkbox) { |
|
let isTop = checkbox.parentNode.classList.contains('top_control'); |
|
if(!isTop) { |
|
count = 0; |
|
|
|
|
|
var theClass = checkbox.name.replace(/(^|\s)(\d)/g, '$1qqqq-$2'); |
|
|
|
var matchingDivs = document.querySelectorAll('.image-item.' + theClass + ':not(.hidden)'); |
|
let filteredDivs = Array.from(matchingDivs).filter(mat => { |
|
return !Array.from(deprecatedDivs).some(dep => dep === mat); |
|
}); |
|
if(deprecatedCheckbox.checked) { |
|
count = filteredDivs.length; |
|
} else { |
|
count = matchingDivs.length; |
|
} |
|
if(count == 0) { |
|
checkbox.parentNode.classList.add('no_matches'); |
|
checkbox.parentNode.querySelector('input').disabled = true; |
|
} else { |
|
checkbox.parentNode.classList.remove('no_matches'); |
|
checkbox.parentNode.querySelector('input').disabled = false; |
|
} |
|
checkbox.parentNode.querySelector('.count').textContent = ' - ' + count.toLocaleString(); |
|
} |
|
}); |
|
} |
|
updateCountOfAllArtistsShown(divs, hiddenDivs); |
|
} |
|
|
|
function updateArtistsCountPerCategory() { |
|
var imageItems = document.querySelectorAll('.image-item'); |
|
let counts = []; |
|
for(i=0,il=tagCategories.length; i<il; i++) { |
|
counts[i] = 0; |
|
} |
|
imageItems.forEach(function(imageItem) { |
|
var classes = Array.from(imageItem.classList).map(className => { |
|
|
|
|
|
|
|
return className.replace(/^qqqq-/, ''); |
|
}); |
|
for(i=0,il=tagCategories.length; i<il; i++) { |
|
if(tagCategories[i].map(c => c.toLowerCase()).some(c => classes.includes(c))) { |
|
counts[i]++; |
|
} |
|
} |
|
}); |
|
for(i=0,il=tagCategories.length; i<il; i++) { |
|
let label = document.querySelector('[data-category-name="' + tagCategories[i][0] + '"]'); |
|
label.querySelector('.count').textContent = ' - ' + counts[i].toLocaleString(); |
|
} |
|
} |
|
|
|
function updateCountOfAllArtistsShown(divs, hiddenDivs) { |
|
var checkAll = document.querySelector('input[name="check-all"]').parentNode.querySelector('.count'); |
|
var shown = document.getElementById('artistsShown').querySelector('.count'); |
|
var deprecatedItems = document.querySelectorAll('[data-deprecated="true"]'); |
|
if(!divs) { |
|
|
|
var divs = document.querySelectorAll('.image-item'); |
|
var hiddenDivs = document.querySelectorAll('.image-item.hidden'); |
|
} |
|
var total = 0; |
|
var visible = 0; |
|
if(document.querySelector('input[name="deprecated"]').checked) { |
|
total = divs.length - deprecatedItems.length; |
|
visible = total - hiddenDivs.length + deprecatedItems.length; |
|
} else { |
|
total = divs.length; |
|
visible = total - hiddenDivs.length; |
|
} |
|
var percent = Math.round((visible / total) * 100) + '%'; |
|
if(percent == '0%') { |
|
percent = '<1%'; |
|
} |
|
checkAll.textContent = ' - ' + total.toLocaleString(); |
|
shown.textContent = 'shown - ' + visible.toLocaleString() + ' / ' + percent; |
|
} |
|
|
|
function checkAllInCategory(theCheckbox) { |
|
let thisLabel = theCheckbox.parentNode; |
|
if (thisLabel.classList.contains('category')) { |
|
let container = document.getElementById('toggles'); |
|
let labels = container.getElementsByTagName('label'); |
|
let isChecking = false; |
|
for (let label of labels) { |
|
|
|
if(label === thisLabel) { |
|
isChecking = true; |
|
continue; |
|
} |
|
|
|
if(isChecking && label.classList.contains('category')) { |
|
break; |
|
} |
|
|
|
if(isChecking) { |
|
if(!label.classList.contains('hidden')) { |
|
|
|
let checkbox = label.querySelector('input[type="checkbox"]'); |
|
if(checkbox) { |
|
checkbox.checked = theCheckbox.checked; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
function hideAllArtists() { |
|
var imageItems = document.querySelectorAll('.image-item'); |
|
imageItems.forEach(function(imageItem) { |
|
imageItem.classList.add('hidden'); |
|
}); |
|
} |
|
|
|
function unhideBasedOnPermissiveSetting() { |
|
var permissiveCheckbox = document.querySelector('input[name="mode"]'); |
|
if(permissiveCheckbox.checked) { |
|
permissiveCheckbox.parentNode.classList.remove('warning'); |
|
unhideArtistsPermissive(); |
|
} else { |
|
permissiveCheckbox.parentNode.classList.add('warning'); |
|
unhideArtistsStrict(); |
|
} |
|
var unHidden = document.querySelectorAll('.image-item').length - document.querySelectorAll('.image-item.hidden').length; |
|
if(unHidden == 0) { |
|
document.getElementById('filtersHidingAll').classList.add('shown'); |
|
} else { |
|
document.getElementById('filtersHidingAll').classList.remove('shown'); |
|
} |
|
} |
|
|
|
function unhideArtistsPermissive() { |
|
|
|
|
|
var imageItems = document.querySelectorAll('.image-item'); |
|
var checkboxes = Array.from(document.querySelectorAll('input[type="checkbox"]')) |
|
.filter(cb => !cb.parentNode.classList.contains("top_control")); |
|
checkboxes.push(document.querySelector('input[name="favorite"]')); |
|
var checked = checkboxes.filter(cb => cb.checked).map(cb => cb.name); |
|
imageItems.forEach(function(imageItem) { |
|
var classes = Array.from(imageItem.classList).map(className => { |
|
|
|
|
|
|
|
return className.replace(/^qqqq-/, ''); |
|
}); |
|
if(checked.some(c => classes.includes(c))) { |
|
imageItem.classList.remove('hidden'); |
|
} |
|
}); |
|
hideDeprecated(); |
|
} |
|
|
|
function unhideArtistsStrict() { |
|
|
|
|
|
var imageItems = document.querySelectorAll('.image-item'); |
|
var checkboxes = Array.from(document.querySelectorAll('input[type="checkbox"]')) |
|
.filter(cb => !cb.parentNode.classList.contains("top_control")); |
|
checkboxes.push(document.querySelector('input[name="favorite"]')); |
|
var checked = checkboxes.filter(cb => cb.checked).map(cb => cb.name); |
|
if(checked.length > 0) { |
|
imageItems.forEach(function(imageItem, index) { |
|
var classes = Array.from(imageItem.classList).map(className => { |
|
|
|
|
|
|
|
return className.replace(/^qqqq-/, ''); |
|
}); |
|
if(checked.every(c => classes.includes(c))) { |
|
imageItem.classList.remove('hidden'); |
|
} |
|
}); |
|
} else { |
|
|
|
|
|
imageItems.forEach(function(imageItem) { |
|
imageItem.classList.remove('hidden'); |
|
}); |
|
} |
|
hideDeprecated(); |
|
} |
|
|
|
function unhideAristsExact() { |
|
|
|
|
|
|
|
var imageItems = document.querySelectorAll('.image-item'); |
|
var checkboxes = Array.from(document.querySelectorAll('input[type="checkbox"]')) |
|
.filter(cb => !cb.parentNode.classList.contains("top_control")); |
|
checkboxes.push(document.querySelector('input[name="favorite"]')); |
|
var checked = checkboxes.filter(cb => cb.checked).map(cb => cb.name); |
|
var unchecked = checkboxes.filter(cb => !cb.checked).map(cb => cb.name); |
|
if(checked.length > 0) { |
|
imageItems.forEach(function(imageItem, index) { |
|
var classes = Array.from(imageItem.classList); |
|
if(checked.every(c => classes.includes(c))) { |
|
if(unchecked.every(c => !classes.includes(c))) { |
|
imageItem.classList.remove('hidden'); |
|
} |
|
} |
|
}); |
|
} |
|
hideDeprecated(); |
|
} |
|
|
|
function hideDeprecated() { |
|
if(document.querySelector('input[name="deprecated"]').checked) { |
|
let deprecatedItems = document.querySelectorAll('[data-deprecated="true"]'); |
|
deprecatedItems.forEach(function(item, index) { |
|
item.classList.add('hidden'); |
|
}); |
|
} |
|
} |
|
|
|
function checkOrUncheckAll(isChecked) { |
|
var divs = document.querySelectorAll('.image-item'); |
|
var checkboxes = document.querySelectorAll('input[type="checkbox"]'); |
|
if(isChecked) { |
|
checkboxes.forEach(function(checkbox) { |
|
let label = checkbox.parentNode; |
|
let isTop = label.classList.contains('top_control'); |
|
let isHidden = label.classList.contains('hidden'); |
|
if(!isTop || checkbox.name == 'favorite') { |
|
if(!isHidden) { |
|
|
|
checkbox.checked = true; |
|
} |
|
}; |
|
}); |
|
} else { |
|
checkboxes.forEach(function(checkbox) { |
|
let label = checkbox.parentNode; |
|
let isTop = label.classList.contains('top_control'); |
|
if(!isTop || checkbox.name == 'favorite') { |
|
checkbox.checked = false; |
|
} |
|
}); |
|
} |
|
} |
|
|
|
function showInstructions() { |
|
document.getElementById('instructions').classList.add('shown'); |
|
hideToggles(); |
|
} |
|
|
|
function showAbout() { |
|
document.getElementById('about').classList.add('shown'); |
|
hideToggles(); |
|
} |
|
|
|
function showExport() { |
|
hideToggles(); |
|
document.getElementById('export').classList.add('shown'); |
|
|
|
var textareaF = document.getElementById('export_favorites_list'); |
|
var favorites = localStorage.getItem('favoritedArtists'); |
|
var value = ''; |
|
if(favorites) { |
|
value += 'You have favorited these artists:\r\n'; |
|
for (let key in JSON.parse(favorites)) { |
|
if (JSON.parse(favorites)[key] === true) { |
|
let names = key.split("|"); |
|
if(!names[0]) { names[0] = '(no first name)'; } |
|
value += '•' + names[0] + ',' + names[1] + '\r\n'; |
|
} |
|
} |
|
value += '\r\n\r\nTo import these favorites later, click "copy to clipboard" and save to any file. Then paste the text from that file into this text box, and click "import". The imported text must contain the JSON string below (the curly brackets and what\'s between them). It must not contain any other more than one set of curly brackets.\r\n\r\n' + favorites; |
|
textareaF.value = value; |
|
} else { |
|
value += 'You haven\'t favorited any artists yet.\r\n\r\n'; |
|
value += 'To import favorites that you exported earlier, paste the text into this text box, and click "import".'; |
|
} |
|
|
|
var textareaE = document.getElementById('export_edits_list'); |
|
let editedArtistsArr = Array.from(editedArtists); |
|
if(editedArtistsArr.length > 0) { |
|
value = 'Post a comment with these edits on Hugging Face:\r\n\r\n'; |
|
for(i=0,il=editedArtistsArr.length;i<il;i++) { |
|
let edit = editedArtistsArr[i]; |
|
value += '["'+edit[0]+'","'+edit[1]+'","'+edit[2]+'",'+edit[3]+'],\r\n'; |
|
} |
|
} else { |
|
value = ''; |
|
} |
|
textareaE.value = value; |
|
|
|
var textareaA = document.getElementById('export_artists_list'); |
|
value = ''; |
|
for(i=0,il=artistsData.length;i<il;i++) { |
|
let edit = artistsData[i]; |
|
value += '["'+edit[0]+'","'+edit[1]+'","'+edit[2]+'",'+edit[3]+'],\r\n'; |
|
} |
|
textareaA.value = value; |
|
} |
|
|
|
function exportTextarea(type) { |
|
let contents = ''; |
|
if(type == 'favorites') { |
|
contents = document.getElementById('export_favorites_list').value; |
|
} else if(type == 'edits') { |
|
contents = document.getElementById('export_edits_list').value; |
|
} else if(type == 'artists') { |
|
contents = document.getElementById('export_artists_list').value; |
|
} |
|
navigator.clipboard.writeText(contents) |
|
.then(() => { |
|
doAlert(type + ' copied to clipboard!',1); |
|
}) |
|
.catch(() => { |
|
doAlert('😭😭 Can\'t access clipboard',1); |
|
}); |
|
} |
|
|
|
function importFavorites() { |
|
let el = document.getElementById('export_favorites_list'); |
|
let favorites = el.value; |
|
let startCount = (favorites.match(/{/g) || []).length; |
|
let endCount = (favorites.match(/}/g) || []).length; |
|
if (startCount > 1 || endCount > 1) { |
|
el.value = 'That text can\'t be imported because it contains multiple curly brackets {}.' |
|
return null; |
|
} |
|
let start = favorites.indexOf('{'); |
|
let end = favorites.lastIndexOf('}'); |
|
if (start === -1 || end === -1) { |
|
el.value = 'That text can\'t be imported because it contains zero curly brackets {}.' |
|
return null; |
|
} |
|
let jsonString = favorites.substring(start, end + 1); |
|
try { |
|
let jsonObject = JSON.parse(jsonString); |
|
|
|
for (let key in jsonObject) { |
|
let value = jsonObject[key]; |
|
if (!key.includes('|') || typeof value !== 'boolean') { |
|
el.value = 'That text can\'t be imported because the JSON string it contains doesn\'t contain a valid list of artists.' |
|
return null; |
|
} |
|
} |
|
if(confirm('This will overwrite any saved favorites. Are you sure?')) { |
|
localStorage.setItem('favoritedArtists', jsonString); |
|
alert('Favorites were imported!'); |
|
loadFavoritesState(); |
|
} else { |
|
alert('Okay, you have cancelled the import.'); |
|
return null; |
|
} |
|
} catch(e) { |
|
el.value = 'That text can\'t be imported because it doesn\'t contain a valid JSON sting.' |
|
return null; |
|
} |
|
} |
|
|
|
function hideInformation() { |
|
var information = document.querySelectorAll('.information'); |
|
information.forEach(function(element) { |
|
element.classList.remove('shown'); |
|
}); |
|
showToggles(); |
|
} |
|
|
|
function sortTags() { |
|
if(document.getElementById('sortTC').classList.contains('selected')) { |
|
sortTagsByCount(); |
|
} else { |
|
sortTagsByAlpha(); |
|
} |
|
} |
|
|
|
function sortTagsByAlpha() { |
|
var useCategories = document.querySelector('input[name="use_categories"]').checked; |
|
let container = document.getElementById('toggles'); |
|
let labels = Array.from(container.getElementsByTagName('label')); |
|
if (!useCategories) { |
|
|
|
labels.sort(function(a, b) { |
|
var aValue = a.querySelector('input[type="checkbox"]').name; |
|
var bValue = b.querySelector('input[type="checkbox"]').name; |
|
return aValue.localeCompare(bValue); |
|
}); |
|
labels.forEach(function(label) { |
|
let isTop = label.classList.contains('top_control'); |
|
if(!isTop) { |
|
|
|
container.appendChild(label); |
|
} |
|
}); |
|
} else { |
|
let labelMap = labels.reduce((acc, label) => { |
|
|
|
let checkboxName = label.querySelector('input[type="checkbox"]').name; |
|
acc[checkboxName.toLowerCase()] = label; |
|
return acc; |
|
}, {}); |
|
|
|
tagCategories.forEach(arrayOfTags => { |
|
|
|
let categoryName = arrayOfTags[0]; |
|
let categoryLabel = labelMap[categoryName.toLowerCase()]; |
|
if (categoryLabel) { |
|
container.appendChild(categoryLabel); |
|
} |
|
|
|
let arrayOfTagsLower = arrayOfTags.slice(1).map(tag => tag.toLowerCase()); |
|
arrayOfTagsLower.sort(); |
|
arrayOfTagsLower.forEach(tag => { |
|
let label = labelMap[tag]; |
|
if (label) { |
|
let isTop = label.classList.contains('top_control'); |
|
if(!isTop) { |
|
label.dataset.isInCategory = categoryLabel.dataset.categoryName; |
|
|
|
container.appendChild(label); |
|
} |
|
|
|
delete labelMap[tag]; |
|
} |
|
}); |
|
if(categoryName == 'important') { |
|
container.appendChild(document.getElementById('edit_most_used')); |
|
} |
|
}); |
|
|
|
let leftoverLabelsKeys = Object.keys(labelMap); |
|
leftoverLabelsKeys.sort(); |
|
leftoverLabelsKeys.forEach(key => { |
|
let label = labelMap[key]; |
|
if (label && !label.classList.contains('top_control') && !label.classList.contains('category')) { |
|
label.dataset.isInCategory = 'other'; |
|
container.appendChild(label); |
|
} |
|
}); |
|
} |
|
} |
|
|
|
function sortTagsByCount() { |
|
var useCategories = document.querySelector('input[name="use_categories"]').checked; |
|
let container = document.getElementById('toggles'); |
|
let labels = Array.from(container.getElementsByTagName('label')); |
|
if (!useCategories) { |
|
labels.sort(function(a, b) { |
|
var numA = parseInt(a.querySelector('.count').textContent.replace(/,/g, '').trim().substring(2),10); |
|
var numB = parseInt(b.querySelector('.count').textContent.replace(/,/g, '').trim().substring(2),10); |
|
return numB - numA; |
|
}); |
|
labels.forEach(function(label) { |
|
let isTop = label.classList.contains('top_control'); |
|
if(!isTop) { |
|
|
|
container.appendChild(label); |
|
} |
|
}); |
|
} else { |
|
let labelMap = labels.reduce((acc, label) => { |
|
|
|
let checkboxName = label.querySelector('input[type="checkbox"]').name; |
|
acc[checkboxName.toLowerCase()] = label; |
|
return acc; |
|
}, {}); |
|
tagCategories.forEach(arrayOfTags => { |
|
let categoryName = arrayOfTags[0]; |
|
let categoryLabel = labelMap[categoryName.toLowerCase()]; |
|
if (categoryLabel) { |
|
container.appendChild(categoryLabel); |
|
} |
|
|
|
let arrayOfTagsLower = arrayOfTags.slice(1).map(tag => tag.toLowerCase()); |
|
|
|
arrayOfTagsLowerExisting = []; |
|
arrayOfTagsLower.forEach(function(tag) { |
|
if(labelMap[tag]) { |
|
arrayOfTagsLowerExisting.push(tag); |
|
} |
|
}); |
|
arrayOfTagsLowerExisting.sort((a, b) => { |
|
let labelA = labelMap[a]; |
|
let labelB = labelMap[b]; |
|
if(labelA && labelB){ |
|
let numA = parseInt(labelA.querySelector('.count').textContent.replace(/,/g, '').trim().substring(2), 10); |
|
let numB = parseInt(labelB.querySelector('.count').textContent.replace(/,/g, '').trim().substring(2), 10); |
|
return numB - numA; |
|
} else { |
|
return 0; |
|
} |
|
}); |
|
arrayOfTagsLowerExisting.forEach(tag => { |
|
let label = labelMap[tag]; |
|
if (label) { |
|
let isTop = label.classList.contains('top_control'); |
|
if (!isTop) { |
|
|
|
label.dataset.isInCategory = categoryLabel.dataset.categoryName; |
|
container.appendChild(label); |
|
} |
|
|
|
delete labelMap[tag]; |
|
} |
|
}); |
|
if(categoryName == 'important') { |
|
container.appendChild(document.getElementById('edit_most_used')); |
|
} |
|
}); |
|
let leftoverLabelsKeys = Object.keys(labelMap); |
|
|
|
leftoverLabelsKeys.sort((a, b) => { |
|
let labelA = labelMap[a]; |
|
let labelB = labelMap[b]; |
|
if(labelA && labelB){ |
|
let numA = parseInt(labelA.querySelector('.count').textContent.replace(/,/g, '').trim().substring(2), 10); |
|
let numB = parseInt(labelB.querySelector('.count').textContent.replace(/,/g, '').trim().substring(2), 10); |
|
return numB - numA; |
|
} else { |
|
return 0; |
|
} |
|
}); |
|
leftoverLabelsKeys.forEach(key => { |
|
let label = labelMap[key]; |
|
if (label && !label.classList.contains('top_control') && !label.classList.contains('category')) { |
|
label.dataset.isInCategory = 'other'; |
|
container.appendChild(label); |
|
} |
|
}); |
|
} |
|
} |
|
|
|
function loadMostUsedTags() { |
|
let state = JSON.parse(localStorage.getItem('mustUsedTags')) || {}; |
|
let mostUsedCategory = document.querySelector('[data-category-name="important"]'); |
|
for(let tag in state) { |
|
if (state[tag]) { |
|
let label = document.querySelector('input[name="'+ tag +'"]'); |
|
if(label) { |
|
label = label.parentNode; |
|
label.classList.add('is_most_used'); |
|
label.querySelectorAll('.most_used_indicator')[0].textContent = '-'; |
|
mostUsedCategory.after(label); |
|
updateTagArrayToMatchMostUsed(true,label,tag); |
|
} |
|
} |
|
}; |
|
} |
|
|
|
function updateTagArrayToMatchMostUsed(isAdding,label,tag) { |
|
|
|
|
|
if(isAdding) { |
|
tagCategories[0].push(tag); |
|
|
|
for(i=0,il<tagCategories.length; i<il; i++) { |
|
if(tagCategories[i][0] == label.dataset.isInCategory) { |
|
tagCategories[i] = tagCategories[i].filter(function(ele){ |
|
return ele != tag; |
|
}); |
|
break; |
|
} |
|
} |
|
} else { |
|
tagCategories[0] = tagCategories[0].filter(function(ele){ |
|
return ele != tag; |
|
}); |
|
|
|
for(i=0,il<tagCategories.length; i<il; i++) { |
|
if(tagCategories[i][0] == label.dataset.isInCategory) { |
|
tagCategories[i].push(tag); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
|
|
function storeMostUsedState(label) { |
|
var name = label.querySelector('input').name; |
|
let state = JSON.parse(localStorage.getItem('mustUsedTags')) || {}; |
|
state[name] = label.classList.contains('is_most_used'); |
|
localStorage.setItem('mustUsedTags', JSON.stringify(state)); |
|
} |
|
|
|
function enterExitEditMostUsedMode(doExit) { |
|
let inputs = Array.from(document.querySelectorAll('input')); |
|
if(editMostUsedMode || doExit) { |
|
|
|
editMostUsedMode = false; |
|
document.getElementById('edit_most_used').textContent = 'edit'; |
|
document.getElementById('layout').classList.remove('edit_mode'); |
|
inputs.forEach(function(input) { |
|
input.disabled = false; |
|
}); |
|
let labels = Array.from(document.querySelectorAll('.was_moved')); |
|
labels.forEach(function(label) { |
|
|
|
label.classList.remove('was_moved'); |
|
}) |
|
document.getElementById('toggles').style.width = 'calc(' + gutterEndPercentX + '% - 20px)'; |
|
document.getElementById('gutter').style.left = gutterEndPercentX + '%'; |
|
document.getElementById('image-container').style.marginLeft = 'calc(' + gutterEndPercentX + '% + 50px)'; |
|
updateArtistsCountPerCategory(); |
|
} else { |
|
|
|
editMostUsedMode = true; |
|
document.getElementById('edit_most_used').textContent = 'exit editing'; |
|
document.getElementById('layout').classList.add('edit_mode'); |
|
inputs.forEach(function(input) { |
|
input.disabled = true; |
|
}); |
|
document.getElementById('toggles').style.width = ''; |
|
document.getElementById('gutter').style.left = ''; |
|
document.getElementById('image-container').style.marginLeft = ''; |
|
} |
|
} |
|
|
|
function addRemoveIsMostUsed(label) { |
|
let mostUsedCategory = document.querySelector('[data-category-name="important"]'); |
|
if(label.classList.contains('is_most_used')) { |
|
|
|
label.classList.remove('is_most_used'); |
|
label.querySelectorAll('.most_used_indicator')[0].textContent = '+'; |
|
let originalCategory = document.querySelector('[data-category-name="' + label.dataset.isInCategory + '"]'); |
|
originalCategory.after(label); |
|
updateTagArrayToMatchMostUsed(false,label,label.querySelector('input').name); |
|
} else { |
|
|
|
label.classList.add('is_most_used'); |
|
label.querySelectorAll('.most_used_indicator')[0].textContent = '-'; |
|
mostUsedCategory.after(label); |
|
updateTagArrayToMatchMostUsed(true,label,label.querySelector('input').name); |
|
} |
|
label.classList.add('was_moved'); |
|
} |
|
|
|
function sortArtists() { |
|
if(document.getElementById('sortAR').classList.contains('selected')) { |
|
sortArtistsByRandom(); |
|
} else { |
|
sortArtistsByAlpha(); |
|
} |
|
} |
|
|
|
function sortArtistsByAlpha() { |
|
var imageItems = Array.from(document.querySelectorAll('.image-item')); |
|
imageItems.sort(function(a, b) { |
|
var aValue = a.querySelector('.lastN').textContent; |
|
var bValue = b.querySelector('.lastN').textContent; |
|
return aValue.localeCompare(bValue); |
|
}); |
|
imageItems.forEach(function(item) { |
|
|
|
document.getElementById('image-container').appendChild(item); |
|
}); |
|
} |
|
|
|
function sortArtistsByRandom() { |
|
var imageItems = Array.from(document.querySelectorAll('.image-item')); |
|
imageItems.forEach(function(item) { |
|
item.dataset.randomRank = Math.random(); |
|
}); |
|
imageItems.sort(function(a, b) { |
|
var aValue = a.dataset.randomRank; |
|
var bValue = b.dataset.randomRank; |
|
return bValue - aValue; |
|
}); |
|
imageItems.forEach(function(item) { |
|
|
|
document.getElementById('image-container').appendChild(item); |
|
}); |
|
} |
|
|
|
function hideToggles() { |
|
document.getElementById('toggles').classList.add('hide'); |
|
} |
|
|
|
function showToggles() { |
|
document.getElementById('toggles').classList.remove('hide'); |
|
} |
|
|
|
function addOrRemoveFavorite(artist) { |
|
if(artist.classList.contains('favorite')) { |
|
artist.classList.remove('favorite'); |
|
} else { |
|
artist.classList.add('favorite'); |
|
} |
|
} |
|
|
|
function loadFavoritesState() { |
|
let state = JSON.parse(localStorage.getItem('favoritedArtists')) || {}; |
|
let artists = document.getElementsByClassName('image-item'); |
|
for(let artist of artists) { |
|
let artistName = artist.getElementsByClassName('firstN')[0].textContent + '|' + artist.getElementsByClassName('lastN')[0].textContent; |
|
if(state[artistName]) { |
|
artist.classList.add('favorite'); |
|
} else { |
|
artist.classList.remove('favorite'); |
|
} |
|
} |
|
updateFavoritesCount(); |
|
} |
|
|
|
function storeFavoriteState(artist) { |
|
var artistName = artist.getElementsByClassName('firstN')[0].textContent + '|' + artist.getElementsByClassName('lastN')[0].textContent; |
|
var isFavorited = artist.classList.contains('favorite'); |
|
let state = JSON.parse(localStorage.getItem('favoritedArtists')) || {}; |
|
state[artistName] = isFavorited; |
|
localStorage.setItem('favoritedArtists', JSON.stringify(state)); |
|
} |
|
|
|
function updateFavoritesCount() { |
|
var favoritedArtists = document.getElementsByClassName('favorite'); |
|
var favoriteCount = favoritedArtists.length; |
|
var favoriteCounter = document.querySelectorAll('input[name="favorite"]')[0].parentNode.querySelector('.count'); |
|
favoriteCounter.textContent = ' - ' + favoriteCount; |
|
} |
|
|
|
function doAlert(str,location) { |
|
var alert = document.getElementById('alert'); |
|
alert.textContent = str; |
|
|
|
alert.classList.remove('show'); |
|
window.clearTimeout(timer); |
|
if(location == 0) { |
|
alert.classList.add('left'); |
|
} else { |
|
alert.classList.remove('left'); |
|
|
|
} |
|
timer = setTimeout(showAlert, 100); |
|
} |
|
|
|
function showAlert() { |
|
var alert = document.getElementById('alert'); |
|
alert.classList.add('show'); |
|
if(alert.classList.contains('left')) { |
|
|
|
timer = setTimeout(hideAlert, 750); |
|
} else { |
|
timer = setTimeout(hideAlert, 2000); |
|
} |
|
} |
|
|
|
function hideAlert() { |
|
var alert = document.getElementById('alert'); |
|
alert.classList.remove('show'); |
|
} |
|
|
|
function copyStuffToClipboard(item,stuff) { |
|
if(stuff == 'name') { |
|
var str = item.closest('.image-item').getElementsByClassName('firstN')[0].textContent + |
|
' ' + item.closest('.image-item').getElementsByClassName('lastN')[0].textContent; |
|
navigator.clipboard.writeText(str) |
|
.then(() => { |
|
doAlert('Copied to name clipboard!',1); |
|
}) |
|
.catch(() => { |
|
doAlert('😭😭 Can\'t access clipboard',1); |
|
}); |
|
} else if(stuff == 'tags') { |
|
var str = item.textContent; |
|
navigator.clipboard.writeText(str) |
|
.then(() => { |
|
doAlert('Copied to tags clipboard!',1); |
|
}) |
|
.catch(() => { |
|
doAlert('😭😭 Can\'t access clipboard',1); |
|
}); |
|
} |
|
} |
|
|
|
function toggleThisArtistsTags(tagsStr) { |
|
let names = tagsStr.split(', '); |
|
let allChecked = true; |
|
for(i=0,il=names.length;i<il;i++) { |
|
if(!document.querySelector('input[name="'+names[i]+'"]').checked) { |
|
allChecked = false; |
|
break; |
|
} |
|
} |
|
for(i=0,il=names.length;i<il;i++) { |
|
var checkbox = document.querySelector('input[name="'+names[i]+'"]'); |
|
if(allChecked) { |
|
checkbox.checked = false; |
|
} else { |
|
checkbox.checked = true; |
|
} |
|
storeCheckboxState(checkbox); |
|
} |
|
} |
|
|
|
function showHideCategories() { |
|
let useCategories = document.querySelectorAll('input[name="use_categories"]')[0].checked; |
|
let categories = document.getElementsByClassName('category'); |
|
for(let category of categories) { |
|
if(useCategories) { |
|
category.classList.remove('hidden'); |
|
} else { |
|
category.classList.add('hidden'); |
|
} |
|
} |
|
let editLink = document.getElementById('edit_most_used'); |
|
if(useCategories) { |
|
editLink.classList.remove('hidden'); |
|
} else { |
|
editLink.classList.add('hidden'); |
|
} |
|
} |
|
|
|
function showHideLowCountTags() { |
|
var hideLowCount = document.querySelector('input[name="low_count"]').checked; |
|
var checkboxes = document.querySelectorAll('input[type="checkbox"]'); |
|
checkboxes.forEach(function(checkbox) { |
|
if(hideLowCount) { |
|
var classes = checkbox.parentNode.classList; |
|
if(classes.contains('category') || classes.contains('no_matches') || classes.contains('top_control')) { |
|
|
|
} else { |
|
let count = parseInt(checkbox.parentNode.querySelector('.count').textContent.replace(/,/g, '').trim().substring(2),10); |
|
if(count < 3) { |
|
checkbox.checked = false; |
|
checkbox.parentNode.classList.add('hidden'); |
|
} |
|
} |
|
} else { |
|
checkbox.parentNode.classList.remove('hidden'); |
|
} |
|
showHideCategories(); |
|
}); |
|
} |
|
|
|
function loadLargerImages(imageItem) { |
|
let images = imageItem.querySelectorAll('img'); |
|
let missingFiles = ''; |
|
let imagePromises = Array.from(images).map((img) => { |
|
if(img.src.indexOf('_thumbs') > -1 && img.dataset.thumbSrc == undefined) { |
|
|
|
if(!img.dataset.deprecated) { |
|
let first = img.closest('.image-item').querySelector('.firstN').textContent; |
|
let last = img.closest('.image-item').querySelector('.lastN').textContent; |
|
return new Promise((resolve, reject) => { |
|
img.onload = () => { |
|
resolve(); |
|
} |
|
img.onerror = () => { |
|
if(img.dataset.missingFiles == undefined) { |
|
img.dataset.missingFiles = true; |
|
missingFiles += '<li>' + img.src + '</li>'; |
|
img.src = img.dataset.thumbSrc; |
|
} |
|
reject(); |
|
}; |
|
img.dataset.thumbSrc = img.src; |
|
let src = 'images/SDXL_1_0/'; |
|
if(first == '') { |
|
src += last.replaceAll(' ', '_'); |
|
} else { |
|
src += first.replaceAll(' ', '_') + '_' + last.replaceAll(' ', '_'); |
|
} |
|
if(img.classList.contains('img_artwork')) { |
|
img.src = src + '-artwork.webp'; |
|
} else if(img.classList.contains('img_portrait')) { |
|
img.src = src + '-portrait.webp'; |
|
} else if(img.classList.contains('img_landscape')) { |
|
img.src = src + '-landscape.webp'; |
|
} |
|
}); |
|
} |
|
} |
|
}); |
|
let report = document.getElementById('missing_images_report'); |
|
if(imagePromises.length > 0) { |
|
Promise.allSettled(imagePromises).then(() => { |
|
if(missingFiles.indexOf('webp')>0) { |
|
report.innerHTML += missingFiles; |
|
} |
|
}); |
|
} |
|
} |
|
|
|
function hideLargerImageBackup(imageItem) { |
|
|
|
|
|
|
|
windowWidth = window.innerWidth; |
|
let layout = document.getElementById('layout'); |
|
|
|
imageItem.boundMouseMoveFunc = mouseMoveFunc.bind(null, imageItem); |
|
layout.addEventListener('mousemove', imageItem.boundMouseMoveFunc); |
|
timer = setTimeout(function() { |
|
cleanupEventListener(imageItem); |
|
}, 200); |
|
} |
|
|
|
function mouseMoveFunc(imageItem, e) { |
|
if (e.clientX < (windowWidth * 0.4)) { |
|
imageItem.getElementsByClassName('imgBox')[0].style.position = 'relative'; |
|
} |
|
} |
|
|
|
function cleanupEventListener(imageItem) { |
|
imageItem.getElementsByClassName('imgBox')[0].style.position = ''; |
|
let layout = document.getElementById('layout'); |
|
|
|
layout.removeEventListener('mousemove', imageItem.boundMouseMoveFunc); |
|
} |
|
|
|
function getStyleRuleForDrag() { |
|
style = document.createElement('style'); |
|
document.head.appendChild(style); |
|
stylesheet = style.sheet; |
|
let index = stylesheet.insertRule('.image-item:hover .imgBox { width: 40%; }', 0); |
|
imgHoverRule = stylesheet.cssRules[index]; |
|
} |
|
|
|
function movePartition(e) { |
|
let newPos = gutterStartPosX + e.pageX - mouseStartPosX; |
|
if(newPos < 240) { |
|
newPos = 240; |
|
} else if(newPos > window.innerWidth - 350) { |
|
newPos = window.innerWidth - 350; |
|
} |
|
gutterEndPercentX = (newPos / window.innerWidth) * 100; |
|
document.getElementById('toggles').style.width = 'calc(' + gutterEndPercentX + '% - 20px)'; |
|
document.getElementById('gutter').style.left = gutterEndPercentX + '%'; |
|
document.getElementById('image-container').style.marginLeft = 'calc(' + gutterEndPercentX + '% + 50px)'; |
|
imgHoverRule.style.width = gutterEndPercentX + '%'; |
|
|
|
if (window.getSelection) { |
|
if (window.getSelection().empty) { |
|
|
|
window.getSelection().empty(); |
|
} else if (window.getSelection().removeAllRanges) { |
|
|
|
window.getSelection().removeAllRanges(); |
|
} |
|
} else if (document.selection) { |
|
|
|
document.selection.empty(); |
|
} |
|
} |
|
|
|
function editTagsClicked(clickedImageItem) { |
|
let indicatorEl = clickedImageItem.querySelector('.art_edit span'); |
|
if(indicatorEl.textContent == '✍️') { |
|
let artistWasInEditMode = editTagsFindArtistInEditMode(clickedImageItem); |
|
if(!artistWasInEditMode) { |
|
doAlert('Read help ⁉️ first',1); |
|
} |
|
editTagsEnterEditMode(clickedImageItem); |
|
} else { |
|
editTagsFindArtistInEditMode(); |
|
} |
|
} |
|
|
|
function editTagsEnterEditMode(imageItem) { |
|
|
|
let indicatorEl = imageItem.querySelector('.art_edit span'); |
|
indicatorEl.textContent = '❌'; |
|
let tagArea = imageItem.querySelector('h4'); |
|
tagArea.title = ''; |
|
tagArea.classList.add('edit_mode'); |
|
imageItem.classList.add('edit_mode'); |
|
let firstN = imageItem.querySelector('.firstN').textContent; |
|
let lastN = imageItem.querySelector('.lastN').textContent; |
|
let tagList = []; |
|
for (let i=0, il=artistsData.length; i<il; i++) { |
|
let artist = artistsData[i]; |
|
if(artist[0] == lastN && artist[1] == firstN) { |
|
let tagListStr = artist[2].replace(/\|added-(\d|-)*/g,''); |
|
tagList = tagListStr.split('|'); |
|
tagList.unshift(artist[3]); |
|
break; |
|
} |
|
} |
|
tagArea.textContent = ''; |
|
for (var i=0, il=tagList.length; i<il; i++) { |
|
addTagToEditor(tagArea,tagList[i]); |
|
} |
|
var adder = document.createElement('input'); |
|
adder.type = 'text'; |
|
adder.name = 'new_tag'; |
|
adder.placeholder = 'add another tag'; |
|
adder.dataset.match = ''; |
|
adder.style.marginTop = '10px'; |
|
tagArea.appendChild(adder); |
|
|
|
adder.addEventListener('focus', function(e) { |
|
var helper = document.createElement('span'); |
|
helper.id = 'edit_mode_helper'; |
|
this.parentNode.appendChild(helper); |
|
}); |
|
adder.addEventListener('keyup', function(e) { |
|
searchForTags(this,e,tagList); |
|
}); |
|
adder.addEventListener('blur', function(e) { |
|
this.value = ''; |
|
window.setTimeout(function() { |
|
|
|
if(document.getElementById('edit_mode_helper')) { |
|
document.getElementById('edit_mode_helper').remove(); |
|
} |
|
}, 100); |
|
}); |
|
} |
|
|
|
function editTagsFindArtistInEditMode(clickedImageItem) { |
|
let imageItems = document.querySelectorAll('.image-item'); |
|
imageItems.forEach(function(imageItem) { |
|
if(imageItem !== clickedImageItem) { |
|
|
|
let indicatorEl = imageItem.querySelector('.art_edit span'); |
|
if(indicatorEl.textContent == '❌') { |
|
editTagsExitEditMode(imageItem); |
|
|
|
return true; |
|
} |
|
} |
|
}); |
|
} |
|
|
|
function editTagsExitEditMode(imageItem) { |
|
|
|
let indicatorEl = imageItem.querySelector('.art_edit span'); |
|
indicatorEl.textContent = '✍️'; |
|
let tagArea = imageItem.querySelector('h4'); |
|
tagArea.title = 'copy to clipboard'; |
|
tagArea.classList.remove('edit_mode'); |
|
imageItem.classList.remove('edit_mode'); |
|
let tagList = ''; |
|
let tagLabels = tagArea.querySelectorAll('label'); |
|
tagLabels.forEach(function(label) { |
|
let input = label.querySelector('input'); |
|
if(input.checked) { |
|
tagList += input.value + ', '; |
|
label.remove(); |
|
} |
|
}); |
|
tagArea.querySelector('input').remove(); |
|
tagArea.textContent = tagList.substring(0,tagList.length-2); |
|
} |
|
|
|
function addTagToEditor(tagArea, tagName) { |
|
var label = document.createElement('label'); |
|
var input = document.createElement('input'); |
|
input.type = 'checkbox'; |
|
if(tagName === true || tagName === false) { |
|
input.name = 'known' |
|
input.value = 'known'; |
|
|
|
if(tagName) { |
|
input.checked = false; |
|
} else { |
|
input.checked = true; |
|
} |
|
tagName = 'known to SDXL' |
|
} else { |
|
input.name = tagName |
|
input.value = tagName; |
|
input.checked = true; |
|
} |
|
var span = document.createElement('span'); |
|
span.textContent = tagName; |
|
label.appendChild(input); |
|
label.appendChild(span); |
|
tagArea.appendChild(label); |
|
|
|
input.addEventListener('change', function(e) { |
|
saveTagsForArtist(tagArea); |
|
}); |
|
} |
|
|
|
function searchForTags(input, event, tagList) { |
|
if(input.dataset.match != '') { |
|
event.preventDefault(); |
|
if(event.key === 'Backspace' || event.keyCode === 8) { |
|
input.value = ''; |
|
input.dataset.match = ''; |
|
} else if (event.key === 'Return' || event.keyCode === 13) { |
|
input.value = ''; |
|
input.dispatchEvent(new Event('blur')); |
|
insertTag(input,input.dataset.match); |
|
input.dataset.match = ''; |
|
} else { |
|
input.value = input.dataset.match; |
|
} |
|
return; |
|
} |
|
let helper = document.getElementById('edit_mode_helper'); |
|
helper.innerHTML = ''; |
|
let matches = 0; |
|
let match = ''; |
|
let range = 'start' |
|
tagsConcatenated.forEach(function(tag) { |
|
for (var i=0, il=tagList.length; i<il; i++) { |
|
if(tag.toLowerCase() == tagList[i].toLowerCase()) { |
|
return; |
|
} |
|
} |
|
if(tag.toLowerCase().indexOf(input.value.toLowerCase()) == 0) { |
|
range = 'continue'; |
|
let matchSpan = document.createElement('span'); |
|
matchSpan.textContent = tag; |
|
helper.appendChild(matchSpan); |
|
matchSpan.addEventListener('click', function(e) { |
|
insertTag(e.target,e.target.textContent); |
|
}); |
|
match = tag; |
|
matches++; |
|
} else { |
|
if(range != 'start') { |
|
range = 'stop'; |
|
} |
|
} |
|
if(range == 'stop') { |
|
return; |
|
} |
|
}); |
|
if(matches == 1) { |
|
input.value = match; |
|
event.preventDefault(); |
|
input.dataset.match = match; |
|
} |
|
} |
|
|
|
function insertTag(matchSpan,tag) { |
|
let tagArea = matchSpan.closest('h4'); |
|
let input = tagArea.querySelector('input[type="text"]'); |
|
addTagToEditor(tagArea,tag); |
|
tagArea.appendChild(input); |
|
document.getElementById('edit_mode_helper').remove(); |
|
saveTagsForArtist(tagArea); |
|
timer = setTimeout(focusInput.bind(this, input), 100); |
|
} |
|
|
|
function focusInput(input) { |
|
input.focus(); |
|
} |
|
|
|
function saveTagsForArtist(tagArea) { |
|
|
|
let tagLabels = tagArea.querySelectorAll('label'); |
|
let newTagsArr = []; |
|
let artistKnown = true; |
|
tagLabels.forEach(function(label) { |
|
let input = label.querySelector('input'); |
|
if(input.value == 'known') { |
|
artistKnown = input.checked; |
|
} else { |
|
if(input.checked) { |
|
newTagsArr.push(input.value); |
|
} |
|
} |
|
}); |
|
|
|
let firstN = tagArea.closest('.image-item').querySelector('.firstN').textContent; |
|
let lastN = tagArea.closest('.image-item').querySelector('.lastN').textContent; |
|
let edit = []; |
|
for (let i=0, il=artistsData.length; i<il; i++) { |
|
let artist = artistsData[i]; |
|
if(artist[0] == lastN && artist[1] == firstN) { |
|
|
|
|
|
let oldTagsArr = artist[2].split('|'); |
|
for (let j=oldTagsArr.length-1; j>=0; j--) { |
|
|
|
if(oldTagsArr[j].match(/added-(\d|-)*/)) { |
|
newTagsArr.push(oldTagsArr[j]); |
|
} |
|
} |
|
let newTagsStr = newTagsArr.join('|'); |
|
artist[2] = newTagsStr; |
|
|
|
if(artistKnown) { |
|
artist[3] = false; |
|
} else { |
|
artist[3] = true; |
|
} |
|
edit = artist; |
|
break; |
|
} |
|
} |
|
|
|
for (let i=0, il=editedArtists.length; i<il; i++) { |
|
let oldEdit = editedArtists[i]; |
|
if(edit[0] == oldEdit[0] && edit[1] == oldEdit[1]) { |
|
editedArtists.delete(oldEdit); |
|
} |
|
} |
|
editedArtists.add(edit) |
|
|
|
localStorage.setItem('editedArtists', JSON.stringify(Array.from(editedArtists))); |
|
} |
|
|
|
function deleteAllEdits() { |
|
if(confirm('This will delete all of your edits. Are you sure?')) { |
|
localStorage.removeItem('editedArtists'); |
|
alert('official database restored! this page will reload...'); |
|
location.reload(); |
|
} else { |
|
alert('restore was cancelled!'); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
document.addEventListener("DOMContentLoaded", function() { |
|
|
|
|
|
startUp(); |
|
|
|
|
|
|
|
var checkboxes = document.querySelectorAll('input[type="checkbox"]'); |
|
checkboxes.forEach(function(checkbox) { |
|
let isTop = checkbox.parentNode.classList.contains('top_control'); |
|
if(!isTop || checkbox.name == 'favorite') { |
|
|
|
checkbox.addEventListener('change', function(e) { |
|
checkAllInCategory(e.target); |
|
hideAllArtists(); |
|
unhideBasedOnPermissiveSetting(); |
|
storeCheckboxState(e.target); |
|
updateArtistsCountPerTag('click'); |
|
}); |
|
} else { |
|
|
|
if(checkbox.name == 'check-all') { |
|
checkbox.addEventListener('change', function(e) { |
|
checkOrUncheckAll(this.checked); |
|
storeCheckboxStateAll(this.checked); |
|
hideAllArtists(); |
|
unhideBasedOnPermissiveSetting(); |
|
updateArtistsCountPerTag('click'); |
|
}); |
|
} else if(checkbox.name == 'mode') { |
|
checkbox.addEventListener('change', function(e) { |
|
hideAllArtists(); |
|
unhideBasedOnPermissiveSetting(); |
|
updateArtistsCountPerTag('click'); |
|
storeCheckboxState(e.target); |
|
}); |
|
} else if(checkbox.name == 'use_categories') { |
|
checkbox.addEventListener('change', function(e) { |
|
showHideCategories(); |
|
sortTags(); |
|
storeCheckboxState(e.target); |
|
}); |
|
} else if(checkbox.name == 'low_count') { |
|
checkbox.addEventListener('change', function(e) { |
|
showHideLowCountTags(); |
|
storeCheckboxState(e.target); |
|
}); |
|
} else if(checkbox.name == 'deprecated') { |
|
checkbox.addEventListener('change', function(e) { |
|
hideAllArtists(); |
|
unhideBasedOnPermissiveSetting(); |
|
updateArtistsCountPerTag('click'); |
|
storeCheckboxState(e.target); |
|
}); |
|
} |
|
} |
|
}); |
|
|
|
var infoI = document.getElementById('infoI'); |
|
infoI.addEventListener('click', function(e) { |
|
showInstructions(); |
|
}); |
|
var infoA = document.getElementById('infoA'); |
|
infoA.addEventListener('click', function(e) { |
|
showAbout(); |
|
}); |
|
var infoE = document.getElementById('infoX'); |
|
infoX.addEventListener('click', function(e) { |
|
showExport(); |
|
}); |
|
|
|
var promptA = document.getElementById('promptA'); |
|
promptA.addEventListener('click', function(e) { |
|
highlightSelectedOption('promptA'); |
|
rotatePromptsImages(); |
|
storeOptionsState(); |
|
}); |
|
var promptP = document.getElementById('promptP'); |
|
promptP.addEventListener('click', function(e) { |
|
highlightSelectedOption('promptP'); |
|
rotatePromptsImages(); |
|
storeOptionsState(); |
|
}); |
|
var promptL = document.getElementById('promptL'); |
|
promptL.addEventListener('click', function(e) { |
|
highlightSelectedOption('promptL'); |
|
rotatePromptsImages(); |
|
storeOptionsState(); |
|
}); |
|
|
|
var export_favorites = document.getElementById('export_favorites_button'); |
|
export_favorites.addEventListener('click', function(e) { |
|
exportTextarea('favorites'); |
|
}); |
|
var import_favorites = document.getElementById('import_favorites_button'); |
|
import_favorites.addEventListener('click', function(e) { |
|
importFavorites(); |
|
}); |
|
var export_edits = document.getElementById('export_edits_button'); |
|
export_edits.addEventListener('click', function(e) { |
|
exportTextarea('edits'); |
|
}); |
|
var delete_edits = document.getElementById('delete_edits_button'); |
|
delete_edits.addEventListener('click', function(e) { |
|
deleteAllEdits(); |
|
}); |
|
var export_artists = document.getElementById('export_artists_button'); |
|
export_artists.addEventListener('click', function(e) { |
|
exportTextarea('artists'); |
|
}); |
|
var information = document.querySelectorAll('.information'); |
|
information.forEach(function(element) { |
|
element.addEventListener('mouseleave', function(e) { |
|
if (!element.contains(e.relatedTarget)) { |
|
hideInformation(); |
|
} |
|
}); |
|
}); |
|
|
|
var sortTA = document.getElementById('sortTA'); |
|
sortTA.addEventListener('click', function(e) { |
|
sortTagsByAlpha(); |
|
highlightSelectedOption('sortTA'); |
|
storeOptionsState(); |
|
}); |
|
var sortTC = document.getElementById('sortTC'); |
|
sortTC.addEventListener('click', function(e) { |
|
sortTagsByCount(); |
|
highlightSelectedOption('sortTC'); |
|
storeOptionsState(); |
|
}); |
|
var sortAA = document.getElementById('sortAA'); |
|
sortAA.addEventListener('click', function(e) { |
|
sortArtistsByAlpha(); |
|
highlightSelectedOption('sortAA'); |
|
storeOptionsState(); |
|
}); |
|
var sortAR = document.getElementById('sortAR'); |
|
sortAR.addEventListener('click', function(e) { |
|
sortArtistsByRandom(); |
|
highlightSelectedOption('sortAR'); |
|
storeOptionsState(); |
|
}); |
|
|
|
var mostUsed = document.getElementById('edit_most_used'); |
|
mostUsed.addEventListener('click', function(e) { |
|
enterExitEditMostUsedMode(); |
|
}); |
|
document.addEventListener('keydown', function(event) { |
|
if (event.key === 'Escape' || event.keyCode === 27) { |
|
|
|
enterExitEditMostUsedMode('exit'); |
|
editTagsFindArtistInEditMode(); |
|
hideInformation(); |
|
} |
|
}); |
|
var labels = document.querySelectorAll('label'); |
|
Array.from(labels).forEach(function(label) { |
|
label.addEventListener('click', function(e) { |
|
if(editMostUsedMode) { |
|
addRemoveIsMostUsed(this); |
|
storeMostUsedState(this); |
|
} |
|
}); |
|
}); |
|
|
|
var imageItems = document.getElementsByClassName('image-item'); |
|
Array.from(imageItems).forEach(function(imageItem) { |
|
imageItem.addEventListener('mouseenter', function(e) { |
|
hideToggles(); |
|
loadLargerImages(e.target); |
|
timer = setTimeout(hideLargerImageBackup.bind(this, this), 200); |
|
}); |
|
imageItem.addEventListener('mouseleave', function(e) { |
|
showToggles(); |
|
}); |
|
imageItem.querySelector('.art_star').addEventListener('click', function(e) { |
|
addOrRemoveFavorite(this.closest('.image-item')); |
|
storeFavoriteState(this.closest('.image-item')); |
|
updateFavoritesCount(); |
|
}); |
|
imageItem.querySelector('.art_prev').addEventListener('click', function(e) { |
|
highlightSelectedOption('prev'); |
|
rotatePromptsImages(); |
|
storeOptionsState(); |
|
}); |
|
imageItem.querySelector('.art_next').addEventListener('click', function(e) { |
|
highlightSelectedOption('next'); |
|
rotatePromptsImages(); |
|
storeOptionsState(); |
|
}); |
|
imageItem.querySelector('.art_edit').addEventListener('click', function(e) { |
|
editTagsClicked(this.closest('.image-item')); |
|
}); |
|
imageItem.getElementsByTagName('h3')[0].addEventListener('click', function(e) { |
|
copyStuffToClipboard(this,'name'); |
|
}); |
|
imageItem.getElementsByTagName('h4')[0].addEventListener('click', function(e) { |
|
if(!this.classList.contains('edit_mode')) { |
|
copyStuffToClipboard(this, 'tags') |
|
|
|
} |
|
}); |
|
}); |
|
|
|
var gutter = document.getElementById('gutter'); |
|
gutter.addEventListener('mousedown', function(e) { |
|
e.preventDefault(); |
|
gutterStartPosX = this.offsetLeft; |
|
mouseStartPosX = e.pageX; |
|
this.addEventListener('mousemove', movePartition, false); |
|
window.addEventListener('mouseup', function() { |
|
gutter.removeEventListener('mousemove', movePartition, false); |
|
}, false); |
|
}, false); |
|
|
|
var closeFooter = document.getElementById('close_footer'); |
|
closeFooter.addEventListener('click', function(e) { |
|
document.getElementById('layout').classList.add('footerHidden'); |
|
}); |
|
}); |
|
|