baqu2213 commited on
Commit
2aa7a86
·
verified ·
1 Parent(s): 244c0fa

Upload 5 files

Browse files
ui/components/generation_panel.py CHANGED
@@ -8,10 +8,12 @@ import gradio as gr
8
  from utils.constants import (
9
  MODEL_CHOICES,
10
  SAMPLER_CHOICES,
 
11
  DEFAULT_MODEL,
12
  DEFAULT_STEPS,
13
  DEFAULT_SCALE,
14
- DEFAULT_SAMPLER
 
15
  )
16
 
17
 
@@ -21,7 +23,7 @@ def create_generation_panel():
21
 
22
  Returns:
23
  Dict with control components:
24
- - model, steps, scale, cfg_rescale, sampler, seed
25
  Note: Resolution is now in the Prompt header, not here
26
  """
27
  with gr.Group():
@@ -71,6 +73,21 @@ def create_generation_panel():
71
  elem_id="naia-sampler"
72
  )
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  # Seed row
75
  seed = gr.Number(
76
  value=0,
@@ -87,5 +104,7 @@ def create_generation_panel():
87
  "scale": scale,
88
  "cfg_rescale": cfg_rescale,
89
  "sampler": sampler,
 
 
90
  "seed": seed
91
  }
 
8
  from utils.constants import (
9
  MODEL_CHOICES,
10
  SAMPLER_CHOICES,
11
+ NOISE_SCHEDULE_CHOICES,
12
  DEFAULT_MODEL,
13
  DEFAULT_STEPS,
14
  DEFAULT_SCALE,
15
+ DEFAULT_SAMPLER,
16
+ DEFAULT_NOISE_SCHEDULE
17
  )
18
 
19
 
 
23
 
24
  Returns:
25
  Dict with control components:
26
+ - model, steps, scale, cfg_rescale, sampler, noise_schedule, variety_plus, seed
27
  Note: Resolution is now in the Prompt header, not here
28
  """
29
  with gr.Group():
 
73
  elem_id="naia-sampler"
74
  )
75
 
76
+ # Noise Schedule and VAR+ row
77
+ with gr.Row():
78
+ noise_schedule = gr.Dropdown(
79
+ choices=NOISE_SCHEDULE_CHOICES,
80
+ value=DEFAULT_NOISE_SCHEDULE,
81
+ label="Noise Schedule",
82
+ elem_id="naia-noise-schedule"
83
+ )
84
+
85
+ variety_plus = gr.Checkbox(
86
+ value=False,
87
+ label="VAR+",
88
+ elem_id="naia-variety-plus"
89
+ )
90
+
91
  # Seed row
92
  seed = gr.Number(
93
  value=0,
 
104
  "scale": scale,
105
  "cfg_rescale": cfg_rescale,
106
  "sampler": sampler,
107
+ "noise_schedule": noise_schedule,
108
+ "variety_plus": variety_plus,
109
  "seed": seed
110
  }
ui/components/output_panel.py CHANGED
@@ -71,6 +71,13 @@ def create_generation_info_panel():
71
  elem_id="naia-processed-negative"
72
  )
73
 
 
 
 
 
 
 
 
74
  return {
75
  "info": output_info,
76
  "processed_prompt": processed_prompt,
 
71
  elem_id="naia-processed-negative"
72
  )
73
 
