feat(imggen): генерация картинок ИИ (FLUX.1) — ассистент, флэшкарты, редактор уроков
Бэкенд /api/imggen (status/generate, CF Workers AI, cooldown+дневной лимит). Переиспользуемый модал LS.imagePromptModal (js/imggen.js). Квантик: режим «Нарисовать» в чате (inline). Флэшкарты: кнопка «ИИ» в блоке картинки карточки. Редактор уроков: кнопка «Сгенерировать» в блоке изображения. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -560,6 +560,7 @@
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/lucide@0.469.0/dist/umd/lucide.min.js"></script>
|
||||
<script src="/js/api.js"></script>
|
||||
<script src="/js/imggen.js"></script>
|
||||
<script src="/js/sidebar.js"></script>
|
||||
<script src="/js/notifications.js"></script>
|
||||
<script src="/js/search.js"></script>
|
||||
@@ -951,13 +952,32 @@ function imgRowHtml(c, side) {
|
||||
</button>
|
||||
</div></div>`;
|
||||
}
|
||||
return `<div class="card-img-row">
|
||||
return `<div class="card-img-row" style="display:flex;gap:6px;flex-wrap:wrap">
|
||||
<button class="card-img-add" onclick="pickCardImage(${c.id},'${side}')">
|
||||
<svg class="ic" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="m21 15-5-5L5 21"/></svg>
|
||||
Картинка
|
||||
</button>
|
||||
<button class="card-img-add" onclick="genCardImage(${c.id},'${side}')" title="Сгенерировать с ИИ">
|
||||
<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M13 3l2.2 6.3L22 12l-6.8 2.7L13 21l-2.2-6.3L4 12l6.8-2.7z"/><path d="M5 4v3M3.5 5.5h3"/></svg>
|
||||
ИИ
|
||||
</button></div>`;
|
||||
}
|
||||
|
||||
function genCardImage(cardId, side) {
|
||||
if (!LS.imagePromptModal) { LS.toast('Модуль генерации не загружен'); return; }
|
||||
const card = _cards.find(c => c.id === cardId);
|
||||
LS.imagePromptModal({
|
||||
title: 'Картинка для карточки',
|
||||
placeholder: card && card[side === 'front' ? 'front' : 'back'] ? 'Иллюстрация к: ' + (card[side === 'front' ? 'front' : 'back'] || '') : '',
|
||||
onUse: async function (url) {
|
||||
const c = _cards.find(x => x.id === cardId); if (!c) return;
|
||||
const field = side === 'front' ? 'front_image' : 'back_image';
|
||||
await LS.api(`/api/flashcards/cards/${cardId}`, { method: 'PUT', body: JSON.stringify({ [field]: url }) }).catch(()=>{});
|
||||
c[field] = url; updateCardImgRow(cardId, side); LS.toast('Картинка добавлена', 'success');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function uploadFcImage(file) {
|
||||
if (!file || !file.type || !file.type.startsWith('image/')) throw new Error('Только изображения');
|
||||
if (file.size > 5 * 1024 * 1024) throw new Error('Файл больше 5 МБ');
|
||||
|
||||
Reference in New Issue
Block a user