Sada8888 commited on
Commit
29a5ac5
·
verified ·
1 Parent(s): 4794b33

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +159 -76
templates/index.html CHANGED
@@ -2,108 +2,191 @@
2
  <html lang="fa" dir="rtl">
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
- 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: 550px; 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 { width: 100%; padding: 12px; border: 1px solid #E2E8F0; border-radius: 8px; box-sizing: border-box; background: #F7FAFC; font-family: inherit;}
15
- textarea:focus { outline: none; border-color: #5A67D8; box-shadow: 0 0 0 3px rgba(90, 103, 216, 0.2); background: #fff;}
16
- .size-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
17
- .size-btn { padding: 10px; border: 1px solid #E2E8F0; border-radius: 8px; background: #F7FAFC; cursor: pointer; font-weight: 600; transition: 0.2s; font-family: inherit;}
18
- .size-btn.active { background: #5A67D8; color: white; border-color: #5A67D8; }
19
- 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; transition: 0.2s;}
20
- button.main-btn:hover { background: #4C51BF; }
21
- button.main-btn:disabled { background: #A3B1E1; cursor: not-allowed; }
22
- #status-box { margin-top: 20px; padding: 15px; border-radius: 8px; display: none; text-align: center; background: #EBF4FF; color: #3182CE; font-weight: bold; }
23
- #result-container { margin-top: 20px; display: none; text-align: center; }
24
- #result-container img { width: 100%; border-radius: 8px; border: 2px solid #E2E8F0; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
 
 
 
 
 
 
25
  </style>
26
  </head>
27
- <body>
28
- <div class="container">
29
- <h2>🎨 استودیو تصویر هوش مصنوعی</h2>
30
-
31
- <div class="form-group">
32
- <label>دستور ساخت تصویر (Prompt)</label>
33
- <textarea id="prompt" rows="4" placeholder="مثال: A futuristic cyberpunk city, glowing neon lights..."></textarea>
34
- </div>
35
 
36
- <div class="form-group">
37
- <label>ابعاد تصویر</label>
38
- <div class="size-grid">
39
- <button class="size-btn active" data-w="1024" data-h="1024" onclick="selectSize(this)">۱:۱ (مربع)</button>
40
- <button class="size-btn" data-w="1344" data-h="768" onclick="selectSize(this)">۱۶:۹ (افقی)</button>
41
- <button class="size-btn" data-w="768" data-h="1344" onclick="selectSize(this)">۹:۱۶ (عمودی)</button>
42
- <button class="size-btn" data-w="1152" data-h="864" onclick="selectSize(this)">۴:۳ (کلاسیک)</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  </div>
44
  </div>
45
-
46
- <button id="btn-submit" class="main-btn" onclick="generateImage()">🚀 ساخت تصویر</button>
47
-
48
- <div id="status-box"></div>
49
-
50
- <div id="result-container">
51
- <h3 style="color: #38A169; margin-bottom: 15px;">🎉 تصویر شما آماده است!</h3>
52
- <img id="generated-image" src="" alt="AI Generated Image">
53
- </div>
54
  </div>
55
 
56
  <script>
57
- let w = 1024, h = 1024, timer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
- function selectSize(btn) {
60
- document.querySelectorAll('.size-btn').forEach(b => b.classList.remove('active'));
61
- btn.classList.add('active');
62
- w = btn.getAttribute('data-w');
63
- h = btn.getAttribute('data-h');
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  }
65
 
66
- async function generateImage() {
67
- const prompt = document.getElementById('prompt').value.trim();
68
- if (!prompt) return alert('لطفاً پرامپت را وارد کنید!');
69
-
70
- document.getElementById('btn-submit').disabled = true;
71
- document.getElementById('result-container').style.display = 'none';
72
-
73
- const statusBox = document.getElementById('status-box');
74
- statusBox.style.display = 'block';
75
- statusBox.innerHTML = 'در حال ارتباط با سرور پردازش... ⏳';
76
 
77
  try {
 
78
  const res = await fetch('/api/generate', {
79
- method: 'POST', headers: {'Content-Type': 'application/json'},
80
- body: JSON.stringify({ prompt, width: w, height: h })
 
 
 
 
 
 
81
  });
 
82
  const data = await res.json();
83
 
84
  if (data.status === 'success') {
85
- statusBox.innerHTML = 'در حال ساخت تصویر... لطفاً صبر کنید (حدود ۴۵ ثانیه) 🎨';
86
- timer = setInterval(() => checkStatus(data.run_id), 3000);
 
87
  } else {
88
- statusBox.innerHTML = 'خطا در برقراری ارتباط با سرور اصلی!';
89
- document.getElementById('btn-submit').disabled = false;
 
90
  }
91
  } catch (e) {
92
- statusBox.innerHTML = 'خطای اینترنت یا سرور.';
93
- document.getElementById('btn-submit').disabled = false;
 
94
  }
95
- }
96
 
97
- async function checkStatus(run_id) {
98
- let res = await fetch(`/api/status/${run_id}`);
99
- let data = await res.json();
100
-
101
- if (data.status === 'ready') {
102
- clearInterval(timer);
103
- document.getElementById('status-box').style.display = 'none';
104
- document.getElementById('result-container').style.display = 'block';
105
- document.getElementById('generated-image').src = data.url;
106
- document.getElementById('btn-submit').disabled = false;
 
 
 
 
 
 
 
107
  }
108
  }
109
  </script>
 
2
  <html lang="fa" dir="rtl">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <title>مولد تصویر آلفا - Flux Pro</title>
 
6
  <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;600;800&display=swap" rel="stylesheet">
7
  <style>
8
+ /* دقیقاً همان CSS ارسالی شما */
9
+ :root {
10
+ --igadlm-alpha-color-primary: #5A67D8; --igadlm-alpha-color-primary-darker: #4C51BF;
11
+ --igadlm-alpha-color-secondary: #805AD5; --igadlm-alpha-color-secondary-darker: #6B46C1;
12
+ --igadlm-alpha-color-text: #1A202C; --igadlm-alpha-color-text-light: #4A5568;
13
+ --igadlm-alpha-color-text-muted: #718096; --igadlm-alpha-color-bg-card: #FFFFFF;
14
+ --igadlm-alpha-color-border: #CBD5E0; --igadlm-alpha-color-input-bg: #EDF2F7;
15
+ --igadlm-alpha-color-white: #FFFFFF; --igadlm-alpha-color-success: #38A169;
16
+ --igadlm-alpha-color-error: #E53E3E;
17
+ --igadlm-alpha-shadow-sm: 0 1px 3px 0 rgba(0,0,0,0.07);
18
+ --igadlm-alpha-shadow-md: 0 4px 8px -2px rgba(0,0,0,0.1);
19
+ --igadlm-alpha-shadow-lg: 0 10px 20px -5px rgba(0,0,0,0.1);
20
+ --igadlm-alpha-border-radius-md: 8px; --igadlm-alpha-border-radius-lg: 12px;
21
+ --igadlm-alpha-transition-speed: 0.25s;
22
+ }
23
+ body.standalone-igadlm-alpha-app { background-color: #f0f2f5; margin:0; padding:20px; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh;}
24
+ #imageGeneratorAppAlphaV2 { font-family: 'Vazirmatn', sans-serif; color: var(--igadlm-alpha-color-text); line-height: 1.6; direction: rtl; width: 100%; }
25
+ .app-content-wrapper { display: flex; justify-content: center; width: 100%; }
26
+ .app-content { width: 100%; max-width: 550px; padding: 0 15px; }
27
+ .app-header { text-align: center; margin-bottom: 30px; }
28
+ .app-header h1 { font-size: clamp(1.8em, 5.5vw, 2.3em); font-weight: 700; color: var(--igadlm-alpha-color-primary); margin-bottom: 8px; }
29
+ .app-header p { font-size: 0.95em; color: var(--igadlm-alpha-color-text-light); }
30
+ .form-section-card { background-color: var(--igadlm-alpha-color-bg-card); padding: 30px; border-radius: var(--igadlm-alpha-border-radius-lg); box-shadow: var(--igadlm-alpha-shadow-lg); border: 1px solid var(--igadlm-alpha-color-border); }
31
  .form-group { margin-bottom: 20px; }
32
+ .form-group label { display: block; font-size: 0.85rem; color: var(--igadlm-alpha-color-text-light); margin-bottom: 6px; font-weight: 600; }
33
+ #imagePromptAlpha { width: 100%; padding: 10px 14px; border: 1px solid var(--igadlm-alpha-color-border); border-radius: var(--igadlm-alpha-border-radius-md); font-size: 0.9rem; background-color: var(--igadlm-alpha-color-input-bg); min-height: 60px; resize: vertical; }
34
+ #imagePromptAlpha:focus { outline: none; border-color: var(--igadlm-alpha-color-primary); background-color: var(--igadlm-alpha-color-white); }
35
+ .dimension-buttons-simple { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
36
+ .dimension-button-simple { padding: 10px 8px; font-size: 0.9rem; font-weight: 500; border: 1px solid var(--igadlm-alpha-color-border); border-radius: var(--igadlm-alpha-border-radius-md); background-color: var(--igadlm-alpha-color-input-bg); cursor: pointer; text-align: center; }
37
+ .dimension-button-simple.selected { background: linear-gradient(60deg, var(--igadlm-alpha-color-primary) 0%, var(--igadlm-alpha-color-secondary) 100%); color: var(--igadlm-alpha-color-white); border-color: transparent; }
38
+ #generateBtnAlpha { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; padding: 11px 16px; border-radius: var(--igadlm-alpha-border-radius-md); font-size: 0.95rem; font-weight: 600; cursor: pointer; background: linear-gradient(60deg, var(--igadlm-alpha-color-primary) 0%, var(--igadlm-alpha-color-secondary) 100%); color: white; border: none; margin-top: 12px; }
39
+ #generateBtnAlpha:disabled { background: #cbd5e0; cursor: not-allowed; }
40
+ #aiLoaderAlpha { display: none; flex-direction: column; align-items: center; margin: 20px auto 10px auto; }
41
+ .ai-loader-bar-container-inline { display: flex; justify-content: center; align-items: flex-end; height: 25px; }
42
+ .ai-loader-bar-inline { width: 5px; height: 5px; background-color: var(--igadlm-alpha-color-primary); border-radius: 2.5px; margin: 0 2.5px; animation: igadlmAlphaV2LoaderAnim 1.2s infinite ease-in-out; }
43
+ .ai-loader-bar-inline:nth-child(2) { animation-delay: 0.2s; background-color: var(--igadlm-alpha-color-secondary); }
44
+ .ai-loader-bar-inline:nth-child(3) { animation-delay: 0.4s; }
45
+ #statusAlphaText { text-align: center; font-size: 0.85em; color: var(--igadlm-alpha-color-text-muted); font-weight: 500; margin-top: 10px; min-height: 1.4em; }
46
+ #imageResultContainerAlpha { margin-top: 15px; text-align: center; display: none; }
47
+ #generatedImageAlpha { max-width: 100%; height: auto; border-radius: var(--igadlm-alpha-border-radius-md); border: 1px solid var(--igadlm-alpha-color-border); }
48
+ #downloadImageBtnAlpha { display: inline-flex; align-items: center; justify-content: center; width: 100%; padding: 11px 16px; border-radius: var(--igadlm-alpha-border-radius-md); margin-top: 10px; background-color: var(--igadlm-alpha-color-white); color: var(--igadlm-alpha-color-primary); border: 1px solid var(--igadlm-alpha-color-border); cursor: pointer; text-decoration: none; font-weight: bold;}
49
+ @keyframes igadlmAlphaV2LoaderAnim { 0%, 100% { transform: scaleY(0.5); opacity: 0.5; } 50% { transform: scaleY(1.5); opacity: 1; height: 15px; } }
50
  </style>
51
  </head>
52
+ <body class="standalone-igadlm-alpha-app">
 
 
 
 
 
 
 
53
 
54
+ <div id="imageGeneratorAppAlphaV2">
55
+ <div class="app-content-wrapper">
56
+ <div class="app-content">
57
+ <div class="app-header">
58
+ <h1>🖼️ مولد تصویر آلفا</h1>
59
+ <p><span style="color: #339966; font-weight: bold;">Flux Pro</span></p>
60
+ <p>ایده خود را به یک تصویر خلاقانه تبدیل کنید</p>
61
+ </div>
62
+
63
+ <div class="form-section-card" id="alphaFormSectionCard">
64
+ <div class="form-group">
65
+ <label for="imagePromptAlpha">ایده خود را بنویسید (به فارسی):</label>
66
+ <textarea id="imagePromptAlpha" rows="3" placeholder="مثال: یک قلعه باستانی بر فراز ابرها"></textarea>
67
+ </div>
68
+
69
+ <div class="form-group">
70
+ <label>اندازه تصویر (نسبت):</label>
71
+ <div class="dimension-buttons-simple" id="alphaDimensionButtons"></div>
72
+ </div>
73
+
74
+ <button id="generateBtnAlpha">🎨 ساخت تصویر</button>
75
+
76
+ <div class="ai-loader-inline" id="aiLoaderAlpha">
77
+ <div class="ai-loader-bar-container-inline">
78
+ <div class="ai-loader-bar-inline"></div>
79
+ <div class="ai-loader-bar-inline"></div>
80
+ <div class="ai-loader-bar-inline"></div>
81
+ </div>
82
+ </div>
83
+
84
+ <div id="statusAlphaText">وضعیت: آماده برای تولید تصویر.</div>
85
+
86
+ <div id="imageResultContainerAlpha">
87
+ <img id="generatedImageAlpha" alt="تصویر ایجاد شده" />
88
+ <a id="downloadImageBtnAlpha" href="#" download="flux_image.webp">📥 دانلود تصویر</a>
89
+ </div>
90
+ </div>
91
  </div>
92
  </div>
 
 
 
 
 
 
 
 
 
93
  </div>
94
 
95
  <script>
96
+ const dimensionsMap = {
97
+ "1:1": { w: 1024, h: 1024, text: "۱:۱ (مربع)" },
98
+ "16:9": { w: 1344, h: 768, text: "۱۶:۹ (افقی)" },
99
+ "9:16": { w: 768, h: 1344, text: "۹:۱۶ (عمودی)" },
100
+ "4:3": { w: 1152, h: 864, text: "۴:۳ (کلاسیک)" }
101
+ };
102
+
103
+ let selectedW = 1024, selectedH = 1024;
104
+ const btnContainer = document.getElementById('alphaDimensionButtons');
105
+ const statusText = document.getElementById('statusAlphaText');
106
+ const loader = document.getElementById('aiLoaderAlpha');
107
+ const genBtn = document.getElementById('generateBtnAlpha');
108
+ const resultContainer = document.getElementById('imageResultContainerAlpha');
109
+ const imgEl = document.getElementById('generatedImageAlpha');
110
+ const downloadBtn = document.getElementById('downloadImageBtnAlpha');
111
+ let pollTimer;
112
 
113
+ // ساخت دکمه‌های ابعاد
114
+ Object.keys(dimensionsMap).forEach((key, index) => {
115
+ const btn = document.createElement('button');
116
+ btn.className = 'dimension-button-simple' + (index === 0 ? ' selected' : '');
117
+ btn.textContent = dimensionsMap[key].text;
118
+ btn.onclick = () => {
119
+ document.querySelectorAll('.dimension-button-simple').forEach(b => b.classList.remove('selected'));
120
+ btn.classList.add('selected');
121
+ selectedW = dimensionsMap[key].w;
122
+ selectedH = dimensionsMap[key].h;
123
+ };
124
+ btnContainer.appendChild(btn);
125
+ });
126
+
127
+ function updateStatus(text, type='info') {
128
+ statusText.textContent = text;
129
+ statusText.style.color = type === 'error' ? 'var(--igadlm-alpha-color-error)' :
130
+ type === 'success' ? 'var(--igadlm-alpha-color-success)' : 'var(--igadlm-alpha-color-text-muted)';
131
  }
132
 
133
+ genBtn.onclick = async () => {
134
+ const prompt = document.getElementById('imagePromptAlpha').value.trim();
135
+ if(!prompt) return updateStatus('لطفا ایده خود را بنویسید!', 'error');
136
+
137
+ genBtn.disabled = true;
138
+ resultContainer.style.display = 'none';
139
+ loader.style.display = 'flex';
140
+ updateStatus('در حال ترجمه متن به انگلیسی... (مرحله ۱ از ۳)');
 
 
141
 
142
  try {
143
+ // ارسال به پایتون خودمان (پایتون هم ترجمه میکنه و هم میفرسته گیت هاب)
144
  const res = await fetch('/api/generate', {
145
+ method: 'POST',
146
+ headers: {'Content-Type': 'application/json'},
147
+ body: JSON.stringify({
148
+ prompt: prompt,
149
+ width: selectedW,
150
+ height: selectedH,
151
+ action_name: "generate-flux" // نام اکشن برای گیت هاب
152
+ })
153
  });
154
+
155
  const data = await res.json();
156
 
157
  if (data.status === 'success') {
158
+ updateStatus(`متن ترجمه شد: "${data.translated_prompt.substring(0, 25)}..."\nدر حال ساخت تصویر در سرور پردازشی... (مرحله ۲ از ۳)`);
159
+ // شروع به چک کردن نتیجه
160
+ pollTimer = setInterval(() => checkResult(data.run_id), 3000);
161
  } else {
162
+ updateStatus('خطا در ارتباط با سرور پردازشی.', 'error');
163
+ genBtn.disabled = false;
164
+ loader.style.display = 'none';
165
  }
166
  } catch (e) {
167
+ updateStatus('خطای ارتباط با سرور.', 'error');
168
+ genBtn.disabled = false;
169
+ loader.style.display = 'none';
170
  }
171
+ };
172
 
173
+ async function checkResult(run_id) {
174
+ try {
175
+ const res = await fetch(`/api/status/${run_id}`);
176
+ const data = await res.json();
177
+
178
+ if (data.status === 'ready') {
179
+ clearInterval(pollTimer);
180
+ loader.style.display = 'none';
181
+ updateStatus('تصویر با موفقیت ساخته شد! 🎉 (مرحله ۳ از ۳)', 'success');
182
+
183
+ imgEl.src = data.url;
184
+ downloadBtn.href = data.url;
185
+ resultContainer.style.display = 'block';
186
+ genBtn.disabled = false;
187
+ }
188
+ } catch(e) {
189
+ console.log('Polling...', e);
190
  }
191
  }
192
  </script>