74
+ # Useful external links
75
+ gr.Markdown("""
76
+ * If you need parameters inspection, visit: [novelai.net/inspect](https://novelai.net/inspect)
77
+ * If you need tags wiki, visit: [danbooru.donmai.us/wiki_pages/tag_groups](https://danbooru.donmai.us/wiki_pages/tag_groups)
78
+ * If you need image to danbooru tags, visit: [SmilingWolf/wd-tagger](https://huggingface.co/spaces/SmilingWolf/wd-tagger)
79
+ """, elem_id="naia-gen-info-links")
80
+
81
  return {
82
  "info": output_info,
83
  "processed_prompt": processed_prompt,
ui/components/quick_search.py CHANGED
@@ -87,7 +87,7 @@ def create_quick_search():
87
  recommended_tags = gr.Dataframe(
88
  headers=["Tag", "Count", "+", "-"],
89
  datatype=["str", "number", "str", "str"],
90
- col_count=(4, "fixed"),
91
  row_count=(10, "dynamic"),
92
  interactive=False,
93
  wrap=True,
 
87
  recommended_tags = gr.Dataframe(
88
  headers=["Tag", "Count", "+", "-"],
89
  datatype=["str", "number", "str", "str"],
90
+ column_count=(4, "fixed"),
91
  row_count=(10, "dynamic"),
92
  interactive=False,
93
  wrap=True,
ui/components/settings_panel.py CHANGED
@@ -178,7 +178,6 @@ LOCALSTORAGE_JS = """
178
  if (generateStartTime) {
179
  const elapsed = (Date.now() - generateStartTime) / 1000;
180
  addResponseTime(elapsed);
181
- console.log('NAIA-WEB: Response time:', elapsed.toFixed(2), 's, Average:', getAverageResponseTime().toFixed(2), 's');
182
  }
183
 
184
  if (timerInterval) {
@@ -203,11 +202,13 @@ LOCALSTORAGE_JS = """
203
  const autoSaveContainer = document.querySelector('#naia-auto-save');
204
  const autoSaveCheckbox = autoSaveContainer ? autoSaveContainer.querySelector('input[type="checkbox"]') : null;
205
  if (autoSaveCheckbox && autoSaveCheckbox.checked) {
206
- // Small delay to ensure image is fully loaded
207
- setTimeout(() => {
 
 
 
208
  downloadBtn.click();
209
- console.log('NAIA-WEB: Auto Save triggered download');
210
- }, 500);
211
  }
212
  }
213
  }
@@ -264,7 +265,6 @@ LOCALSTORAGE_JS = """
264
  input.value = savedToken;
265
  input.dispatchEvent(new Event('input', { bubbles: true }));
266
  input.dispatchEvent(new Event('change', { bubbles: true }));
267
- console.log('NAIA-WEB: Token loaded from localStorage');
268
  }
269
  } catch (e) {
270
  console.error('NAIA-WEB: Error loading token:', e);
@@ -387,6 +387,8 @@ LOCALSTORAGE_JS = """
387
  scale: toFloat(getInputValue('#naia-scale')),
388
  cfg_rescale: toFloat(getInputValue('#naia-cfg-rescale')),
389
  sampler: getInputValue('#naia-sampler'),
 
 
390
  // Random resolution
391
  random_resolution: getInputValue('#naia-random-resolution', 'checkbox'),
392
  enabled_resolutions: getCheckboxGroupValues('#naia-res-checkboxes'),
@@ -417,10 +419,6 @@ LOCALSTORAGE_JS = """
417
 
418
  try {
419
  localStorage.setItem(SETTINGS_KEY, JSON.stringify(settings));
420
- console.log('NAIA-WEB: Settings saved', settings.char_slots ? `(${settings.char_slots.length} char slots)` : '(no char slots)');
421
- if (settings.char_slots && settings.char_slots.length > 0) {
422
- console.log('NAIA-WEB: Saved char slots:', JSON.stringify(settings.char_slots));
423
- }
424
  } catch (e) {
425
  console.error('NAIA-WEB: Error saving settings:', e);
426
  }
@@ -481,7 +479,6 @@ LOCALSTORAGE_JS = """
481
  renderFromCache() {
482
  const grid = document.getElementById('naia-qs-tag-grid');
483
  if (!grid) {
484
- console.log('NAIA-WEB QuickSearch: Grid not ready, will render when accordion opens');
485
  return;
486
  }
487
 
@@ -510,7 +507,6 @@ LOCALSTORAGE_JS = """
510
  }
511
 
512
  this.updatePageInfo();
513
- console.log(`NAIA-WEB QuickSearch: Rendered page ${this.currentPage}/${this.totalPages} (${this.currentTags.length} tags)`);
514
  },
515
 
516
  // Show popup to choose Include or Exclude (positioned above grid)
@@ -582,7 +578,6 @@ LOCALSTORAGE_JS = """
582
  actionInput.value = `${action}:${tag}`;
583
  actionInput.dispatchEvent(new Event('input', { bubbles: true }));
584
  actionInput.dispatchEvent(new Event('change', { bubbles: true }));
585
- console.log(`NAIA-WEB QuickSearch: Tag action ${action}:${tag}`);
586
  }
587
  },
