Sada8888 commited on
Commit
e09ab3a
·
verified ·
1 Parent(s): aa4622d

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +63 -27
templates/index.html CHANGED
@@ -6,20 +6,23 @@
6
  <title>استودیو تصویر هوش مصنوعی</title>
7
  <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;600;800&display=swap" rel="stylesheet">
8
  <style>
9
- body { font-family: 'Vazirmatn', Tahoma, sans-serif; background-color: #EDF2F7; padding: 40px 20px; display: flex; justify-content: center; }
10
- .container { background-color: #ffffff; border-radius: 12px; box-shadow: 0 10px 15px rgba(0,0,0,0.1); width: 100%; max-width: 500px; padding: 30px; }
11
  h2 { text-align: center; color: #5A67D8; margin-top: 0; }
12
  .form-group { margin-bottom: 20px; }
13
- label { display: block; margin-bottom: 8px; font-weight: 600; }
14
- textarea { width: 100%; padding: 12px; border: 1px solid #E2E8F0; border-radius: 8px; box-sizing: border-box; background: #F7FAFC; }
15
  .size-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
16
- .size-btn { padding: 10px; border: 1px solid #E2E8F0; border-radius: 8px; background: #F7FAFC; cursor: pointer; font-weight: 600; transition: 0.2s; }
17
  .size-btn.active { background: #5A67D8; color: white; border-color: #5A67D8; }
18
  button.main-btn { width: 100%; padding: 14px; background: #5A67D8; color: white; border: none; border-radius: 8px; font-size: 1.1rem; font-weight: bold; cursor: pointer; }
19
  button.main-btn:disabled { background: #A3B1E1; cursor: not-allowed; }
20
  #status-box { margin-top: 20px; padding: 15px; border-radius: 8px; display: none; text-align: center; background: #EBF4FF; color: #3182CE; font-weight: bold; }
21
- #result-container { margin-top: 20px; display: none; text-align: center; }
22
- #result-container img { max-width: 100%; border-radius: 8px; border: 2px solid #E2E8F0; }
 
 
 
23
  </style>
24
  </head>
25
  <body>
@@ -27,25 +30,39 @@
27
  <h2>استودیو تصویر هوش مصنوعی</h2>
28
  <div class="form-group">
29
  <label>دستور ساخت تصویر (Prompt)</label>
30
- <textarea id="prompt" rows="4" placeholder="مثال: A futuristic cyberpunk city..."></textarea>
 
 
 
 
 
 
 
 
 
 
 
 
31
  </div>
 
32
  <div class="form-group">
33
  <label>ابعاد تصویر</label>
34
  <div class="size-grid">
35
- <button class="size-btn active" data-w="1024" data-h="1024" onclick="selectSize(this)">۱:۱ مربع</button>
36
- <button class="size-btn" data-w="1344" data-h="768" onclick="selectSize(this)">۱۶:۹ افقی</button>
 
 
37
  </div>
38
  </div>
39
- <button id="btn-submit" class="main-btn" onclick="generateImage()">🚀 ساخت تصویر</button>
 
 
40
  <div id="status-box"></div>
41
- <div id="result-container">
42
- <h3 style="color: #2ea44f;">🎉 تصویر شما آماده است!</h3>
43
- <img id="generated-image" src="" alt="AI Image">
44
- </div>
45
  </div>
46
 
47
  <script>
48
- let w = 1024, h = 1024, timer;
49
 
50
  function selectSize(btn) {
51
  document.querySelectorAll('.size-btn').forEach(b => b.classList.remove('active'));
@@ -56,25 +73,28 @@
56
 
57
  async function generateImage() {
58
  const prompt = document.getElementById('prompt').value.trim();
 
59
  if (!prompt) return alert('پرامپت خالی است!');
60
 
 
 
 
61
  document.getElementById('btn-submit').disabled = true;
62
- document.getElementById('result-container').style.display = 'none';
 
63
  const statusBox = document.getElementById('status-box');
64
  statusBox.style.display = 'block';
65
- statusBox.innerHTML = 'در حال ارتباط با سرور... ⏳';
66
 
67
  try {
68
- // درخواست به بک‌اندِ داکر اسپیسِ خودمان
69
  const res = await fetch('/api/generate', {
70
  method: 'POST', headers: {'Content-Type': 'application/json'},
71
- body: JSON.stringify({ prompt, width: w, height: h })
72
  });
73
  const data = await res.json();
74
 
75
  if (data.status === 'success') {
76
- statusBox.innerHTML = 'گیت‌هاب در حال ساخت و آپلود تصویر است... (حدود ۳۰ تا ۶۰ ثانیه) 🎨';
77
- // بررسی دوره‌ای تا زمانی که گیت هاب عکس را در سرور آپلود کند
78
  timer = setInterval(() => checkStatus(data.run_id), 3000);
79
  } else {
80
  statusBox.innerHTML = 'خطا در ارسال به گیت‌هاب!';
@@ -87,14 +107,30 @@
87
  }
88
 
89
  async function checkStatus(run_id) {
90
- let res = await fetch(`/api/status/${run_id}`);
 
91
  let data = await res.json();
92
 
93
- if (data.status === 'ready') {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  clearInterval(timer);
95
- document.getElementById('status-box').style.display = 'none';
96
- document.getElementById('result-container').style.display = 'block';
97
- document.getElementById('generated-image').src = data.url; // نمایش عکسی که در داکر ذخیره شده
98
  document.getElementById('btn-submit').disabled = false;
99
  }
100
  }
 
6
  <title>استودیو تصویر هوش مصنوعی</title>
7
  <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;600;800&display=swap" rel="stylesheet">
8
  <style>
9
+ body { font-family: 'Vazirmatn', Tahoma, sans-serif; background-color: #EDF2F7; padding: 40px 20px; display: flex; justify-content: center; margin: 0;}
10
+ .container { background-color: #ffffff; border-radius: 12px; box-shadow: 0 10px 15px rgba(0,0,0,0.1); width: 100%; max-width: 600px; padding: 30px; }
11
  h2 { text-align: center; color: #5A67D8; margin-top: 0; }
12
  .form-group { margin-bottom: 20px; }
13
+ label { display: block; margin-bottom: 8px; font-weight: 600; font-size: 0.95rem;}
14
+ textarea, select { width: 100%; padding: 12px; border: 1px solid #E2E8F0; border-radius: 8px; box-sizing: border-box; background: #F7FAFC; font-family: inherit;}
15
  .size-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
16
+ .size-btn { padding: 10px; border: 1px solid #E2E8F0; border-radius: 8px; background: #F7FAFC; cursor: pointer; font-weight: 600; transition: 0.2s; font-family: inherit;}
17
  .size-btn.active { background: #5A67D8; color: white; border-color: #5A67D8; }
18
  button.main-btn { width: 100%; padding: 14px; background: #5A67D8; color: white; border: none; border-radius: 8px; font-size: 1.1rem; font-weight: bold; cursor: pointer; }
19
  button.main-btn:disabled { background: #A3B1E1; cursor: not-allowed; }
20
  #status-box { margin-top: 20px; padding: 15px; border-radius: 8px; display: none; text-align: center; background: #EBF4FF; color: #3182CE; font-weight: bold; }
21
+
22
+ .result-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; margin-top: 20px; }
23
+ .result-item { width: 100%; border-radius: 8px; overflow: hidden; border: 2px solid #E2E8F0; box-shadow: 0 4px 6px rgba(0,0,0,0.1); animation: fadeIn 0.5s ease; }
24
+ .result-item img { width: 100%; height: auto; display: block; }
25
+ @keyframes fadeIn { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } }
26
  </style>
27
  </head>
28
  <body>
 
30
  <h2>استودیو تصویر هوش مصنوعی</h2>
31
  <div class="form-group">
32
  <label>دستور ساخت تصویر (Prompt)</label>
33
+ <textarea id="prompt" rows="3" placeholder="مثال: A futuristic cyberpunk city..."></textarea>
34
+ </div>
35
+
36
+ <div style="display: flex; gap: 15px; margin-bottom: 20px;">
37
+ <div style="flex: 1;">
38
+ <label>تعداد تصاویر</label>
39
+ <select id="num-images">
40
+ <option value="1">۱ تصویر (سریع)</option>
41
+ <option value="2">۲ تصویر</option>
42
+ <option value="3">۳ تصویر</option>
43
+ <option value="4" selected>۴ تصویر (پیش‌فرض)</option>
44
+ </select>
45
+ </div>
46
  </div>
47
+
48
  <div class="form-group">
49
  <label>ابعاد تصویر</label>
50
  <div class="size-grid">
51
+ <button class="size-btn active" data-w="1024" data-h="1024" onclick="selectSize(this)">۱:۱ (مربع)</button>
52
+ <button class="size-btn" data-w="1344" data-h="768" onclick="selectSize(this)">۱۶:۹ (افقی)</button>
53
+ <button class="size-btn" data-w="768" data-h="1344" onclick="selectSize(this)">۹:۱۶ (عمودی)</button>
54
+ <button class="size-btn" data-w="1152" data-h="864" onclick="selectSize(this)">۴:۳ (کلاسیک)</button>
55
  </div>
56
  </div>
57
+
58
+ <button id="btn-submit" class="main-btn" onclick="generateImage()">🚀 ساخت تصاویر</button>
59
+
60
  <div id="status-box"></div>
61
+ <div id="result-container" class="result-grid"></div>
 
 
 
62
  </div>
63
 
64
  <script>
65
+ let w = 1024, h = 1024, timer, expectedTotal = 1, receivedImages = 0;
66
 
67
  function selectSize(btn) {
68
  document.querySelectorAll('.size-btn').forEach(b => b.classList.remove('active'));
 
73
 
74
  async function generateImage() {
75
  const prompt = document.getElementById('prompt').value.trim();
76
+ const numImgs = parseInt(document.getElementById('num-images').value);
77
  if (!prompt) return alert('پرامپت خالی است!');
78
 
79
+ expectedTotal = numImgs;
80
+ receivedImages = 0;
81
+
82
  document.getElementById('btn-submit').disabled = true;
83
+ document.getElementById('result-container').innerHTML = ''; // پاک کردن نتایج قبلی
84
+
85
  const statusBox = document.getElementById('status-box');
86
  statusBox.style.display = 'block';
87
+ statusBox.innerHTML = 'در حال راه‌اندازی سرور پردازش... ⏳';
88
 
89
  try {
 
90
  const res = await fetch('/api/generate', {
91
  method: 'POST', headers: {'Content-Type': 'application/json'},
92
+ body: JSON.stringify({ prompt, width: w, height: h, num_images: numImgs })
93
  });
94
  const data = await res.json();
95
 
96
  if (data.status === 'success') {
97
+ statusBox.innerHTML = `در حال ساخت ${numImgs} تصویر... لطفاً صفحه را نبندید 🎨`;
 
98
  timer = setInterval(() => checkStatus(data.run_id), 3000);
99
  } else {
100
  statusBox.innerHTML = 'خطا در ارسال به گیت‌هاب!';
 
107
  }
108
 
109
  async function checkStatus(run_id) {
110
+ // می‌پرسیم از بین کل تعداد، چه تعداد آماده شده؟
111
+ let res = await fetch(`/api/status/${run_id}?total=${expectedTotal}`);
112
  let data = await res.json();
113
 
114
+ const container = document.getElementById('result-container');
115
+
116
+ // اگر عکس جدیدی اضافه شده بود، آن را روی صفحه بکش
117
+ if (data.images.length > receivedImages) {
118
+ for (let i = receivedImages; i < data.images.length; i++) {
119
+ const item = document.createElement('div');
120
+ item.className = 'result-item';
121
+ item.innerHTML = `<img src="${data.images[i]}" alt="AI Generated Image">`;
122
+ container.appendChild(item);
123
+ }
124
+ receivedImages = data.images.length;
125
+ document.getElementById('status-box').innerHTML = `تصاویر دریافت شده: ${receivedImages} از ${expectedTotal} 📥`;
126
+ }
127
+
128
+ // اگر تمام عکس‌ها ساخته و دریافت شد
129
+ if (data.status === 'done') {
130
  clearInterval(timer);
131
+ document.getElementById('status-box').innerHTML = '🎉 تمام تصاویر با موفقیت ساخته شدند!';
132
+ document.getElementById('status-box').style.background = '#F0FFF4';
133
+ document.getElementById('status-box').style.color = '#276749';
134
  document.getElementById('btn-submit').disabled = false;
135
  }
136
  }