Update index.html
Browse files- index.html +75 -70
index.html
CHANGED
|
@@ -3,18 +3,18 @@
|
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
-
<title>پنل ساخت وی
|
| 7 |
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;600;800&display=swap" rel="stylesheet">
|
| 8 |
<style>
|
| 9 |
:root {
|
| 10 |
-
--primary: #
|
| 11 |
-
--primary-hover: #
|
| 12 |
-
--bg-color: #
|
| 13 |
--panel-bg: #ffffff;
|
| 14 |
-
--border: #
|
| 15 |
-
--text-main: #
|
| 16 |
-
--text-muted: #
|
| 17 |
-
--radius:
|
| 18 |
}
|
| 19 |
|
| 20 |
body {
|
|
@@ -34,131 +34,135 @@
|
|
| 34 |
background-color: var(--panel-bg);
|
| 35 |
border: 1px solid var(--border);
|
| 36 |
border-radius: var(--radius);
|
| 37 |
-
box-shadow: 0
|
| 38 |
width: 100%;
|
| 39 |
max-width: 550px;
|
| 40 |
padding: 30px;
|
| 41 |
}
|
| 42 |
|
| 43 |
-
h2 { text-align: center; margin-top: 0; margin-bottom: 25px; color: var(--
|
| 44 |
.form-group { margin-bottom: 20px; }
|
| 45 |
label { display: block; margin-bottom: 8px; font-weight: 600; font-size: 0.95rem; }
|
| 46 |
|
| 47 |
input[type="text"], input[type="password"], textarea {
|
| 48 |
width: 100%; padding: 12px; border: 1px solid var(--border); border-radius: var(--radius);
|
| 49 |
-
font-family: inherit; font-size: 1rem; box-sizing: border-box; background-color: #
|
| 50 |
}
|
| 51 |
input[type="text"]:focus, input[type="password"]:focus, textarea:focus {
|
| 52 |
-
outline: none; border-color:
|
| 53 |
}
|
| 54 |
|
| 55 |
-
.
|
| 56 |
-
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
-
button {
|
| 60 |
width: 100%; padding: 14px; background-color: var(--primary); color: #ffffff; border: none;
|
| 61 |
border-radius: var(--radius); font-size: 1.1rem; font-weight: bold; cursor: pointer; margin-top: 10px;
|
|
|
|
| 62 |
}
|
| 63 |
-
button:hover { background-color: var(--primary-hover); }
|
| 64 |
-
button:disabled { background-color: #
|
| 65 |
|
| 66 |
hr { border: 0; border-top: 1px solid var(--border); margin: 25px 0; }
|
| 67 |
.notice { font-size: 0.85rem; color: var(--text-muted); margin-top: 5px; display: block; }
|
| 68 |
|
| 69 |
#status-box { margin-top: 25px; padding: 15px; border-radius: var(--radius); display: none; line-height: 1.6; text-align: center; }
|
| 70 |
-
.status-loading { background-color: #
|
| 71 |
-
.status-success { background-color: #
|
| 72 |
-
.status-error { background-color: #
|
| 73 |
.action-link {
|
| 74 |
-
display: inline-block; margin-top: 15px; padding:
|
| 75 |
-
border
|
| 76 |
}
|
| 77 |
</style>
|
| 78 |
</head>
|
| 79 |
<body>
|
| 80 |
|
| 81 |
<div class="container">
|
| 82 |
-
<h2>استودیو تو
|
| 83 |
|
| 84 |
<div class="form-group">
|
| 85 |
-
<label
|
| 86 |
-
<input type="text" id="gh-username" value="Hamed744" readonly style="
|
| 87 |
</div>
|
| 88 |
|
| 89 |
<div class="form-group">
|
| 90 |
-
<label
|
| 91 |
-
<input type="text" id="gh-repo" value="vid-test" readonly style="
|
| 92 |
</div>
|
| 93 |
|
| 94 |
<div class="form-group">
|
| 95 |
-
<label
|
| 96 |
<input type="password" id="gh-token" placeholder="ghp_....................................">
|
| 97 |
-
<span class="notice">توکن شما در مرورگر خودتان
|
| 98 |
</div>
|
| 99 |
|
| 100 |
<hr>
|
| 101 |
|
| 102 |
<div class="form-group">
|
| 103 |
-
<label
|
| 104 |
-
<
|
| 105 |
-
<input type="file" id="imageFile" accept="image/png, image/jpeg, image/webp">
|
| 106 |
-
</div>
|
| 107 |
</div>
|
| 108 |
|
| 109 |
<div class="form-group">
|
| 110 |
-
<label
|
| 111 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
</div>
|
| 113 |
|
| 114 |
-
<button id="btn-submit" onclick="triggerGitHubAction()">ارسال درخواست ساخت
|
| 115 |
|
| 116 |
<div id="status-box"></div>
|
| 117 |
</div>
|
| 118 |
|
| 119 |
<script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
async function triggerGitHubAction() {
|
| 121 |
const username = document.getElementById('gh-username').value;
|
| 122 |
const repo = document.getElementById('gh-repo').value;
|
| 123 |
const token = document.getElementById('gh-token').value.trim();
|
| 124 |
const prompt = document.getElementById('prompt').value.trim();
|
| 125 |
-
const fileInput = document.getElementById('imageFile');
|
| 126 |
const statusBox = document.getElementById('status-box');
|
| 127 |
const submitBtn = document.getElementById('btn-submit');
|
| 128 |
|
| 129 |
-
if (!token || !prompt
|
| 130 |
-
alert('لطفاً توکن
|
| 131 |
return;
|
| 132 |
}
|
| 133 |
|
| 134 |
submitBtn.disabled = true;
|
| 135 |
statusBox.style.display = 'block';
|
| 136 |
statusBox.className = 'status-loading';
|
|
|
|
| 137 |
|
| 138 |
try {
|
| 139 |
-
// مرحله اول: آپلود موقت تصویر برای دریافت لینک
|
| 140 |
-
statusBox.innerHTML = 'در حال آپلود موقت تصویر... (مرحله ۱ از ۲)';
|
| 141 |
-
const formData = new FormData();
|
| 142 |
-
formData.append('file', fileInput.files[0]);
|
| 143 |
-
|
| 144 |
-
// استفاده از سرور موقت و رایگان tmpfiles.org
|
| 145 |
-
const uploadRes = await fetch('https://tmpfiles.org/api/v1/upload', {
|
| 146 |
-
method: 'POST',
|
| 147 |
-
body: formData
|
| 148 |
-
});
|
| 149 |
-
const uploadData = await uploadRes.json();
|
| 150 |
-
|
| 151 |
-
if (uploadData.status !== 'success') {
|
| 152 |
-
throw new Error('آپلود تصویر ناموفق بود.');
|
| 153 |
-
}
|
| 154 |
-
|
| 155 |
-
// تبدیل لینک آپلود به لینک دانلود مستقیم
|
| 156 |
-
const imageUrl = uploadData.data.url.replace('tmpfiles.org/', 'tmpfiles.org/dl/');
|
| 157 |
-
|
| 158 |
-
// مرحله دوم: ارسال لینک تصویر و دستور به گیتهاب
|
| 159 |
-
statusBox.innerHTML = 'در حال ارسال دستور ساخت به گیتهاب... (مرحله ۲ از ۲)';
|
| 160 |
const apiUrl = `https://api.github.com/repos/${username}/${repo}/dispatches`;
|
| 161 |
|
|
|
|
| 162 |
const response = await fetch(apiUrl, {
|
| 163 |
method: 'POST',
|
| 164 |
headers: {
|
|
@@ -167,10 +171,11 @@
|
|
| 167 |
'Content-Type': 'application/json'
|
| 168 |
},
|
| 169 |
body: JSON.stringify({
|
| 170 |
-
event_type: 'generate-
|
| 171 |
client_payload: {
|
| 172 |
prompt: prompt,
|
| 173 |
-
|
|
|
|
| 174 |
}
|
| 175 |
})
|
| 176 |
});
|
|
@@ -178,22 +183,22 @@
|
|
| 178 |
if (response.ok) {
|
| 179 |
statusBox.className = 'status-success';
|
| 180 |
statusBox.innerHTML = `
|
| 181 |
-
<strong>
|
| 182 |
-
|
| 183 |
-
برای مشاهده
|
| 184 |
-
<a href="https://github.com/${username}/${repo}/actions" target="_blank" class="action-link">
|
| 185 |
`;
|
| 186 |
} else {
|
| 187 |
const errorText = await response.text();
|
| 188 |
statusBox.className = 'status-error';
|
| 189 |
-
statusBox.innerHTML = `<strong>خطا در ارسال!</strong><br>کد خطا: ${response.status}<br><small>
|
| 190 |
}
|
| 191 |
} catch (error) {
|
| 192 |
statusBox.className = 'status-error';
|
| 193 |
-
statusBox.innerHTML = `<strong>خطای ارت
|
| 194 |
} finally {
|
| 195 |
submitBtn.disabled = false;
|
| 196 |
-
submitBtn.
|
| 197 |
}
|
| 198 |
}
|
| 199 |
</script>
|
|
|
|
| 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 {
|
| 10 |
+
--primary: #5A67D8;
|
| 11 |
+
--primary-hover: #4C51BF;
|
| 12 |
+
--bg-color: #EDF2F7;
|
| 13 |
--panel-bg: #ffffff;
|
| 14 |
+
--border: #E2E8F0;
|
| 15 |
+
--text-main: #1A202C;
|
| 16 |
+
--text-muted: #718096;
|
| 17 |
+
--radius: 12px;
|
| 18 |
}
|
| 19 |
|
| 20 |
body {
|
|
|
|
| 34 |
background-color: var(--panel-bg);
|
| 35 |
border: 1px solid var(--border);
|
| 36 |
border-radius: var(--radius);
|
| 37 |
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
|
| 38 |
width: 100%;
|
| 39 |
max-width: 550px;
|
| 40 |
padding: 30px;
|
| 41 |
}
|
| 42 |
|
| 43 |
+
h2 { text-align: center; margin-top: 0; margin-bottom: 25px; color: var(--primary); font-weight: 800; }
|
| 44 |
.form-group { margin-bottom: 20px; }
|
| 45 |
label { display: block; margin-bottom: 8px; font-weight: 600; font-size: 0.95rem; }
|
| 46 |
|
| 47 |
input[type="text"], input[type="password"], textarea {
|
| 48 |
width: 100%; padding: 12px; border: 1px solid var(--border); border-radius: var(--radius);
|
| 49 |
+
font-family: inherit; font-size: 1rem; box-sizing: border-box; background-color: #F7FAFC;
|
| 50 |
}
|
| 51 |
input[type="text"]:focus, input[type="password"]:focus, textarea:focus {
|
| 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>
|
| 89 |
<body>
|
| 90 |
|
| 91 |
<div class="container">
|
| 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">
|
| 118 |
+
<label>ابعاد تصویر</label>
|
| 119 |
+
<div class="size-grid">
|
| 120 |
+
<button class="size-btn active" data-w="1024" data-h="1024" onclick="selectSize(this)">۱:۱ (مربع)</button>
|
| 121 |
+
<button class="size-btn" data-w="1344" data-h="768" onclick="selectSize(this)">۱۶:۹ (افقی)</button>
|
| 122 |
+
<button class="size-btn" data-w="768" data-h="1344" onclick="selectSize(this)">۹:۱۶ (عمودی)</button>
|
| 123 |
+
<button class="size-btn" data-w="1152" data-h="864" onclick="selectSize(this)">۴:۳ (کلاسیک)</button>
|
| 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');
|
| 140 |
+
selectedWidth = parseInt(btn.getAttribute('data-w'));
|
| 141 |
+
selectedHeight = parseInt(btn.getAttribute('data-h'));
|
| 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: {
|
|
|
|
| 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 |
});
|
|
|
|
| 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>
|