588
 
@@ -610,16 +605,11 @@ LOCALSTORAGE_JS = """
610
  }
611
 
612
  // Add click listener - just try to render after click
613
- // renderWithRetry will handle checking if grid exists
614
  button.addEventListener('click', () => {
615
- console.log('NAIA-WEB QuickSearch: Accordion clicked');
616
  if (self.dataReady) {
617
- // Try to render with retries (accordion might need time to expand)
618
  self.renderWithRetry(5);
619
  }
620
  });
621
-
622
- console.log('NAIA-WEB QuickSearch: Click listener set up on accordion');
623
  };
624
 
625
  checkAccordion();
@@ -688,16 +678,10 @@ LOCALSTORAGE_JS = """
688
 
689
  // Initialize autocomplete on all target textareas
690
  init() {
691
- console.log('NAIA-WEB Autocomplete: Starting initialization...');
692
  this.createDropdown();
693
- console.log('NAIA-WEB Autocomplete: Dropdown created');
694
- // Debug: show all textareas on page
695
- this.debugListTextareas();
696
  this.attachToTargets();
697
- console.log('NAIA-WEB Autocomplete: Attached to targets');
698
  // Re-attach when new elements appear (for dynamic char slots)
699
  this.setupMutationObserver();
700
- console.log('NAIA-WEB Autocomplete: Initialized successfully');
701
  },
702
 
703
  // Create the dropdown element
@@ -736,9 +720,6 @@ LOCALSTORAGE_JS = """
736
  return container.querySelector('textarea');
737
  },
738
 
739
- // Track which IDs we've already reported as not found (to reduce log spam)
740
- _notFoundReported: new Set(),
741
-
742
  // Attach to all target textareas
743
  attachToTargets() {
744
  let attachedCount = 0;
@@ -748,11 +729,6 @@ LOCALSTORAGE_JS = """
748
  if (textarea && !textarea.dataset.autocompleteAttached) {
749
  this.attachToTextarea(textarea);
750
  attachedCount++;
751
- console.log('NAIA-WEB Autocomplete: Attached to #' + containerId);
752
- this._notFoundReported.delete(containerId);
753
- } else if (!textarea && !this._notFoundReported.has(containerId)) {
754
- // Only log "not found" once per ID
755
- this._notFoundReported.add(containerId);
756
  }
757
  }
758
 
@@ -763,12 +739,10 @@ LOCALSTORAGE_JS = """
763
  if (promptTextarea && !promptTextarea.dataset.autocompleteAttached) {
764
  this.attachToTextarea(promptTextarea);
765
  attachedCount++;
766
- console.log('NAIA-WEB Autocomplete: Attached to #naia-char-prompt-' + i);
767
  }
768
  if (negativeTextarea && !negativeTextarea.dataset.autocompleteAttached) {
769
  this.attachToTextarea(negativeTextarea);
770
  attachedCount++;
771
- console.log('NAIA-WEB Autocomplete: Attached to #naia-char-negative-' + i);
772
  }
773
  }
774
 
@@ -777,11 +751,6 @@ LOCALSTORAGE_JS = """
777
  if (charSearchTextarea && !charSearchTextarea.dataset.autocompleteAttached) {
778
  this.attachToTextarea(charSearchTextarea);
779
  attachedCount++;
780
- console.log('NAIA-WEB Autocomplete: Attached to character search input');
781
- }
782
-
783
- if (attachedCount > 0) {
784
- console.log('NAIA-WEB Autocomplete: Total attached:', attachedCount);
785
  }
