Mattthew commited on
Commit
214046a
·
1 Parent(s): 02fb1eb

moving favorite tag to important, bug fixes

Browse files

was a pain and code is clunky, but needed to be done

artists_and_tags.js CHANGED
@@ -861,6 +861,7 @@ var artistsData = [
861
  ["Rubens","Peter Paul","baroque|Flemish|history|mythology|nudes|oil-painting|painting|renaissance|romanticism|added-2023-08-08",false],
862
  ["Ruysch","Rachel","baroque|painting|still-life|added-2023-08-16",false],
863
  ["Ryder","Albert Pinkham","dream-like|impressionism|painting|seascapes|added-2023-08-16",false],
 
864
  ["Rydingsvard","Ursula von","abstract|Metamorphosis|Minimalism|Sculpture|added-2023-08-08",false],
865
  ["Rysselberghe","Theo van","expressionism|impressionism|landscapes|portraits|added-2023-09-01",false],
866
  ["Saarinen","Eero","Architecture|metaphysics|modern|Modern|added-2023-08-08",false],
@@ -1329,7 +1330,7 @@ var artistsData = [
1329
  // first category must be 'important' and last must be 'other' or things won't work
1330
  // tag names cannot be 'image-item' or 'hidden' because well, this isn't coded that well, lol
1331
  var tagCategories = [
1332
- ['important'],
1333
  ['mediums',"3D-rendering","animation","architecture","assemblage","body-art","book-illustration","bronze","calligraphy","caricature","cartoon","ceiling-painting","ceramics","collage","comics","digital","drawing","earthworks","enamel","engraving","etching","experiential","film","frescoes","glasswork","graffiti","graphic-design","graphic-novel","illuminated-manuscripts","illustration","immersive","metalwork","infinity-rooms","installation","interactive","jewelry","kinetic","land-art","landscape-architecture","light-art","lithography","manga-anime","mixed-media","montage","mosaic","multimedia","mural-painting","newspaper","oil-painting","painting","pastel","pen-and-ink","performance","photography","photography-color","photography-bw","posters","printmaking","public-art","puppets","quilting","recycled-materials","sculpture","sketching","stained-glass","street-art","tapestry","textiles","typography","velvet","video-art","video-games","virtual-reality","wall-drawings","watercolor","woodblock"],
1334
  ['styles',"abstract","action-painting","afro-futurism","angular","anthropomorphism","atmospheric","blurry","bohemian","bold-colors","color-field","colorful","cute","cyberpunk","dark","delicate","drip-painting","eerie","elegant","ethereal","figurative","flat-colors","folk-art","fragmentation","futuristic","geometric","gestural","golden","gothic","grids","grungy","high-contrast","illusion","impasto","improvisation","industrial","kids-book","large-scale","long-exposure","low-contrast","opulent","macro-world","Maximalism","melancholy","messy","miniature","monochromatic","muted-colors","mysterious","naturalist","neon","noir","observational","organic","ornate","pastel-colors","photorealism","pin-up","playful","polka-dots","precisionism","primary-colors","propaganda","psychedelic","pulp","Rococo","shallow-depth-of-field","steampunk","symbolist","text-based","vibrant","whimsical"],
1335
  ['themes',"activism","adventure","advertising","allegory","anxiety","autobiographical","childhood","commercial-art","conceptual","consumerism","controversy","death","displacement","distortion","documentary","dream-like","dreams","dystopia","empowerment","environmentalism","exoticism","family","fantasy","femininity","feminism","fleeting-moments","folklore","friendship","futurism","homo-eroticism","horror","identity","kitsch","loneliness","luxury","magic","mathematics","metamorphosis","metaphysics","mysticism","nightlife","nostalgia","observational","plein-air","politics","punk","religion","satire","science-fiction","serenity","slice-of-life","social-commentary","solitude","spirituality","surreal","utopia"],
 
861
  ["Rubens","Peter Paul","baroque|Flemish|history|mythology|nudes|oil-painting|painting|renaissance|romanticism|added-2023-08-08",false],
862
  ["Ruysch","Rachel","baroque|painting|still-life|added-2023-08-16",false],
863
  ["Ryder","Albert Pinkham","dream-like|impressionism|painting|seascapes|added-2023-08-16",false],
864
+ ["Ryden","Mark","big-eyes|childhood|contemporary|creatures|dark|dream-like|illustration|surreal|added-2023-09-01",false],
865
  ["Rydingsvard","Ursula von","abstract|Metamorphosis|Minimalism|Sculpture|added-2023-08-08",false],
866
  ["Rysselberghe","Theo van","expressionism|impressionism|landscapes|portraits|added-2023-09-01",false],
867
  ["Saarinen","Eero","Architecture|metaphysics|modern|Modern|added-2023-08-08",false],
 
1330
  // first category must be 'important' and last must be 'other' or things won't work
1331
  // tag names cannot be 'image-item' or 'hidden' because well, this isn't coded that well, lol
1332
  var tagCategories = [
1333
+ ['important',"favorite"],
1334
  ['mediums',"3D-rendering","animation","architecture","assemblage","body-art","book-illustration","bronze","calligraphy","caricature","cartoon","ceiling-painting","ceramics","collage","comics","digital","drawing","earthworks","enamel","engraving","etching","experiential","film","frescoes","glasswork","graffiti","graphic-design","graphic-novel","illuminated-manuscripts","illustration","immersive","metalwork","infinity-rooms","installation","interactive","jewelry","kinetic","land-art","landscape-architecture","light-art","lithography","manga-anime","mixed-media","montage","mosaic","multimedia","mural-painting","newspaper","oil-painting","painting","pastel","pen-and-ink","performance","photography","photography-color","photography-bw","posters","printmaking","public-art","puppets","quilting","recycled-materials","sculpture","sketching","stained-glass","street-art","tapestry","textiles","typography","velvet","video-art","video-games","virtual-reality","wall-drawings","watercolor","woodblock"],
1335
  ['styles',"abstract","action-painting","afro-futurism","angular","anthropomorphism","atmospheric","blurry","bohemian","bold-colors","color-field","colorful","cute","cyberpunk","dark","delicate","drip-painting","eerie","elegant","ethereal","figurative","flat-colors","folk-art","fragmentation","futuristic","geometric","gestural","golden","gothic","grids","grungy","high-contrast","illusion","impasto","improvisation","industrial","kids-book","large-scale","long-exposure","low-contrast","opulent","macro-world","Maximalism","melancholy","messy","miniature","monochromatic","muted-colors","mysterious","naturalist","neon","noir","observational","organic","ornate","pastel-colors","photorealism","pin-up","playful","polka-dots","precisionism","primary-colors","propaganda","psychedelic","pulp","Rococo","shallow-depth-of-field","steampunk","symbolist","text-based","vibrant","whimsical"],
1336
  ['themes',"activism","adventure","advertising","allegory","anxiety","autobiographical","childhood","commercial-art","conceptual","consumerism","controversy","death","displacement","distortion","documentary","dream-like","dreams","dystopia","empowerment","environmentalism","exoticism","family","fantasy","femininity","feminism","fleeting-moments","folklore","friendship","futurism","homo-eroticism","horror","identity","kitsch","loneliness","luxury","magic","mathematics","metamorphosis","metaphysics","mysticism","nightlife","nostalgia","observational","plein-air","politics","punk","religion","satire","science-fiction","serenity","slice-of-life","social-commentary","solitude","spirituality","surreal","utopia"],
images/SDXL_1_0/Mark_Ryden-artwork.webp ADDED
images/SDXL_1_0/Mark_Ryden-landscape.webp ADDED
images/SDXL_1_0/Mark_Ryden-portrait.webp ADDED
images/SDXL_1_0_thumbs/Mark_Ryden-artwork.webp ADDED
images/SDXL_1_0_thumbs/Mark_Ryden-landscape.webp ADDED
images/SDXL_1_0_thumbs/Mark_Ryden-portrait.webp ADDED
index.css CHANGED
@@ -1012,7 +1012,7 @@ input[type="checkbox"]:checked::before {
1012
  color: #ffe300;
1013
  opacity: 0.8;
1014
  cursor: pointer;
1015
- margin: 5px 0 0 21px;
1016
  }
1017
 
1018
  #edit_most_used:hover {
@@ -1069,3 +1069,7 @@ input[type="checkbox"]:checked::before {
1069
  #layout.edit_mode #toggles .most_used_indicator {
1070
  visibility: visible;
1071
  }
 
 
 
 
 
1012
  color: #ffe300;
1013
  opacity: 0.8;
1014
  cursor: pointer;
1015
+ margin: 2px 0 10px 27px;
1016
  }
1017
 
1018
  #edit_most_used:hover {
 
1069
  #layout.edit_mode #toggles .most_used_indicator {
1070
  visibility: visible;
1071
  }
1072
+
1073
+ #layout.edit_mode #favorite_label {
1074
+ cursor: default;
1075
+ }
index.html CHANGED
@@ -53,11 +53,8 @@
53
  <label class="top_control">
54
  <input type="checkbox" checked="checked" name="deprecated" value="deprecated" autocomplete="off"><span>hide unknown to SDXL</span><span class="count"></span>
55
  </label>
56
- <label class="top_control">
57
- <input type="checkbox" checked="checked" name="favorite" value="favorite" autocomplete="off"><span>favorited</span><span class="count"></span>
58
- </label>
59
  <div class="divider"></div>
60
- <span id="edit_most_used" class="hidden">edit</span>
61
  <!-- JS will insert checkboxes here -->
62
  </div>
63
  <div id="gutter">
 
53
  <label class="top_control">
54
  <input type="checkbox" checked="checked" name="deprecated" value="deprecated" autocomplete="off"><span>hide unknown to SDXL</span><span class="count"></span>
55
  </label>
 
 
 
56
  <div class="divider"></div>
57
+ <span id="edit_most_used" class="hidden">edit these</span>
58
  <!-- JS will insert checkboxes here -->
59
  </div>
60
  <div id="gutter">
index.js CHANGED
@@ -45,9 +45,9 @@ async function startUp() {
45
  unhideBasedOnPermissiveSetting();
46
  updateArtistsCountPerTag('start');
47
  rotatePromptsImages();
 
48
  sortArtists();
49
  sortTags();
50
- await loadMostUsedTags();
51
  updateArtistsCountPerCategory();
52
  showHideLowCountTags();
53
  makeStyleRuleForDrag();
@@ -401,6 +401,8 @@ function insertCheckboxesFromArtistsData() {
401
  uniqueTags.add(tag.toLowerCase());
402
  });
403
  });
 
 
