Corrigindo salvamento de múltiplos projetos e continuidade de quadrinhos com consistência de personagens
This commit is contained in:
+99
-60
@@ -2097,56 +2097,47 @@ const initApp = () => {
|
||||
const mode = btn.dataset.mode;
|
||||
const text = userInput.value.trim();
|
||||
|
||||
// Se for modo POETRY ou TEXT, ou se o input estiver vazio, preenchemos o input com a sugestão correspondente sem enviar
|
||||
const isTextOrPoetry = (mode === 'POETRY' || mode === 'TEXT');
|
||||
let suggestion = "";
|
||||
let baseText = text;
|
||||
|
||||
if (!text || isTextOrPoetry) {
|
||||
let suggestion = "";
|
||||
let baseText = text;
|
||||
|
||||
// Se o texto atual já for uma das sugestões padrão, limpamos para não duplicar
|
||||
const suggestionsList = [
|
||||
"Crie uma música pedagógica alegre e animada sobre ",
|
||||
"Crie um roteiro detalhado para um vídeo educativo sobre ",
|
||||
"Crie uma ilustração pedagógica com cores vibrantes mostrando ",
|
||||
"Escreva uma poesia infantil rimada e educativa sobre ",
|
||||
"Escreva uma história educativa infantil curta sobre "
|
||||
];
|
||||
|
||||
for (const sugg of suggestionsList) {
|
||||
if (baseText.startsWith(sugg)) {
|
||||
baseText = baseText.replace(sugg, "");
|
||||
break;
|
||||
}
|
||||
// Se o texto atual já for uma das sugestões padrão, limpamos para não duplicar
|
||||
const suggestionsList = [
|
||||
"Crie uma música pedagógica alegre e animada sobre ",
|
||||
"Crie um roteiro detalhado para um vídeo educativo sobre ",
|
||||
"Crie uma ilustração pedagógica com cores vibrantes mostrando ",
|
||||
"Escreva uma poesia infantil rimada e educativa sobre ",
|
||||
"Escreva uma história educativa infantil curta sobre "
|
||||
];
|
||||
|
||||
for (const sugg of suggestionsList) {
|
||||
if (baseText.startsWith(sugg)) {
|
||||
baseText = baseText.replace(sugg, "").trim();
|
||||
break;
|
||||
}
|
||||
|
||||
if (mode === 'AUDIO') {
|
||||
suggestion = "Crie uma música pedagógica alegre e animada sobre ";
|
||||
} else if (mode === 'VIDEO') {
|
||||
suggestion = "Crie um roteiro detalhado para um vídeo educativo sobre ";
|
||||
} else if (mode === 'IMAGE') {
|
||||
suggestion = "Crie uma ilustração pedagógica com cores vibrantes mostrando ";
|
||||
} else if (mode === 'POETRY') {
|
||||
suggestion = "Escreva uma poesia infantil rimada e educativa sobre ";
|
||||
} else if (mode === 'TEXT') {
|
||||
suggestion = "Escreva uma história educativa infantil curta sobre ";
|
||||
}
|
||||
|
||||
userInput.value = suggestion + baseText;
|
||||
userInput.focus();
|
||||
|
||||
// Mover cursor para o final do texto
|
||||
userInput.selectionStart = userInput.selectionEnd = userInput.value.length;
|
||||
|
||||
// Ajustar altura do textarea para acomodar a sugestão
|
||||
userInput.style.height = 'auto';
|
||||
userInput.style.height = userInput.scrollHeight + 'px';
|
||||
btnSend.disabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Se houver texto e for outro modo (AUDIO, VIDEO, IMAGE), envia imediatamente
|
||||
handleSendMessage(text, false, null, mode);
|
||||
if (mode === 'AUDIO') {
|
||||
suggestion = "Crie uma música pedagógica alegre e animada sobre ";
|
||||
} else if (mode === 'VIDEO') {
|
||||
suggestion = "Crie um roteiro detalhado para um vídeo educativo sobre ";
|
||||
} else if (mode === 'IMAGE') {
|
||||
suggestion = "Crie uma ilustração pedagógica com cores vibrantes mostrando ";
|
||||
} else if (mode === 'POETRY') {
|
||||
suggestion = "Escreva uma poesia infantil rimada e educativa sobre ";
|
||||
} else if (mode === 'TEXT') {
|
||||
suggestion = "Escreva uma história educativa infantil curta sobre ";
|
||||
}
|
||||
|
||||
userInput.value = suggestion + baseText;
|
||||
userInput.focus();
|
||||
|
||||
// Mover cursor para o final do texto
|
||||
userInput.selectionStart = userInput.selectionEnd = userInput.value.length;
|
||||
|
||||
// Ajustar altura do textarea para acomodar a sugestão
|
||||
userInput.style.height = 'auto';
|
||||
userInput.style.height = userInput.scrollHeight + 'px';
|
||||
if (btnSend) btnSend.disabled = false;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3515,6 +3506,7 @@ const initApp = () => {
|
||||
const btnSaveComicsProject = document.getElementById('btnSaveComicsProject');
|
||||
|
||||
let currentComicsProjectId = null;
|
||||
let currentComicsCharDescEnglish = '';
|
||||
let selectedComicsQty = 5;
|
||||
let selectedComicsBubbles = true;
|
||||
let selectedComicsRatio = '16:9';
|
||||
@@ -3617,6 +3609,13 @@ const initApp = () => {
|
||||
// --- GERENCIADOR DE PROJETOS DE HQ ---
|
||||
const startNewComicsProject = () => {
|
||||
currentComicsProjectId = null;
|
||||
currentComicsCharDescEnglish = '';
|
||||
|
||||
const modeContainer = document.getElementById('comicsGenerationModeContainer');
|
||||
if (modeContainer) modeContainer.style.display = 'none';
|
||||
const radioNew = document.querySelector('input[name="comicsGenMode"][value="new_story"]');
|
||||
if (radioNew) radioNew.checked = true;
|
||||
|
||||
if (comicsProjectSelect) comicsProjectSelect.value = '';
|
||||
if (comicsProjectTitleInput) comicsProjectTitleInput.value = '';
|
||||
if (btnDeleteComicsProject) btnDeleteComicsProject.style.display = 'none';
|
||||
@@ -3699,6 +3698,11 @@ const initApp = () => {
|
||||
const { project, panels } = await resp.json();
|
||||
|
||||
currentComicsProjectId = project.id;
|
||||
currentComicsCharDescEnglish = project.character_description_english || '';
|
||||
|
||||
const modeContainer = document.getElementById('comicsGenerationModeContainer');
|
||||
if (modeContainer) modeContainer.style.display = 'flex';
|
||||
|
||||
if (comicsProjectTitleInput) comicsProjectTitleInput.value = project.titulo || '';
|
||||
comicsTemaInput.value = project.tema || '';
|
||||
|
||||
@@ -3852,9 +3856,10 @@ const initApp = () => {
|
||||
cenario,
|
||||
proporcao: selectedComicsRatio,
|
||||
character_description_global: JSON.stringify(characters),
|
||||
character_description_english: currentComicsCharDescEnglish || '',
|
||||
panels: generatedPanelsData.map(p => ({
|
||||
panel_number: p.panel_number,
|
||||
image_url: p.imageUrl,
|
||||
image_url: p.imageUrl || p.image_url || '',
|
||||
image_prompt: p.image_prompt || '',
|
||||
dialogue: p.dialogue || ''
|
||||
}))
|
||||
@@ -4009,17 +4014,32 @@ const initApp = () => {
|
||||
|
||||
try {
|
||||
// 1. Gerar Roteiro
|
||||
const genMode = currentComicsProjectId ? (document.querySelector('input[name="comicsGenMode"]:checked')?.value || 'new_story') : 'new_story';
|
||||
|
||||
const requestBody = {
|
||||
tema,
|
||||
quantidade: selectedComicsQty,
|
||||
baloes: selectedComicsBubbles,
|
||||
proporcao: selectedComicsRatio,
|
||||
personagens,
|
||||
cenario
|
||||
};
|
||||
|
||||
if (currentComicsProjectId) {
|
||||
requestBody.continuationType = genMode;
|
||||
requestBody.character_description = currentComicsCharDescEnglish;
|
||||
requestBody.existingPanels = generatedPanelsData.map(p => ({
|
||||
panel_number: p.panel_number,
|
||||
image_url: p.imageUrl || p.image_url || '',
|
||||
image_prompt: p.image_prompt || '',
|
||||
dialogue: p.dialogue || ''
|
||||
}));
|
||||
}
|
||||
|
||||
const scriptResp = await fetch('/api/comics/generate-script', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
tema,
|
||||
quantidade: selectedComicsQty,
|
||||
baloes: selectedComicsBubbles,
|
||||
proporcao: selectedComicsRatio,
|
||||
personagens,
|
||||
cenario
|
||||
})
|
||||
body: JSON.stringify(requestBody)
|
||||
});
|
||||
|
||||
if (!scriptResp.ok) {
|
||||
@@ -4030,8 +4050,14 @@ const initApp = () => {
|
||||
const scriptData = await scriptResp.json();
|
||||
comicsLoaderProgress.style.width = '15%';
|
||||
|
||||
if (scriptData.character_description) {
|
||||
currentComicsCharDescEnglish = scriptData.character_description;
|
||||
}
|
||||
|
||||
// 2. Gerar cada quadrinho sequencialmente
|
||||
generatedPanelsData = [];
|
||||
if (genMode !== 'extend') {
|
||||
generatedPanelsData = [];
|
||||
}
|
||||
const totalPanels = scriptData.panels.length;
|
||||
|
||||
for (let i = 0; i < totalPanels; i++) {
|
||||
@@ -4058,12 +4084,13 @@ const initApp = () => {
|
||||
generatedPanelsData.push({
|
||||
panel_number: panel.panel_number,
|
||||
imageUrl: frameData.imageUrl,
|
||||
dialogue: panel.dialogue || ''
|
||||
dialogue: panel.dialogue || '',
|
||||
image_prompt: panel.image_prompt || ''
|
||||
});
|
||||
}
|
||||
|
||||
// Renderizar quadrinhos na tela
|
||||
comicsResultTitle.textContent = scriptData.title || 'Fábrica de Quadrinhos Camila';
|
||||
// Renderizar quadrinhos na tela (todos, incluindo os anteriores caso tenha sido extensão)
|
||||
comicsResultTitle.textContent = scriptData.title || comicsResultTitle.textContent || 'Fábrica de Quadrinhos Camila';
|
||||
comicsGridContainer.innerHTML = '';
|
||||
|
||||
generatedPanelsData.forEach(panel => {
|
||||
@@ -4075,7 +4102,7 @@ const initApp = () => {
|
||||
|
||||
const img = document.createElement('img');
|
||||
img.className = 'comic-panel-image';
|
||||
img.src = panel.imageUrl;
|
||||
img.src = panel.imageUrl || panel.image_url;
|
||||
img.alt = `Quadro ${panel.panel_number}`;
|
||||
imgContainer.appendChild(img);
|
||||
|
||||
@@ -4106,6 +4133,18 @@ const initApp = () => {
|
||||
comicsGridContainer.appendChild(panelCard);
|
||||
});
|
||||
|
||||
// Se for uma nova história derivada de um projeto antigo, limpamos o ID para virar um novo projeto independente ao salvar
|
||||
if (genMode === 'new_story' && currentComicsProjectId) {
|
||||
currentComicsProjectId = null;
|
||||
if (comicsProjectSelect) comicsProjectSelect.value = '';
|
||||
const modeContainer = document.getElementById('comicsGenerationModeContainer');
|
||||
if (modeContainer) modeContainer.style.display = 'none';
|
||||
if (comicsProjectTitleInput) {
|
||||
comicsProjectTitleInput.value = scriptData.title || (comicsProjectTitleInput.value + ' (Derivado)');
|
||||
}
|
||||
if (btnDeleteComicsProject) btnDeleteComicsProject.style.display = 'none';
|
||||
}
|
||||
|
||||
comicsGenerateLoader.style.display = 'none';
|
||||
comicsResultArea.style.display = 'flex';
|
||||
btnGenerateComics.disabled = false;
|
||||
|
||||
Reference in New Issue
Block a user