786
  },
787
 
@@ -840,25 +809,12 @@ LOCALSTORAGE_JS = """
840
  observer.observe(document.body, { childList: true, subtree: true });
841
  },
842
 
843
- // Debug: List all textareas on page
844
- debugListTextareas() {
845
- const textareas = document.querySelectorAll('textarea');
846
- console.log('NAIA-WEB Autocomplete DEBUG: Found', textareas.length, 'textareas on page:');
847
- textareas.forEach((ta, i) => {
848
- const parent = ta.closest('[id]');
849
- const parentId = parent ? parent.id : 'no-id-parent';
850
- console.log(` [${i}] parent=#${parentId}, placeholder="${ta.placeholder || ''}"`.substring(0, 100));
851
- });
852
- },
853
-
854
  // Handle input event
855
  onInput(textarea) {
856
- console.log('NAIA-WEB Autocomplete: Input event fired');
857
  this.activeTextarea = textarea;
858
 
859
  clearTimeout(this.debounceTimer);
860
  this.debounceTimer = setTimeout(() => {
861
- console.log('NAIA-WEB Autocomplete: Debounce triggered, calling search');
862
  this.search(textarea);
863
  }, this.DEBOUNCE_MS);
864
  },
@@ -951,12 +907,10 @@ LOCALSTORAGE_JS = """
951
  }
952
 
953
  const tokenInfo = this.getCurrentToken(textarea);
954
- const { token, isWeightValue, weightPrefix, weightSuffix } = tokenInfo;
955
- console.log('NAIA-WEB Autocomplete: Search called, token:', token, 'weightPrefix:', weightPrefix, 'weightSuffix:', weightSuffix);
956
 
957
  // Skip autocomplete if editing a weight value (e.g., "0.5" in "0.5::tag")
958
  if (isWeightValue) {
959
- console.log('NAIA-WEB Autocomplete: Editing weight value, skipping');
960
  this.close();
961
  return;
962
  }
@@ -965,42 +919,33 @@ LOCALSTORAGE_JS = """
965
  this.currentTokenInfo = tokenInfo;
966
 
967
  if (token.length < this.MIN_CHARS) {
968
- console.log('NAIA-WEB Autocomplete: Token too short, closing');
969
  this.close();
970
  return;
971
  }
972
 
973
  // Determine search mode based on textarea context
974
  this.currentSearchMode = this.getSearchMode(textarea);
975
- console.log('NAIA-WEB Autocomplete: Search mode:', this.currentSearchMode);
976
 
977
  // Trigger Gradio search via hidden input
978
  // Format: "mode:query" (e.g., "no_character:blue" or "character_only:miku")
979
  const searchContainer = document.getElementById('naia-autocomplete-query');
980
  const searchInput = searchContainer ? searchContainer.querySelector('textarea, input') : null;
981
- console.log('NAIA-WEB Autocomplete: Search input element:', searchInput);
982
  if (searchInput) {
983
  const queryWithMode = this.currentSearchMode + ':' + token;
984
  searchInput.value = queryWithMode;
985
  searchInput.dispatchEvent(new Event('input', { bubbles: true }));
986
- console.log('NAIA-WEB Autocomplete: Dispatched search event for:', queryWithMode);
987
- } else {
988
- console.log('NAIA-WEB Autocomplete: ERROR - Search input not found! Container:', searchContainer);
989
  }
990
  },
991
 
992
  // Receive results from Gradio (called from JS parameter)
993
  setResults(results) {
994
- console.log('NAIA-WEB Autocomplete: setResults called with:', results);
995
  if (!results || results.length === 0) {
996
- console.log('NAIA-WEB Autocomplete: No results, closing');
997
  this.close();
998
  return;
999
  }
1000
 
1001
  this.currentResults = results;
1002
  this.selectedIndex = 0;
1003
- console.log('NAIA-WEB Autocomplete: Rendering', results.length, 'results');
1004
  this.renderDropdown();
1005
  this.show();
1006
  },
@@ -1116,7 +1061,6 @@ LOCALSTORAGE_JS = """
1116
  const searchBtn = document.querySelector('#naia-char-search-btn');
