Wavetype commited on
Commit
c0eaf7e
·
verified ·
1 Parent(s): 3507381

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +49 -16
index.html CHANGED
@@ -3,25 +3,42 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Wavetype Frequency Grid - Clean</title>
7
  <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/css/bootstrap.min.css" rel="stylesheet">
8
  <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.11.1/font/bootstrap-icons.min.css" rel="stylesheet">
9
  <style>
10
  :root { --border-ai: #ff00ff; --accent: #00ff00; --bg: #000; }
11
  body, html { margin: 0; padding: 0; width: 100%; height: 100vh; overflow: hidden; background: var(--bg); color: white; font-family: monospace; }
 
12
  #sidebar { position: fixed; left: 0; top: 0; width: 320px; height: 100vh; background: #111; border-right: 1px solid #333; z-index: 2000; transition: transform 0.3s; }
13
  #sidebar.collapsed { transform: translateX(-320px); }
 
14
  #sidebar-toggle { position: fixed; left: 320px; top: 20px; z-index: 2001; cursor: pointer; background: #111; color: var(--accent); border: 1px solid #333; border-left: none; padding: 5px; transition: left 0.3s; }
15
  #sidebar.collapsed ~ #sidebar-toggle { left: 0; }
 
16
  #grid-container { display: grid; width: 100vw; height: 100vh; gap: 4px; padding: 4px 4px 4px 324px; transition: padding 0.3s; }
17
  #sidebar.collapsed ~ #grid-container { padding-left: 4px; }
18
- .block { border: 2px solid #222; background: rgba(255,255,255,0.05); display: flex; align-items: center; justify-content: center; position: relative; cursor: pointer; }
 
19
  .block.active { position: fixed; top: 0; left: 0; width: 100vw!important; height: 100vh!important; z-index: 2500; background: #000; padding: 40px; cursor: default; }
20
- .ai-ui { display: none; width: 100%; max-width: 800px; flex-direction: column; gap: 15px; }
 
21
  .block.active .ai-ui { display: flex; }
22
- .close-btn { display: none; position: absolute; top: 20px; right: 20px; background: #ff0055; color: #fff; border: none; padding: 5px 15px; }
 
 
 
 
 
 
 
 
 
23
  .block.active .close-btn { display: block; }
 
24
  .preview-img { width: 100%; max-height: 60vh; object-fit: contain; margin-top: 15px; border: 1px solid var(--border-ai); display: none; }
 
 
25
  </style>
26
  </head>
27
  <body>
@@ -31,10 +48,10 @@
31
  HF_AUTH: <span id="authStatus" class="text-danger">MISSING</span>
32
  </div>
33
  <div class="p-3">
34
- <label class="small text-muted">DENSITY</label>
35
  <input type="range" class="form-range" id="density" min="1" max="16" value="4" oninput="initGrid()">
36
  <div class="mt-3">
37
- <label class="small text-muted">TOKEN</label>
38
  <input type="password" class="form-control form-control-sm bg-dark text-white border-secondary" id="tokenField" placeholder="hf_...">
39
  </div>
40
  <button class="btn btn-info btn-sm w-100 mt-4" onclick="save()">SAVE TO CACHE</button>
@@ -53,10 +70,9 @@
53
  const urlKey = params.get('token');
54
  const hfInp = document.getElementById('tokenField');
55
 
56
- // Auto-detect token from URL or Cache
57
  if (urlKey) {
58
  hfInp.value = urlKey;
59
- window.history.replaceState({}, '', window.location.pathname); // Clean URL
60
  save();
61
  } else {
62
  const cache = JSON.parse(localStorage.getItem('flux_cfg') || '{}');
@@ -79,17 +95,21 @@
79
  const cols = Math.ceil(Math.sqrt(count));
80
  container.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;
81
  container.innerHTML = '';
82
- nodes = Array.from({length: count}, (_, i) => ({ id: i, prompt: '' }));
83
 
84
  nodes.forEach(n => {
85
  const div = document.createElement('div');
86
  div.className = 'block';
87
- div.onclick = () => div.classList.add('active');
88
  div.innerHTML = `
89
  <div class="ai-ui">
 
 
 
 
90
  <h4 class="text-info">NODE_${n.id + 1}</h4>
91
- <textarea class="form-control bg-dark text-white" id="p-${n.id}" placeholder="Prompt..."></textarea>
92
- <button class="btn btn-info mt-2" onclick="gen(${n.id}, this)">GENERATE</button>
93
  <img id="img-${n.id}" class="preview-img">
94
  </div>
95
  <div class="small text-muted">FLUX_NODE_${n.id + 1}</div>
@@ -104,20 +124,33 @@
104
  const token = document.getElementById('tokenField').value;
105
  const prompt = document.getElementById(`p-${id}`).value;
106
  const img = document.getElementById(`img-${id}`);
107
- if (!token || !prompt) return alert("Missing Token or Prompt");
 
 
 
 
 
 
 
108
 
109
- btn.disabled = true; btn.innerText = "RUNNING...";
110
  try {
111
  const res = await fetch("https://api-inference.huggingface.co/models/Comfy-Org/flux2-klein-9B", {
112
  headers: { Authorization: `Bearer ${token}` },
113
  method: "POST",
114
  body: JSON.stringify({ inputs: prompt })
115
  });
 
 
 
116
  const blob = await res.blob();
117
  img.src = URL.createObjectURL(blob);
118
  img.style.display = 'block';
119
- } catch (e) { console.error(e); }
120
- btn.disabled = false; btn.innerText = "GENERATE";
 
 
 
 
121
  }
122
 
123
  function save() {
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Wavetype Frequency Grid - Flux.1</title>
7
  <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/css/bootstrap.min.css" rel="stylesheet">
8
  <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.11.1/font/bootstrap-icons.min.css" rel="stylesheet">
9
  <style>
10
  :root { --border-ai: #ff00ff; --accent: #00ff00; --bg: #000; }
11
  body, html { margin: 0; padding: 0; width: 100%; height: 100vh; overflow: hidden; background: var(--bg); color: white; font-family: monospace; }
12
+
13
  #sidebar { position: fixed; left: 0; top: 0; width: 320px; height: 100vh; background: #111; border-right: 1px solid #333; z-index: 2000; transition: transform 0.3s; }
14
  #sidebar.collapsed { transform: translateX(-320px); }
15
+
16
  #sidebar-toggle { position: fixed; left: 320px; top: 20px; z-index: 2001; cursor: pointer; background: #111; color: var(--accent); border: 1px solid #333; border-left: none; padding: 5px; transition: left 0.3s; }
17
  #sidebar.collapsed ~ #sidebar-toggle { left: 0; }
18
+
19
  #grid-container { display: grid; width: 100vw; height: 100vh; gap: 4px; padding: 4px 4px 4px 324px; transition: padding 0.3s; }
20
  #sidebar.collapsed ~ #grid-container { padding-left: 4px; }
21
+
22
+ .block { border: 2px solid #222; background: rgba(255,255,255,0.05); display: flex; align-items: center; justify-content: center; position: relative; cursor: pointer; transition: 0.3s; }
23
  .block.active { position: fixed; top: 0; left: 0; width: 100vw!important; height: 100vh!important; z-index: 2500; background: #000; padding: 40px; cursor: default; }
24
+
25
+ .ai-ui { display: none; width: 100%; max-width: 800px; flex-direction: column; gap: 15px; position: relative; }
26
  .block.active .ai-ui { display: flex; }
27
+
28
+ /* Loading Visuals */
29
+ .loader-overlay {
30
+ display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%;
31
+ background: rgba(0,0,0,0.8); z-index: 10; flex-direction: column; align-items: center; justify-content: center;
32
+ border: 2px solid var(--border-ai); border-radius: 8px; animation: pulse 1.5s infinite;
33
+ }
34
+ @keyframes pulse { 0% { opacity: 0.6; } 50% { opacity: 1; } 100% { opacity: 0.6; } }
35
+
36
+ .close-btn { display: none; position: absolute; top: 20px; right: 20px; background: #ff0055; color: #fff; border: none; padding: 5px 15px; z-index: 2600; }
37
  .block.active .close-btn { display: block; }
38
+
39
  .preview-img { width: 100%; max-height: 60vh; object-fit: contain; margin-top: 15px; border: 1px solid var(--border-ai); display: none; }
40
+
41
+ input, textarea { border-radius: 0!important; }
42
  </style>
43
  </head>
44
  <body>
 
48
  HF_AUTH: <span id="authStatus" class="text-danger">MISSING</span>
49
  </div>
50
  <div class="p-3">
51
+ <label class="small text-muted">GRID DENSITY</label>
52
  <input type="range" class="form-range" id="density" min="1" max="16" value="4" oninput="initGrid()">
53
  <div class="mt-3">
54
+ <label class="small text-muted">API TOKEN</label>
55
  <input type="password" class="form-control form-control-sm bg-dark text-white border-secondary" id="tokenField" placeholder="hf_...">
56
  </div>
57
  <button class="btn btn-info btn-sm w-100 mt-4" onclick="save()">SAVE TO CACHE</button>
 
70
  const urlKey = params.get('token');
71
  const hfInp = document.getElementById('tokenField');
72
 
 
73
  if (urlKey) {
74
  hfInp.value = urlKey;
75
+ window.history.replaceState({}, '', window.location.pathname);
76
  save();
77
  } else {
78
  const cache = JSON.parse(localStorage.getItem('flux_cfg') || '{}');
 
95
  const cols = Math.ceil(Math.sqrt(count));
96
  container.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;
97
  container.innerHTML = '';
98
+ nodes = Array.from({length: count}, (_, i) => ({ id: i }));
99
 
100
  nodes.forEach(n => {
101
  const div = document.createElement('div');
102
  div.className = 'block';
103
+ div.onclick = () => { if(!div.classList.contains('active')) div.classList.add('active'); };
104
  div.innerHTML = `
105
  <div class="ai-ui">
106
+ <div id="loader-${n.id}" class="loader-overlay">
107
+ <div class="spinner-border text-info mb-2"></div>
108
+ <div class="small">VPS INFERENCE IN PROGRESS...</div>
109
+ </div>
110
  <h4 class="text-info">NODE_${n.id + 1}</h4>
111
+ <textarea class="form-control bg-dark text-white border-secondary" id="p-${n.id}" rows="4" placeholder="Describe the image..."></textarea>
112
+ <button class="btn btn-info mt-2" onclick="gen(${n.id}, this)">GENERATE ON FLUX</button>
113
  <img id="img-${n.id}" class="preview-img">
114
  </div>
115
  <div class="small text-muted">FLUX_NODE_${n.id + 1}</div>
 
124
  const token = document.getElementById('tokenField').value;
125
  const prompt = document.getElementById(`p-${id}`).value;
126
  const img = document.getElementById(`img-${id}`);
127
+ const loader = document.getElementById(`loader-${id}`);
128
+
129
+ if (!token || !prompt) return alert("Please enter a token in sidebar and a prompt in the node.");
130
+
131
+ // Show Loading state
132
+ loader.style.display = 'flex';
133
+ img.style.display = 'none';
134
+ btn.disabled = true;
135
 
 
136
  try {
137
  const res = await fetch("https://api-inference.huggingface.co/models/Comfy-Org/flux2-klein-9B", {
138
  headers: { Authorization: `Bearer ${token}` },
139
  method: "POST",
140
  body: JSON.stringify({ inputs: prompt })
141
  });
142
+
143
+ if (!res.ok) throw new Error("API Limit or Token Error");
144
+
145
  const blob = await res.blob();
146
  img.src = URL.createObjectURL(blob);
147
  img.style.display = 'block';
148
+ } catch (e) {
149
+ alert("Error: " + e.message);
150
+ } finally {
151
+ loader.style.display = 'none';
152
+ btn.disabled = false;
153
+ }
154
  }
155
 
156
  function save() {