Sada8888 commited on
Commit
1fd9cfa
·
verified ·
1 Parent(s): 851081c

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +128 -60
index.html CHANGED
@@ -3,7 +3,7 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>پنل ساخت تصویر با GitHub Actions</title>
7
  <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;600;800&display=swap" rel="stylesheet">
8
  <style>
9
  :root {
@@ -52,37 +52,33 @@
52
  outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(90, 103, 216, 0.3); background-color: #ffffff;
53
  }
54
 
55
- .size-grid {
56
- display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px;
57
- }
58
-
59
  .size-btn {
60
  padding: 10px; border: 1px solid var(--border); border-radius: var(--radius);
61
  background-color: #F7FAFC; color: var(--text-muted); cursor: pointer;
62
- font-family: inherit; font-size: 0.9rem; font-weight: 600; transition: all 0.2s;
63
- }
64
- .size-btn.active {
65
- background-color: var(--primary); color: white; border-color: var(--primary);
66
  }
 
67
 
68
  button.main-btn {
69
  width: 100%; padding: 14px; background-color: var(--primary); color: #ffffff; border: none;
70
  border-radius: var(--radius); font-size: 1.1rem; font-weight: bold; cursor: pointer; margin-top: 10px;
71
- transition: background-color 0.2s;
72
  }
73
  button.main-btn:hover { background-color: var(--primary-hover); }