1117
  if (searchBtn) {
1118
  searchBtn.click();
1119
- console.log('NAIA-WEB Autocomplete: Clicked character search button');
1120
  }
1121
  }, 100);
1122
  } else {
@@ -1259,7 +1203,6 @@ LOCALSTORAGE_JS = """
1259
 
1260
  // Initialize after DOM ready with retry
1261
  function initAutocompleteWithRetry(attempt = 1) {
1262
- console.log('NAIA-WEB Autocomplete: Init attempt', attempt);
1263
  Autocomplete.init();
1264
 
1265
  // If no textareas attached and still have retries, try again
@@ -1290,7 +1233,6 @@ LOCALSTORAGE_JS = """
1290
  // Move download button into image container
1291
  if (!imageContainer.contains(downloadBtn)) {
1292
  imageContainer.appendChild(downloadBtn);
1293
- console.log('NAIA-WEB: Download button moved into image container');
1294
  }
1295
  }
1296
 
 
178
  if (generateStartTime) {
179
  const elapsed = (Date.now() - generateStartTime) / 1000;
180
  addResponseTime(elapsed);
 
181
  }
182
 
183
  if (timerInterval) {
 
202
  const autoSaveContainer = document.querySelector('#naia-auto-save');
203
  const autoSaveCheckbox = autoSaveContainer ? autoSaveContainer.querySelector('input[type="checkbox"]') : null;
204
  if (autoSaveCheckbox && autoSaveCheckbox.checked) {
205
+ // Mobile-friendly auto-save: click immediately to maintain user interaction context
206
+ const link = downloadBtn.querySelector('a[download]');
207
+ if (link) {
208
+ link.click();
209
+ } else {
210
  downloadBtn.click();
211
+ }
 
212
  }
213
  }
214
  }
 
265
  input.value = savedToken;
266
  input.dispatchEvent(new Event('input', { bubbles: true }));
267
  input.dispatchEvent(new Event('change', { bubbles: true }));
 
268
  }
269
  } catch (e) {
270
  console.error('NAIA-WEB: Error loading token:', e);
 
387
  scale: toFloat(getInputValue('#naia-scale')),
388
  cfg_rescale: toFloat(getInputValue('#naia-cfg-rescale')),
389
  sampler: getInputValue('#naia-sampler'),
390
+ noise_schedule: getInputValue('#naia-noise-schedule'),
391
+ variety_plus: getInputValue('#naia-variety-plus', 'checkbox'),
392
  // Random resolution
393
  random_resolution: getInputValue('#naia-random-resolution', 'checkbox'),
394
  enabled_resolutions: getCheckboxGroupValues('#naia-res-checkboxes'),
 
419
 
420
  try {
421
  localStorage.setItem(SETTINGS_KEY, JSON.stringify(settings));
 
 
 
 
422
  } catch (e) {
423
  console.error('NAIA-WEB: Error saving settings:', e);
424
  }
 
479
  renderFromCache() {
480
  const grid = document.getElementById('naia-qs-tag-grid');
481
  if (!grid) {
 
482
  return;
483
  }
484
 
 
507
  }
508
 
509
  this.updatePageInfo();
 
510
  },
511
 
512
  // Show popup to choose Include or Exclude (positioned above grid)
 
578
  actionInput.value = `${action}:${tag}`;
579
  actionInput.dispatchEvent(new Event('input', { bubbles: true }));
580
  actionInput.dispatchEvent(new Event('change', { bubbles: true }));
 
581
  }
582
  },
583
 
 
605
  }
606
 
607
  // Add click listener - just try to render after click
 
608
  button.addEventListener('click', () => {
 
609
  if (self.dataReady) {
 
610
  self.renderWithRetry(5);
611
  }
612
  });
 
 
613
  };
614
 
615
  checkAccordion();
 
678
 
679
  // Initialize autocomplete on all target textareas
