From 2c520a96c0a1968b4a0950b5fe7c2b5a5c4dd7bb Mon Sep 17 00:00:00 2001 From: Dauren777 Date: Fri, 19 Jun 2026 06:28:35 +0000 Subject: [PATCH] fix: local generation, regenerate button, API via ?api= --- script.js | 159 ++++++++++++++++++++++++++++++------------------------ style.css | 11 ++++ 2 files changed, 101 insertions(+), 69 deletions(-) diff --git a/script.js b/script.js index e684b29..51c3de9 100644 --- a/script.js +++ b/script.js @@ -1,4 +1,6 @@ -const API_URL = window.location.origin + '/api'; +// Настройка: если запустили server.py на другом хосте/порте, +// укажите URL здесь или добавьте ?api=http://host:8000 к URL страницы +const API_URL = new URLSearchParams(window.location.search).get('api') || ''; const promptInput = document.getElementById('promptInput'); const tempSlider = document.getElementById('tempSlider'); @@ -10,94 +12,113 @@ const generate5Btn = document.getElementById('generate5Btn'); const outputArea = document.getElementById('outputArea'); const statusMsg = document.getElementById('statusMsg'); -tempSlider.addEventListener('input', () => { - tempVal.textContent = tempSlider.value; -}); - -topkSlider.addEventListener('input', () => { - topkVal.textContent = topkSlider.value; -}); +tempSlider.addEventListener('input', () => { tempVal.textContent = tempSlider.value; }); +topkSlider.addEventListener('input', () => { topkVal.textContent = topkSlider.value; }); generateBtn.addEventListener('click', () => generate(1)); generate5Btn.addEventListener('click', () => generate(5)); +// --------------------------------------------------------------------------- +// Client-side clickbait generator (fallback / default) +// --------------------------------------------------------------------------- + +const TEMPLATES = [ + 'этот секрет знают единицы', + 'врачи в шоке от этого открытия', + 'ты не поверишь что произошло дальше', + 'всего один ингредиент меняет всё', + 'вот почему никто не говорит об этом', + 'результат превзошёл все ожидания', + 'это должен знать каждый', + 'никто не ожидал такого поворота', + 'учёные озадачены этим феноменом', + 'это изменит вашу жизнь навсегда', + 'вы будете в шоке от правды', + 'самое важное о чём молчат СМИ', + 'это открытие перевернуло науку', + 'простые вещи которые творят чудеса', + 'теперь это знает весь мир', + 'о чём вам не расскажут в школе', + 'главный секрет успешных людей', + 'это работает безотказно', + 'вы упускаете это каждый день', + 'пора узнать правду' +]; + +const PREFIXES = ['', 'невероятно но ', 'шокирующе но ', 'оказывается ', 'представьте себе ']; + +function pick(arr, seed) { + const idx = Math.abs(seed * 7 + seed * seed * 31) % arr.length; + return arr[idx]; +} + +function localGenerate(prompt, temperature, top_k, count) { + const now = Date.now(); + const results = []; + for (let i = 0; i < count; i++) { + const seed = now + i * 137 + Math.floor(temperature * 100) + top_k; + const prefix = pick(PREFIXES, seed + 3); + const template = prompt + ? `${prompt} — ${pick(TEMPLATES, seed + 7)}` + : pick(TEMPLATES, seed + 11); + const extra = temperature > 1.3 + ? (pick(['невероятно', 'шокирующе', 'фантастически'], seed + 19) + ' ') + : ''; + results.push(prefix + extra + template); + } + return results; +} + +// --------------------------------------------------------------------------- +// Main generation +// --------------------------------------------------------------------------- + async function generate(count) { const prompt = promptInput.value.trim(); const temperature = parseFloat(tempSlider.value); const top_k = parseInt(topkSlider.value); outputArea.innerHTML = ''; - statusMsg.textContent = 'Генерация...'; + statusMsg.textContent = '⚡ Генерируем...'; statusMsg.className = 'status-msg'; - try { - const res = await fetch(`${API_URL}/generate`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - prompt, - temperature, - top_k, - num_samples: count - }) - }); + let texts; - if (!res.ok) { - const err = await res.json().catch(() => ({})); - throw new Error(err.detail || `Ошибка ${res.status}`); + if (API_URL) { + try { + const res = await fetch(`${API_URL}/generate`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ prompt, temperature, top_k, num_samples: count }) + }); + if (!res.ok) throw new Error(`HTTP ${res.status}`); + const data = await res.json(); + texts = data.texts; + } catch { + texts = localGenerate(prompt, temperature, top_k, count); } - - const data = await res.json(); - statusMsg.textContent = ''; - statusMsg.className = 'status-msg'; - - data.texts.forEach((text, i) => { - const div = document.createElement('div'); - div.className = 'gen-output-item'; - if (count > 1) { - div.innerHTML = `#${i + 1}${text}...😱`; - } else { - div.textContent = `${text}...😱`; - } - outputArea.appendChild(div); - }); - } catch (err) { - statusMsg.textContent = '❌ Сервер недоступен. Запустите API: python server.py'; - statusMsg.className = 'status-msg error'; - fallbackGenerate(count, prompt, temperature, top_k); + } else { + texts = localGenerate(prompt, temperature, top_k, count); } -} -function fallbackGenerate(count, prompt, temperature, top_k) { - const templates = [ - prompt - ? `${prompt} — этот секрет знают единицы` - : 'Этот секрет знают единицы', - prompt - ? `${prompt} — врачи в шоке от открытия` - : 'Врачи в шоке от этого открытия', - prompt - ? `${prompt} — ты не поверишь что произошло` - : 'Ты не поверишь что произошло дальше', - prompt - ? `${prompt} — всего один ингредиент меняет всё` - : 'Всего один ингредиент меняет всё', - prompt - ? `${prompt} — вот почему никто не говорит об этом` - : 'Вот почему никто не говорит об этом' - ]; + statusMsg.textContent = ''; + statusMsg.className = 'status-msg'; - outputArea.innerHTML = ''; - for (let i = 0; i < count && i < templates.length; i++) { + texts.forEach((text, i) => { const div = document.createElement('div'); div.className = 'gen-output-item'; - if (count > 1) { - div.innerHTML = `#${i + 1}${templates[i]}...😱`; - } else { - div.textContent = `${templates[i]}...😱`; - } + div.style.animationDelay = `${i * 0.08}s`; + const label = count > 1 ? `#${i + 1}` : ''; + div.innerHTML = `${label}${text}...😱`; outputArea.appendChild(div); - } + }); + + // Regenerate button + const reBtn = document.createElement('button'); + reBtn.className = 'btn btn-secondary btn-regenerate'; + reBtn.textContent = '🔄 Сгенерировать ещё'; + reBtn.addEventListener('click', () => generate(count)); + outputArea.appendChild(reBtn); } // Example tabs diff --git a/style.css b/style.css index 00b659c..09845f8 100644 --- a/style.css +++ b/style.css @@ -127,6 +127,17 @@ body { color: var(--cyan); } +.btn-regenerate { + margin-top: 16px; + font-size: 14px; + padding: 10px 20px; + align-self: flex-start; +} + +.gen-output .btn-regenerate { + align-self: flex-start; +} + /* Sections */ .section { padding: 80px 0;