74
  button.main-btn:disabled { background-color: #A3B1E1; cursor: not-allowed; }
75
 
76
  hr { border: 0; border-top: 1px solid var(--border); margin: 25px 0; }
77
- .notice { font-size: 0.85rem; color: var(--text-muted); margin-top: 5px; display: block; }
78
-
79
- #status-box { margin-top: 25px; padding: 15px; border-radius: var(--radius); display: none; line-height: 1.6; text-align: center; }
80
  .status-loading { background-color: #EBF4FF; border: 1px solid #90CDF4; color: #3182CE; }
81
- .status-success { background-color: #F0FFF4; border: 1px solid #9AE6B4; color: #276749; }
82
  .status-error { background-color: #FFF5F5; border: 1px solid #FEB2B2; color: #C53030; }
83
- .action-link {
84
- display: inline-block; margin-top: 15px; padding: 10px 20px; background-color: var(--primary);
85
- border-radius: var(--radius); color: white; text-decoration: none; font-weight: 600;
 
 
 
86
  }
87
  </style>
88
  </head>
@@ -92,26 +88,23 @@
92
  <h2>🎨 استودیو تصویر Flux</h2>
93
 
94
  <div class="form-group">
95
- <label>نام کاربری GitHub</label>
96
- <input type="text" id="gh-username" value="Hamed744" readonly style="color: #718096; background: #EDF2F7;">
97
- </div>
98
-
99
- <div class="form-group">
100
- <label>نام مخزن (Repository)</label>
101
- <input type="text" id="gh-repo" value="vid-test" readonly style="color: #718096; background: #EDF2F7;">
102
  </div>
103
 
104
  <div class="form-group">
105
  <label>توکن امنیتی (PAT)</label>
106
  <input type="password" id="gh-token" placeholder="ghp_....................................">
107
- <span class="notice">توکن شما فقط در مرورگر خودتان استفاده می‌شود.</span>
108
  </div>
109
 
110
  <hr>
111
 
112
  <div class="form-group">
113
  <label>دستور ساخت تصویر (Prompt به انگلیسی)</label>
114
- <textarea id="prompt" rows="4" placeholder="مثال: A futuristic cyberpunk city, neon lights, highly detailed, 8k..."></textarea>
115
  </div>
116
 
117
  <div class="form-group">
@@ -124,16 +117,21 @@
124
  </div>
125
  </div>
126
 
127
- <button id="btn-submit" class="main-btn" onclick="triggerGitHubAction()">🚀 ارسال درخواست ساخت تصویر</button>
128
 
129
  <div id="status-box"></div>
 
 
 
 
 
130
  </div>
131
 
132
  <script>
133
  let selectedWidth = 1024;
134
  let selectedHeight = 1024;
 
135
 
136
- // انتخاب سایز عکس
137
  function selectSize(btn) {
138
  document.querySelectorAll('.size-btn').forEach(b => b.classList.remove('active'));
139
  btn.classList.add('active');
@@ -142,63 +140,133 @@
142
  }
143
 
144
  async function triggerGitHubAction() {
145
- const username = document.getElementById('gh-username').value;
146
- const repo = document.getElementById('gh-repo').value;
147
  const token = document.getElementById('gh-token').value.trim();
148
  const prompt = document.getElementById('prompt').value.trim();
149
  const statusBox = document.getElementById('status-box');
150
  const submitBtn = document.getElementById('btn-submit');
 
151
 
152
- if (!token || !prompt) {
153
- alert('لطفاً توکن و دستور ساخت تصویر را وارد کنید.');
154
- return;
155
- }
156
 
 
157
  submitBtn.disabled = true;
 
158
  statusBox.style.display = 'block';
159
  statusBox.className = 'status-loading';
160
  statusBox.innerHTML = 'در حال ارتباط با سرور گیت‌هاب...';
 
161
 
162
  try {
163
  const apiUrl = `https://api.github.com/repos/${username}/${repo}/dispatches`;
164
 
165
- // ارسال فقط متن‌ها (بدون نیاز به آپلود فایل!)
166
  const response = await fetch(apiUrl, {
167
  method: 'POST',
168
- headers: {
169
- 'Accept': 'application/vnd.github.v3+json',
170
- 'Authorization': `token ${token}`,
171
- 'Content-Type': 'application/json'
172
- },
173
  body: JSON.stringify({
174
- event_type: 'generate-image', // این نام باید دقیقا با main.yml یکی باشد
175
- client_payload: {
176
- prompt: prompt,
177
- width: selectedWidth.toString(),
178
- height: selectedHeight.toString()
179
- }
180
  })
181
  });
182
 
183
- if (response.ok) {
184
- statusBox.className = 'status-success';
185
- statusBox.innerHTML = `
186
- <strong>درخواست با موفقیت ارسال شد! 🎉</strong><br>
187
- گیت‌هاب در حال ساخت تصویر است. (حدود ۳۰ تا ۶۰ ثانیه زمان می‌برد).<br><br>
188
- برای مشاهده پیشرفت و دانلود تصویر نهایی روی دکمه زیر کلیک کنید:<br>
189
- <a href="https://github.com/${username}/${repo}/actions" target="_blank" class="action-link">دریافت تصویر از گیت‌هاب</a>
190
- `;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  } else {
192
- const errorText = await response.text();
193
  statusBox.className = 'status-error';
194
- statusBox.innerHTML = `<strong>خطا در ارسال!</strong><br>کد خطا: ${response.status}<br><small>بررسی کنید توکن دسترسی Repo داشته باشد.</small>`;
195
  }
196
- } catch (error) {
197
  statusBox.className = 'status-error';
198
- statusBox.innerHTML = `<strong>خطای اینترنت!</strong><br><small>${error.message}</small>`;
199
  } finally {
200
- submitBtn.disabled = false;
201
- submitBtn.innerHTML = '🚀 ارسال درخواست ساخت تصویر';
202
  }
203
  }
204
  </script>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>استودیو تصویر هوش مصنوعی</title>
7
  <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;600;800&display=swap" rel="stylesheet">
8
  <style>
9
  :root {
 
52
  outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(90, 103, 216, 0.3); background-color: #ffffff;
53
  }
54
 
55
+ .size-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
 
 
 
56
  .size-btn {
57
  padding: 10px; border: 1px solid var(--border); border-radius: var(--radius);
58
  background-color: #F7FAFC; color: var(--text-muted); cursor: pointer;
59
+ font-weight: 600; transition: all 0.2s;
 
 
 
60
  }
61
+ .size-btn.active { background-color: var(--primary); color: white; border-color: var(--primary); }
62
 
63
  button.main-btn {
64
  width: 100%; padding: 14px; background-color: var(--primary); color: #ffffff; border: none;
65
  border-radius: var(--radius); font-size: 1.1rem; font-weight: bold; cursor: pointer; margin-top: 10px;
 
66
  }
67
  button.main-btn:hover { background-color: var(--primary-hover); }
68
  button.main-btn:disabled { background-color: #A3B1E1; cursor: not-allowed; }
69
 
70
  hr { border: 0; border-top: 1px solid var(--border); margin: 25px 0; }
71
+
72
+ /* استایل‌های پیام و نمایش نتیجه */
73
+ #status-box { margin-top: 20px; padding: 15px; border-radius: var(--radius); display: none; text-align: center; font-weight: 600; }
74
  .status-loading { background-color: #EBF4FF; border: 1px solid #90CDF4; color: #3182CE; }
 
75
  .status-error { background-color: #FFF5F5; border: 1px solid #FEB2B2; color: #C53030; }
76
+
77
+ #result-container {
78
+ margin-top: 20px; display: none; text-align: center;
79
+ }
80
+ #result-container img {
81
+ max-width: 100%; border-radius: var(--radius); border: 2px solid var(--border); box-shadow: 0 4px 6px rgba(0,0,0,0.1);
82
  }
83
  </style>
84
  </head>
 
88
  <h2>🎨 استودیو تصویر Flux</h2>
89
 
90
  <div class="form-group">
91
+ <label>نام کاربری GitHub و نام مخزن</label>
92
+ <div style="display: flex; gap: 10px;">
93
+ <input type="text" id="gh-username" value="Hamed744" placeholder="نام کاربری">
94
+ <input type="text" id="gh-repo" value="vid-test" placeholder="مخزن">
95
+ </div>
 
 
96
  </div>
97
 
98
  <div class="form-group">
99
  <label>توکن امنیتی (PAT)</label>
100
  <input type="password" id="gh-token" placeholder="ghp_....................................">
 
101
  </div>
102
 
103
  <hr>
104
 
105
  <div class="form-group">
106
  <label>دستور ساخت تصویر (Prompt به انگلیسی)</label>
107
+ <textarea id="prompt" rows="3" placeholder="مثال: A beautiful glowing cat in cyberpunk style..."></textarea>
108
  </div>
109
 
110
  <div class="form-group">
 
117
  </div>
118
  </div>
119
 
120
+ <button id="btn-submit" class="main-btn" onclick="triggerGitHubAction()">🚀 ساخت تصویر</button>
121
 
122
  <div id="status-box"></div>
123
+
124
+ <div id="result-container">
125
+ <h3 style="color: #2ea44f; margin-bottom: 10px;">🎉 تصویر شما آماده است!</h3>
126
+ <img id="generated-image" src="" alt="AI Generated Image">
127
+ </div>
128
  </div>
129
 
130
  <script>
131
  let selectedWidth = 1024;
132
  let selectedHeight = 1024;
133
+ let checkInterval;
134
 
 
135
  function selectSize(btn) {
136
  document.querySelectorAll('.size-btn').forEach(b => b.classList.remove('active'));
137
  btn.classList.add('active');
 
140
  }
141
 
142
  async function triggerGitHubAction() {
143
+ const username = document.getElementById('gh-username').value.trim();
144
+ const repo = document.getElementById('gh-repo').value.trim();
145
  const token = document.getElementById('gh-token').value.trim();
146
  const prompt = document.getElementById('prompt').value.trim();
147
  const statusBox = document.getElementById('status-box');
148
  const submitBtn = document.getElementById('btn-submit');
149
+ const resultContainer = document.getElementById('result-container');
150
 
151
+ if (!token || !prompt) return alert('توکن و دستور متحرک‌سازی الزامی است.');
 
 
 
152
 
153
+ // ریست کردن بخش نتایج و دکمه
154
  submitBtn.disabled = true;
155
+ resultContainer.style.display = 'none';
156
  statusBox.style.display = 'block';
157
  statusBox.className = 'status-loading';
158
  statusBox.innerHTML = 'در حال ارتباط با سرور گیت‌هاب...';
159
+ clearInterval(checkInterval);
160
 
161
  try {
162
  const apiUrl = `https://api.github.com/repos/${username}/${repo}/dispatches`;
163
 
164
+ // ۱. ارسال دستور شروع به گیت هاب
165
  const response = await fetch(apiUrl, {
166
  method: 'POST',
167
+ headers: { 'Accept': 'application/vnd.github.v3+json', 'Authorization': `token ${token}`, 'Content-Type': 'application/json' },
 
 
 
 
168
  body: JSON.stringify({
169
+ event_type: 'generate-image',
170
+ client_payload: { prompt: prompt, width: selectedWidth.toString(), height: selectedHeight.toString() }
 
 
 
 
171
  })
172
  });
173
 
174
+ if (!response.ok) throw new Error('خطا در ارسال دستور به گیت‌هاب');
175
+
176
+ statusBox.innerHTML = 'درخواست ارسال شد. منتظر روشن شدن سرور... (این مرحله حدود ۱ دقیقه زمان می‌برد) ⏳';
177
+
178
+ // ۲. ۲ ثانیه صبر میکنیم تا اکشن در گیت هاب ثبت شود
179
+ setTimeout(() => {
180
+ checkWorkflowStatus(username, repo, token);
181
+ }, 3000);
182
+
183
+ } catch (error) {
184
+ statusBox.className = 'status-error';
185
+ statusBox.innerHTML = `خطا: ${error.message}`;
186
+ submitBtn.disabled = false;
187
+ }
188
+ }
189
+
190
+ // تابع برای پیگیری وضعیت گیت هاب در پس‌زمینه
191
+ async function checkWorkflowStatus(username, repo, token) {
192
+ const statusBox = document.getElementById('status-box');
193
+ const submitBtn = document.getElementById('btn-submit');
194
+ const headers = { 'Accept': 'application/vnd.github.v3+json', 'Authorization': `token ${token}` };
195
+
196
+ try {
197
+ // پیدا کردن ID جدی��ترین پردازش
198
+ let runsRes = await fetch(`https://api.github.com/repos/${username}/${repo}/actions/runs?event=repository_dispatch&per_page=1`, { headers });
199
+ let runsData = await runsRes.json();
200
+
201
+ if (!runsData.workflow_runs || runsData.workflow_runs.length === 0) {
202
+ setTimeout(() => checkWorkflowStatus(username, repo, token), 3000);
203
+ return;
204
+ }
205
+
206
+ const runId = runsData.workflow_runs[0].id;
207
+
208
+ // شروع به پرسیدن مداوم وضعیت هر ۵ ثانیه یکبار
209
+ checkInterval = setInterval(async () => {
210
+ let runDetailRes = await fetch(`https://api.github.com/repos/${username}/${repo}/actions/runs/${runId}`, { headers });
211
+ let runDetail = await runDetailRes.json();
212
+
213
+ if (runDetail.status === 'in_progress') {
214
+ statusBox.innerHTML = 'سرور روشن شد. در حال تولید تصویر توسط هوش مصنوعی... 🎨<br><small>(لطفاً صفحه را نبندید)</small>';
215
+ }
216
+ else if (runDetail.status === 'completed') {
217
+ clearInterval(checkInterval);
218
+
219
+ if (runDetail.conclusion === 'success') {
220
+ statusBox.innerHTML = 'تصویر ساخته شد! در حال استخراج تصویر... 📥';
221
+ extractImageUrl(username, repo, token, runId);
222
+ } else {
223
+ statusBox.className = 'status-error';
224
+ statusBox.innerHTML = 'خطا! ساخت تصویر در سرور گیت‌هاب با شکست مواجه شد ❌';
225
+ submitBtn.disabled = false;
226
+ }
227
+ }
228
+ }, 5000);
229
+
230
+ } catch (e) {
231
+ clearInterval(checkInterval);
232
+ statusBox.className = 'status-error';
233
+ statusBox.innerHTML = 'ارتباط برای پیگیری وضعیت قطع شد.';
234
+ submitBtn.disabled = false;
235
+ }
236
+ }
237
+
238
+ // خواندن لاگ‌های گیت هاب و بیرون کشیدن لینک عکس
239
+ async function extractImageUrl(username, repo, token, runId) {
240
+ const headers = { 'Accept': 'application/vnd.github.v3+json', 'Authorization': `token ${token}` };
241
+ const statusBox = document.getElementById('status-box');
242
+
243
+ try {
244
+ // پیدا کردن Job ID
245
+ let jobsRes = await fetch(`https://api.github.com/repos/${username}/${repo}/actions/runs/${runId}/jobs`, { headers });
246
+ let jobsData = await jobsRes.json();
247
+ const jobId = jobsData.jobs[0].id;
248
+
249
+ // دریافت فایل متنی لاگ‌ها
250
+ let logsRes = await fetch(`https://api.github.com/repos/${username}/${repo}/actions/jobs/${jobId}/logs`, { headers });
251
+ let logsText = await logsRes.text();
252
+
253
+ // جستجو در متن برای پیدا کردن لینکی که کد پایتون چاپ کرده بود
254
+ const urlMatch = logsText.match(/\[FINAL_IMAGE_URL\]\s*(https:\/\/[^\s]+)/);
255
+
256
+ if (urlMatch && urlMatch[1]) {
257
+ const imageUrl = urlMatch[1];
258
+ statusBox.style.display = 'none'; // مخفی کردن وضعیت
259
+ document.getElementById('result-container').style.display = 'block'; // نمایش عکس
260
+ document.getElementById('generated-image').src = imageUrl;
261
  } else {
 
262
  statusBox.className = 'status-error';
263
+ statusBox.innerHTML = 'عملیات موفق بود اما نتوانستیم لینک تصویر را از سرور استخراج کنیم!';
264
  }
265
+ } catch (e) {
266
  statusBox.className = 'status-error';
267
+ statusBox.innerHTML = 'خطا در خواندن فایل‌های نهایی از گیت‌هاب.';
268
  } finally {
269
+ document.getElementById('btn-submit').disabled = false;
 
270
  }
271
  }
272
  </script>