680
  init() {
 
681
  this.createDropdown();
 
 
 
682
  this.attachToTargets();
 
683
  // Re-attach when new elements appear (for dynamic char slots)
684
  this.setupMutationObserver();
 
685
  },
686
 
687
  // Create the dropdown element
 
720
  return container.querySelector('textarea');
721
  },
722
 
 
 
 
723
  // Attach to all target textareas
724
  attachToTargets() {
725
  let attachedCount = 0;
 
729
  if (textarea && !textarea.dataset.autocompleteAttached) {
730
  this.attachToTextarea(textarea);
731
  attachedCount++;
 
 
 
 
 
732
  }
733
  }
734
 
 
739
  if (promptTextarea && !promptTextarea.dataset.autocompleteAttached) {
740
  this.attachToTextarea(promptTextarea);
741
  attachedCount++;
 
742
  }
743
  if (negativeTextarea && !negativeTextarea.dataset.autocompleteAttached) {
744
  this.attachToTextarea(negativeTextarea);
745
  attachedCount++;
 
746
  }
747
  }
748
 
 
751
  if (charSearchTextarea && !charSearchTextarea.dataset.autocompleteAttached) {
752
  this.attachToTextarea(charSearchTextarea);
753
  attachedCount++;
 
 
 
 
 
754
  }
755
  },
756
 
 
809
  observer.observe(document.body, { childList: true, subtree: true });
810
  },
811
 
 
 
 
 
 
 
 
 
 
 
 
812
  // Handle input event
813
  onInput(textarea) {
 
814
  this.activeTextarea = textarea;
815
 
816
  clearTimeout(this.debounceTimer);
817
  this.debounceTimer = setTimeout(() => {
 
818
  this.search(textarea);
819
  }, this.DEBOUNCE_MS);
820
  },
 
907
  }
908
 
909
  const tokenInfo = this.getCurrentToken(textarea);
910
+ const { token, isWeightValue } = tokenInfo;
 
911
 
912
  // Skip autocomplete if editing a weight value (e.g., "0.5" in "0.5::tag")
913
  if (isWeightValue) {
 
914
  this.close();
915
  return;
916
  }
 
919
  this.currentTokenInfo = tokenInfo;
920
 
921
  if (token.length < this.MIN_CHARS) {
 
922
  this.close();
923
  return;
924
  }
925
 
926
  // Determine search mode based on textarea context
927
  this.currentSearchMode = this.getSearchMode(textarea);
 
928
 
929
  // Trigger Gradio search via hidden input
930
  // Format: "mode:query" (e.g., "no_character:blue" or "character_only:miku")
931
  const searchContainer = document.getElementById('naia-autocomplete-query');
932
  const searchInput = searchContainer ? searchContainer.querySelector('textarea, input') : null;
 
933
  if (searchInput) {
934
  const queryWithMode = this.currentSearchMode + ':' + token;
935
  searchInput.value = queryWithMode;
936
  searchInput.dispatchEvent(new Event('input', { bubbles: true }));
 
 
 
937
  }
938
  },
939
 
940
  // Receive results from Gradio (called from JS parameter)
941
  setResults(results) {
 
942
  if (!results || results.length === 0) {
 
943
  this.close();
944
  return;
945
  }
946
 
947
  this.currentResults = results;
948
  this.selectedIndex = 0;
 
949
  this.renderDropdown();
950
  this.show();
951
  },
 
1061
  const searchBtn = document.querySelector('#naia-char-search-btn');
1062
  if (searchBtn) {
1063
  searchBtn.click();
 
1064
  }
1065
  }, 100);
1066
  } else {
 
1203
 
1204
  // Initialize after DOM ready with retry
1205
  function initAutocompleteWithRetry(attempt = 1) {
 
1206
  Autocomplete.init();
1207
 
1208
  // If no textareas attached and still have retries, try again
 
1233
  // Move download button into image container
1234
  if (!imageContainer.contains(downloadBtn)) {
1235
  imageContainer.appendChild(downloadBtn);
 
1236
  }
1237
  }
1238