404
  var uTags = Array.from(uniqueTags);
405
  var toggles = document.getElementById('toggles');
406
  for(i=0,il=uTags.length;i<il;i++) {
@@ -426,6 +428,8 @@ function insertCheckboxesFromArtistsData() {
426
  toggles.appendChild(label);
427
  }
428
  }
 
 
429
  }
430
 
431
  function insertCheckboxesFromCategories() {
@@ -454,9 +458,10 @@ async function loadCheckboxesState() {
454
  await loadItemBasedOnAccessType('tagsChecked').then(state => {
455
  let allChecked = true;
456
  for (let name in state) {
457
- if (document.querySelector('input[name="'+name+'"]')) {
458
- document.querySelector('input[name="'+name+'"]').checked = state[name];
459
- styleLabelToCheckbox(document.querySelector('input[name="'+name+'"]'));
 
460
  if(name != 'mode' && name != 'use_categories') {
461
  if(!state[name]) {
462
  allChecked = false;
@@ -645,33 +650,36 @@ function updateArtistsCountPerTagSlow() {
645
  let deprecatedDivs = document.querySelectorAll('.image-item[data-deprecated="true"]');
646
  let last = performance.now();
647
  checkboxes.forEach(function(checkbox) {
648
- let isTop = checkbox.parentNode.classList.contains('top_control');
649
- if(!isTop) {
650
- let matchingDivs;
651
- if(isPermissive) {
652
- matchingDivs = document.querySelectorAll('.image-item[data-tag-list*="' + checkbox.name + '"]');
653
- } else {
654
- // for strict mode, for each checkbox, only count artists with a tags matching all checked checkboxes
655
- matchingDivs = document.querySelectorAll('.image-item[data-tag-list*="' + checkbox.name + '"]:not(.hidden)');
656
- }
657
- let filteredDivs = Array.from(matchingDivs).filter(mat => {
658
- // only includes the artists known to SD
659
- return !Array.from(deprecatedDivs).some(dep => dep === mat);
660
- });
661
- let count = 0;
662
- if(deprecatedCheckbox.checked) {
663
- count = filteredDivs.length;
664
- } else {
665
- count = matchingDivs.length;
666
- }
667
- if(!count) { count = 0; }
668
- checkbox.parentNode.querySelector('.count').textContent = ' - ' + count.toLocaleString();
669
- checkbox.parentNode.classList.remove('no_matches');
670
- checkbox.parentNode.querySelector('input').disabled = false;
671
- if(!isPermissive) {
672
- if(count == 0) {
673
- checkbox.parentNode.classList.add('no_matches');
674
- checkbox.parentNode.querySelector('input').disabled = true;
 
 
 
675
  }
676
  }
677
  }
@@ -696,10 +704,16 @@ function updateArtistsCountPerCategory() {
696
  }
697
  countItems.forEach(function(imageItem) {
698
  let tagList = imageItem.dataset.tagList.split('|');
 
699
  for(i=0,il=tagCategories.length; i<il; i++) {
700
  if(tagCategories[i].map(tag => tag.toLowerCase()).some(tag => tagList.includes(tag))) {
701
  counts[i]++;
702
  }
 
 
 
 
 
703
  }
704
  });
705
  for(i=0,il=tagCategories.length; i<il; i++) {
@@ -1238,6 +1252,17 @@ function sortTagsByAlpha() {
1238
  labels.forEach(function(label) {
1239
  let isTop = label.classList.contains('top_control');
1240
  if(!isTop) {
 
 
 
 
 
 
 
 
 
 
 
1241
  // appendChild will move the element to the end of the container
1242
  container.appendChild(label);
1243
  }
@@ -1262,7 +1287,7 @@ function sortTagsByAlpha() {
1262
  arrayOfTagsLower.sort();
1263
  arrayOfTagsLower.forEach(tag => {
1264
  let label = labelMap[tag];
1265
- if (label) {
1266
  let isTop = label.classList.contains('top_control');
1267
  if(!isTop) {
1268
  label.dataset.isInCategory = categoryLabel.dataset.categoryName;
@@ -1287,6 +1312,10 @@ function sortTagsByAlpha() {
1287
  container.appendChild(label);
1288
  }
1289
  });
 
 
 
 
1290
  }
1291
  }
1292
 
@@ -1303,6 +1332,17 @@ function sortTagsByCount() {
1303
  labels.forEach(function(label) {
1304
  let isTop = label.classList.contains('top_control');
1305
  if(!isTop) {
 
 
 
 
 
 
 
 
 
 
 
1306
  // appendChild will move the element to the end of the container
1307
  container.appendChild(label);
1308
  }
@@ -1377,14 +1417,19 @@ function sortTagsByCount() {
1377
  container.appendChild(label);
1378
  }
1379
  });
 
 
 
 
1380
  }
1381
  }
1382
 
1383
  async function loadMostUsedTags() {
 
1384
  await loadItemBasedOnAccessType('mustUsedTags').then(state => {
1385
  let mostUsedCategory = document.querySelector('[data-category-name="important"]');
1386
  for(let tag in state) {
1387
- if (state[tag]) {
1388
  let label = document.querySelector('input[name="'+ tag +'"]');
1389
  if(label) {
1390
  label = label.parentNode;
@@ -1395,6 +1440,11 @@ async function loadMostUsedTags() {
1395
  }
1396
  }
1397
  }
 
 
 
 
 
1398
  });
1399
  }
1400
 
@@ -1439,7 +1489,7 @@ function enterExitEditMostUsedMode(doExit) {
1439
  if(editMostUsedMode || doExit) {
1440
  // exit edit mode
1441
  editMostUsedMode = false;
1442
- document.getElementById('edit_most_used').textContent = 'edit';
1443
  document.getElementById('layout').classList.remove('edit_mode');
1444
  inputs.forEach(function(input) {
1445
  input.disabled = false;
@@ -1448,11 +1498,12 @@ function enterExitEditMostUsedMode(doExit) {
1448
  labels.forEach(function(label) {
1449
  // clean up classes added to track moved tags during edit mode
1450
  label.classList.remove('was_moved');
1451
- })
1452
  document.getElementById('toggles').style.width = 'calc(' + gutterEndPercentX + '% - 20px)';
1453
  document.getElementById('gutter').style.left = gutterEndPercentX + '%';
1454
  document.getElementById('image-container').style.marginLeft = 'calc(' + gutterEndPercentX + '% + 50px)';
1455
  updateArtistsCountPerCategory();
 
1456
  } else {
1457
  // enter edit mode
1458
  editMostUsedMode = true;
@@ -1568,7 +1619,7 @@ function storeFavoriteState(artist) {
1568
  function updateFavoritesCount() {
1569
  var favoritedArtists = document.getElementsByClassName('favorite');
1570
  var favoriteCount = favoritedArtists.length;
1571
- var favoriteCounter = document.querySelectorAll('input[name="favorite"]')[0].parentNode.querySelector('.count');
1572
  favoriteCounter.textContent = ' - ' + favoriteCount;
1573
  }
1574
 
@@ -2338,12 +2389,16 @@ function addAllListeners() {
2338
  });
2339
  var labels = document.querySelectorAll('label');
2340
  Array.from(labels).forEach(function(label) {
2341
- label.addEventListener('click', function(e) {
2342
- if(editMostUsedMode) {
2343
- addRemoveIsMostUsed(this);
2344
- storeMostUsedState(this);
2345
- }
2346
- });
 
 
 
 
2347
  });
2348
  // artists
2349
  var imageItems = document.getElementsByClassName('image-item');
 
45
  unhideBasedOnPermissiveSetting();
46
  updateArtistsCountPerTag('start');
47
  rotatePromptsImages();
48
+ await loadMostUsedTags();
49
  sortArtists();
50
  sortTags();
 
51
  updateArtistsCountPerCategory();
52
  showHideLowCountTags();
53
  makeStyleRuleForDrag();
 
401
  uniqueTags.add(tag.toLowerCase());
402
  });
403
  });
404
+ // favorite isn't an artist tag so has to be added
405
+ uniqueTags.add('favorite');
406
  var uTags = Array.from(uniqueTags);
407
  var toggles = document.getElementById('toggles');
408
  for(i=0,il=uTags.length;i<il;i++) {
 
428
  toggles.appendChild(label);
429
  }
430
  }
431
+ // so it can be referenced by CSS
432
+ document.querySelector('input[name="favorite"').parentNode.id = "favorite_label";
433
  }
434
 
435
  function insertCheckboxesFromCategories() {
 
458
  await loadItemBasedOnAccessType('tagsChecked').then(state => {
459
  let allChecked = true;
460
  for (let name in state) {
461
+ let checkbox = document.querySelector('input[name="'+name+'"]');
462
+ if (checkbox) {
463
+ checkbox.checked = state[name];
464
+ styleLabelToCheckbox(checkbox);
465
  if(name != 'mode' && name != 'use_categories') {
466
  if(!state[name]) {
467
  allChecked = false;
 
650
  let deprecatedDivs = document.querySelectorAll('.image-item[data-deprecated="true"]');
651
  let last = performance.now();
652
  checkboxes.forEach(function(checkbox) {
653
+ // 'favorite' count is updated elsewhere
654
+ if(checkbox.name != 'favorite') {
655
+ // top controls aren't tags and don't have counts
656
+ if(!checkbox.parentNode.classList.contains('top_control')) {
657
+ let matchingDivs;
658
+ if(isPermissive) {
659
+ matchingDivs = document.querySelectorAll('.image-item[data-tag-list*="' + checkbox.name + '"]');
660
+ } else {
661
+ // for strict mode, for each checkbox, only count artists with a tags matching all checked checkboxes
662
+ matchingDivs = document.querySelectorAll('.image-item[data-tag-list*="' + checkbox.name + '"]:not(.hidden)');
663
+ }
664
+ let filteredDivs = Array.from(matchingDivs).filter(mat => {
665
+ // only includes the artists known to SD
666
+ return !Array.from(deprecatedDivs).some(dep => dep === mat);
667
+ });
668
+ let count = 0;
669
+ if(deprecatedCheckbox.checked) {
670
+ count = filteredDivs.length;
671
+ } else {
672
+ count = matchingDivs.length;
673
+ }
674
+ if(!count) { count = 0; }
675
+ checkbox.parentNode.querySelector('.count').textContent = ' - ' + count.toLocaleString();
676
+ checkbox.parentNode.classList.remove('no_matches');
677
+ checkbox.parentNode.querySelector('input').disabled = false;
678
+ if(!isPermissive) {
679
+ if(count == 0) {
680
+ checkbox.parentNode.classList.add('no_matches');
681
+ checkbox.parentNode.querySelector('input').disabled = true;
682
+ }
683
  }
684
  }
685
  }
 
704
  }
705
  countItems.forEach(function(imageItem) {
706
  let tagList = imageItem.dataset.tagList.split('|');
707
+ let isFavorited = imageItem.classList.contains('favorite');
708
  for(i=0,il=tagCategories.length; i<il; i++) {
709
  if(tagCategories[i].map(tag => tag.toLowerCase()).some(tag => tagList.includes(tag))) {
710
  counts[i]++;
711
  }
712
+ if(tagCategories[i][0] == 'important') {
713
+ if(isFavorited) {
714
+ counts[i]++;
715
+ }
716
+ }
717
  }
718
  });
719
  for(i=0,il=tagCategories.length; i<il; i++) {
 
1252
  labels.forEach(function(label) {
1253
  let isTop = label.classList.contains('top_control');
1254
  if(!isTop) {
1255
+ // appendChild will move the element to the end of the container
1256
+ // "favorite" tag always stays at top
1257
+ if(label.querySelector('input').name != 'favorite') {
1258
+ container.appendChild(label);
1259
+ }
1260
+ }
1261
+ });
1262
+ // "added" tags always goes to bottom
1263
+ labels.forEach(function(label) {
1264
+ let name = label.querySelector('input').name;
1265
+ if(name.indexOf('added-') > -1) {
1266
  // appendChild will move the element to the end of the container
1267
  container.appendChild(label);
1268
  }
 
1287
  arrayOfTagsLower.sort();
1288
  arrayOfTagsLower.forEach(tag => {
1289
  let label = labelMap[tag];
1290
+ if(label) {
1291
  let isTop = label.classList.contains('top_control');
1292
  if(!isTop) {
1293
  label.dataset.isInCategory = categoryLabel.dataset.categoryName;
 
1312
  container.appendChild(label);
1313
  }
1314
  });
1315
+ // favorite always goes to top of important category
1316
+ let importantCategory = document.querySelector('label[data-category-name="important"]');
1317
+ let favoriteLabel = document.getElementById('favorite_label');
1318
+ importantCategory.after(favoriteLabel);
1319
  }
1320
  }
1321
 
 
1332
  labels.forEach(function(label) {
1333
  let isTop = label.classList.contains('top_control');
1334
  if(!isTop) {
1335
+ // appendChild will move the element to the end of the container
1336
+ // "favorite" tag always stays at top
1337
+ if(label.querySelector('input').name != 'favorite') {
1338
+ container.appendChild(label);
1339
+ }
1340
+ }
1341
+ });
1342
+ // "added" tags always goes to bottom
1343
+ labels.forEach(function(label) {
1344
+ let name = label.querySelector('input').name;
1345
+ if(name.indexOf('added-') > -1) {
1346
  // appendChild will move the element to the end of the container
1347
  container.appendChild(label);
1348
  }
 
1417
  container.appendChild(label);
1418
  }
1419
  });
1420
+ // favorite always goes to top of important category
1421
+ let importantCategory = document.querySelector('label[data-category-name="important"]');
1422
+ let favoriteLabel = document.getElementById('favorite_label');
1423
+ importantCategory.after(favoriteLabel);
1424
  }
1425
  }
1426
 
1427
  async function loadMostUsedTags() {
1428
+ // aka the important category
1429
  await loadItemBasedOnAccessType('mustUsedTags').then(state => {
1430
  let mostUsedCategory = document.querySelector('[data-category-name="important"]');
1431
  for(let tag in state) {
1432
+ if(state[tag]) {
1433
  let label = document.querySelector('input[name="'+ tag +'"]');
1434
  if(label) {
1435
  label = label.parentNode;
 
1440
  }
1441
  }
1442
  }
1443
+ // favorite is always most used
1444
+ let favoriteLabel = document.getElementById('favorite_label');
1445
+ favoriteLabel.classList.add('is_most_used');
1446
+ favoriteLabel.querySelectorAll('.most_used_indicator')[0].textContent = '';
1447
+ updateTagArrayToMatchMostUsed(true,favoriteLabel,'favorite');
1448
  });
1449
  }
1450
 
 
1489
  if(editMostUsedMode || doExit) {
1490
  // exit edit mode
1491
  editMostUsedMode = false;
1492
+ document.getElementById('edit_most_used').textContent = 'edit these';
1493
  document.getElementById('layout').classList.remove('edit_mode');
1494
  inputs.forEach(function(input) {
1495
  input.disabled = false;
 
1498
  labels.forEach(function(label) {
1499
  // clean up classes added to track moved tags during edit mode
1500
  label.classList.remove('was_moved');
1501
+ });
1502
  document.getElementById('toggles').style.width = 'calc(' + gutterEndPercentX + '% - 20px)';
1503
  document.getElementById('gutter').style.left = gutterEndPercentX + '%';
1504
  document.getElementById('image-container').style.marginLeft = 'calc(' + gutterEndPercentX + '% + 50px)';
1505
  updateArtistsCountPerCategory();
1506
+ sortTags();
1507
  } else {
1508
  // enter edit mode
1509
  editMostUsedMode = true;
 
1619
  function updateFavoritesCount() {
1620
  var favoritedArtists = document.getElementsByClassName('favorite');
1621
  var favoriteCount = favoritedArtists.length;
1622
+ var favoriteCounter = document.getElementById('favorite_label').querySelector('.count');
1623
  favoriteCounter.textContent = ' - ' + favoriteCount;
1624
  }
1625
 
 
2389
  });
2390
  var labels = document.querySelectorAll('label');
2391
  Array.from(labels).forEach(function(label) {
2392
+ let name = label.querySelector('input').name;
2393
+ if(name != 'favorite') {
2394
+ // favorite can't be removed from most used
2395
+ label.addEventListener('click', function(e) {
2396
+ if(editMostUsedMode) {
2397
+ addRemoveIsMostUsed(this);
2398
+ storeMostUsedState(this);
2399
+ }
2400
+ });
2401
+ }
2402
  });
2403
  // artists
2404
  var imageItems = document.getElementsByClassName('image-item');