feat: criada a aba Tipos de vídeo com cinco perfis editoriais pré-
- criada a aba Tipos de vídeo com cinco perfis editoriais pré-cadastrados e catálogo local pronto para integração com o Schedule Light - ampliado o cadastro vertical dos perfis com objetivos, narrativa, emoção, prioridades, formato, áudio e regras para IA - criado plano JSON para resumir a entrevista jornalística em até três minutos Resumo: - 4 arquivos alterados - 1 novos - 3 modificados - 0 removidos 3 files changed, 318 insertions(+), 3 deletions(-) Arquivos: - code/cep-plugin/index.html - code/cep-plugin/main.js - code/cep-plugin/styles.css - plano-resumo-video.json
This commit is contained in:
@@ -30,6 +30,28 @@ function log(msg, cls) {
|
||||
// reposicionado na aba de origem com etapa atual, barra e tempo decorrido.
|
||||
var taskState = { active: false, startedAt: 0, timer: null, clearTimer: null, mirror: null, originTab: "silence", originPanelId: "tabSilence", errorText: "" };
|
||||
|
||||
var TIPOS_VIDEO_CHAVE = "schedule_light_tipos_video";
|
||||
var tipoVideoAtualId = null;
|
||||
var tiposVideoPadrao = [
|
||||
{ id: "midia-social", nome: "Conteúdo para mídia social", duracao_maxima_segundos: 60, descricao: "Vídeo curto para interromper a rolagem, comunicar uma ideia e estimular uma ação.", canais: "Instagram Reels, TikTok, Shorts", proporcao: "9:16", ritmo: "agil", emocao: "Curiosidade e energia", storytelling: true, estrutura: "Gancho nos primeiros 2 segundos → desenvolvimento em blocos curtos → CTA direto.", cortes: "Cortes rápidos, remover pausas e repetições; preservar frases de impacto. Usar jump cuts com moderação.", broll: "Inserir imagens de apoio a cada mudança de ideia, preferindo planos que reforcem a fala.", texto: "Legendas sempre; destacar palavras-chave na tela e usar título curto. CTA visual no final.", som: "Voz sempre inteligível e à frente da trilha; música energética em volume baixo.", diretriz: "Priorize retenção e clareza. Cada corte deve manter o ritmo e reforçar uma única ideia por vez." },
|
||||
{ id: "depoimento", nome: "Depoimento de cliente", duracao_maxima_segundos: 120, descricao: "Relato autêntico que gera identificação, confiança e prova social.", canais: "Site, redes sociais, apresentação comercial", proporcao: "adaptavel", ritmo: "equilibrado", emocao: "Empatia e confiança", storytelling: true, estrutura: "Problema vivido → experiência com a solução → transformação → recomendação.", cortes: "Cortar hesitações e desvios sem deixar a fala artificial; manter reações, pausas emocionais e frases espontâneas.", broll: "Cobrir cortes com cenas do cliente usando o produto, ambiente real ou detalhes que comprovem o relato.", texto: "Nome e contexto do depoente; destacar a transformação em frases curtas; legendas completas.", som: "Voz natural, limpa e próxima; trilha emocional discreta, crescendo apenas na transformação.", diretriz: "Proteja a autenticidade do depoimento. A emoção deve vir da fala e das evidências, não de efeitos excessivos." },
|
||||
{ id: "entrevista", nome: "Entrevista", duracao_maxima_segundos: 600, descricao: "Conversa estruturada para extrair conhecimento, opinião ou história de uma pessoa.", canais: "YouTube, podcast em vídeo, cortes sociais", proporcao: "16:9", ritmo: "equilibrado", emocao: "Interesse e credibilidade", storytelling: true, estrutura: "Apresentação → perguntas essenciais → aprofundamento → síntese e encerramento.", cortes: "Remover redundâncias e silêncios longos; preservar respostas completas, escuta, reação e contexto da pergunta.", broll: "Usar planos de reação, detalhes do ambiente e imagens relacionadas ao tema para quebrar a monotonia.", texto: "Identificação do entrevistado, perguntas resumidas quando necessário, capítulos ou palavras-chave.", som: "Diálogo consistente entre os canais; reduzir ruído e nivelar vozes sem tirar naturalidade.", diretriz: "Mantenha a linha de raciocínio da conversa. Não cortar uma resposta de modo que altere o sentido ou a intenção do entrevistado." },
|
||||
{ id: "institucional", nome: "Vídeo institucional", duracao_maxima_segundos: 180, descricao: "Apresentação da empresa, marca, cultura ou solução com percepção de valor.", canais: "Site, eventos, apresentações, LinkedIn", proporcao: "16:9", ritmo: "progressivo", emocao: "Segurança e inspiração", storytelling: true, estrutura: "Contexto ou propósito → pessoas e operação → diferenciais → prova → convite para conhecer.", cortes: "Ritmo elegante; evitar excesso de cortes. Alternar entrevistas, planos de ambiente e detalhes de operação.", broll: "B-roll planejado para mostrar pessoas, processos, produto e escala; toda imagem deve provar uma mensagem.", texto: "Títulos limpos, dados essenciais e assinatura da marca; evitar excesso de texto na tela.", som: "Trilha cinematográfica ou institucional discreta; voz firme, clara e com pausas bem preservadas.", diretriz: "Construa confiança e percepção de valor. Use consistência visual e sonora; efeitos só quando ajudarem a mensagem da marca." },
|
||||
{ id: "educativo-storytelling", nome: "Educativo com storytelling", duracao_maxima_segundos: 240, descricao: "Explicação didática que ensina uma ideia por meio de uma história, caso ou problema concreto.", canais: "YouTube, curso, LinkedIn, redes sociais", proporcao: "adaptavel", ritmo: "progressivo", emocao: "Curiosidade e clareza", storytelling: true, estrutura: "Problema ou pergunta → história/exemplo → explicação → aplicação prática → resumo.", cortes: "Cortar repetições, mas manter a sequência pedagógica; inserir pausas após conceitos importantes.", broll: "Usar diagramas, tela, exemplos e imagens que tornem o conceito visível; sincronizar apoio com a explicação.", texto: "Título do conceito, palavras-chave e resumo final; legendas e marcadores de etapas.", som: "Voz em primeiro plano; trilha quase imperceptível; pequenos efeitos apenas para sinalizar transições.", diretriz: "Ensine uma coisa por vez. O espectador deve entender o conceito sem depender apenas de texto ou de efeitos visuais." }
|
||||
];
|
||||
|
||||
function tipoVideoCompletar(tipo) {
|
||||
var configuracoes = {
|
||||
"midia-social": { categoria: "Comercial", objetivo: "Gerar retenção e ação", objetivo_secundario: "Comunicar uma ideia rapidamente", publico: "Público das redes sociais", mensagem: "Uma ideia clara por vídeo.", tipo_narrativa: "Problema → solução → benefício", foco_narrativo: "Gancho e CTA", intensidade: 4, tom: "Positivo", construcao_emocao: "Ritmo ágil, cortes de impacto, legendas e trilha energética.", duracao_minima: 15, prioridades: ["Retenção", "Clareza", "Mensagem", "Ritmo", "Estética"], usa_broll: true, usa_legendas: true, usa_textos: true, usa_graficos: false, usa_zoom: true, usa_musica: true, intensidade_musica: 25, prioridade_voz: "Muito alta", restricoes: "Evitar excesso de informação e cortes sem função.", qualidade: "A abertura prende atenção e a mensagem é compreendida sem áudio." },
|
||||
"depoimento": { categoria: "Depoimento", objetivo: "Gerar credibilidade e confiança", objetivo_secundario: "Criar identificação emocional", publico: "Clientes em potencial", mensagem: "A experiência real comprova o valor da solução.", tipo_narrativa: "História pessoal", foco_narrativo: "Problema → experiência → transformação → recomendação", intensidade: 3, tom: "Íntimo", construcao_emocao: "Preservar pausas naturais, reações e imagens reais; usar trilha discreta.", duracao_minima: 30, prioridades: ["Autenticidade", "Clareza", "Conexão emocional", "Ritmo", "Estética"], usa_broll: true, usa_legendas: true, usa_textos: true, usa_graficos: false, usa_zoom: false, usa_musica: true, intensidade_musica: 20, prioridade_voz: "Muito alta", restricoes: "Não alterar o sentido das frases nem deixar o depoimento artificial.", qualidade: "A pessoa parece verdadeira e o resultado do relato fica evidente." },
|
||||
"entrevista": { categoria: "Entrevista", objetivo: "Transmitir conhecimento e autoridade", objetivo_secundario: "Organizar a conversa por temas", publico: "Pessoas interessadas no assunto", mensagem: "O conteúdo da conversa é compreendido com contexto.", tipo_narrativa: "Pergunta e resposta", foco_narrativo: "Pergunta → resposta → aprofundamento", intensidade: 2, tom: "Informativo", construcao_emocao: "Reações, escuta e pausas que preservem a naturalidade da conversa.", duracao_minima: 60, prioridades: ["Clareza", "Conteúdo", "Contexto", "Ritmo", "Estética"], usa_broll: true, usa_legendas: true, usa_textos: true, usa_graficos: false, usa_zoom: true, usa_musica: false, intensidade_musica: 10, prioridade_voz: "Muito alta", restricoes: "Não cortar frases de modo que prejudique o raciocínio do entrevistado.", qualidade: "As respostas mantêm contexto, lógica e informação relevante." },
|
||||
"institucional": { categoria: "Institucional", objetivo: "Apresentar valor e confiança na marca", objetivo_secundario: "Mostrar pessoas, processo e diferenciais", publico: "Clientes, parceiros e equipe", mensagem: "A marca entrega valor de forma consistente.", tipo_narrativa: "Jornada / transformação", foco_narrativo: "Propósito → pessoas → operação → prova", intensidade: 4, tom: "Inspirador", construcao_emocao: "Trilha progressiva, imagens de pessoas e planos de operação.", duracao_minima: 45, prioridades: ["Confiança", "Mensagem", "Narrativa", "Estética", "Ritmo"], usa_broll: true, usa_legendas: true, usa_textos: true, usa_graficos: true, usa_zoom: false, usa_musica: true, intensidade_musica: 35, prioridade_voz: "Alta", restricoes: "Evitar efeitos decorativos que não reforcem a mensagem da marca.", qualidade: "O vídeo transmite profissionalismo, clareza e percepção de valor." },
|
||||
"educativo-storytelling": { categoria: "Educativo", objetivo: "Ensinar um assunto com clareza", objetivo_secundario: "Aumentar retenção e aplicação prática", publico: "Pessoas que precisam aprender o assunto", mensagem: "O espectador consegue entender e aplicar o conceito.", tipo_narrativa: "Explicação passo a passo", foco_narrativo: "Problema → exemplo → explicação → aplicação", intensidade: 2, tom: "Informativo", construcao_emocao: "Curiosidade inicial, exemplos visuais e pausas após conceitos importantes.", duracao_minima: 60, prioridades: ["Clareza", "Organização", "Didática", "Retenção", "Estética"], usa_broll: true, usa_legendas: true, usa_textos: true, usa_graficos: true, usa_zoom: true, usa_musica: false, intensidade_musica: 5, prioridade_voz: "Muito alta", restricoes: "Não cortar exemplos ou transições que prejudiquem a explicação.", qualidade: "O conteúdo fica fácil de acompanhar, revisar e aplicar." }
|
||||
}[tipo.id] || {};
|
||||
var completo = Object.assign({ ativo: true, categoria: "Personalizado", objetivo: "", objetivo_secundario: "", publico: "", mensagem: "", tipo_narrativa: "História pessoal", foco_narrativo: "", intensidade: 3, tom: "Positivo", construcao_emocao: "", duracao_minima: 0, prioridades: ["Clareza", "Mensagem", "Ritmo", "Conexão emocional", "Estética"], usa_broll: false, usa_legendas: true, usa_textos: false, usa_graficos: false, usa_zoom: false, usa_musica: false, intensidade_musica: 20, prioridade_voz: "Alta", restricoes: "", qualidade: "" }, configuracoes, tipo);
|
||||
return completo;
|
||||
}
|
||||
|
||||
function taskEl(id) { return document.getElementById(id); }
|
||||
|
||||
function formatClock(ms) {
|
||||
@@ -207,6 +229,7 @@ function switchTab(name) {
|
||||
{ key: "scanner", panel: "tabScanner", btn: "tabBtnScanner" },
|
||||
{ key: "retakes", panel: "tabRetakes", btn: "tabBtnRetakes" },
|
||||
{ key: "analises", panel: "tabAnalises", btn: "tabBtnAnalises" },
|
||||
{ key: "tipos-video", panel: "tabTiposVideo", btn: "tabBtnTiposVideo" },
|
||||
{ key: "bridge", panel: "tabBridge", btn: "tabBtnBridge" },
|
||||
{ key: "models", panel: "tabModels", btn: "tabBtnModels" },
|
||||
{ key: "settings", panel: "tabSettings", btn: "tabBtnSettings" },
|
||||
@@ -226,6 +249,196 @@ function switchTab(name) {
|
||||
if (name === "scanner") { renderScannerTranscriptionOptions(); loadScannerProfile(); renderScannerHuggingFaceStatus(); }
|
||||
if (name === "retakes") retakesAoAbrir();
|
||||
if (name === "analises") analisesAoAbrir();
|
||||
if (name === "tipos-video") tiposVideoAoAbrir();
|
||||
}
|
||||
|
||||
// ---- Catálogo de tipos de vídeo -------------------------------------------
|
||||
// A primeira versão usa o armazenamento local do painel. O documento salvo já
|
||||
// tem formato estável e pode ser migrado para o Schedule Light sem alterar o
|
||||
// contrato editorial enviado para a IA.
|
||||
function tiposVideoLer() {
|
||||
try {
|
||||
var salvo = JSON.parse(localStorage.getItem(TIPOS_VIDEO_CHAVE) || "null");
|
||||
if (Array.isArray(salvo) && salvo.length) return salvo.map(tipoVideoCompletar);
|
||||
var iniciais = tiposVideoPadrao.slice().map(tipoVideoCompletar);
|
||||
tiposVideoSalvarNoCatalogo(iniciais);
|
||||
return iniciais;
|
||||
} catch (_) { return tiposVideoPadrao.slice().map(tipoVideoCompletar); }
|
||||
}
|
||||
|
||||
function tiposVideoSalvarNoCatalogo(lista) {
|
||||
localStorage.setItem(TIPOS_VIDEO_CHAVE, JSON.stringify(lista));
|
||||
}
|
||||
|
||||
function tiposVideoAoAbrir() {
|
||||
tiposVideoRenderizarLista();
|
||||
if (!tipoVideoAtualId) tipoVideoNovo();
|
||||
}
|
||||
|
||||
function tiposVideoRenderizarLista() {
|
||||
var lista = document.getElementById("tiposVideoLista");
|
||||
if (!lista) return;
|
||||
lista.innerHTML = "";
|
||||
tiposVideoLer().forEach(function (tipo) {
|
||||
var item = document.createElement("div");
|
||||
item.className = "video-type-row" + (tipo.id === tipoVideoAtualId ? " is-selected" : "");
|
||||
item.setAttribute("role", "listitem");
|
||||
item.innerHTML = '<div class="video-type-copy"><strong></strong><span></span></div><div class="video-type-meta"></div><button class="button button-ghost" type="button">Editar</button>';
|
||||
item.querySelector("strong").textContent = tipo.nome;
|
||||
item.querySelector("span").textContent = tipo.descricao;
|
||||
item.querySelector(".video-type-meta").textContent = tipo.duracao_maxima_segundos + " s · " + tipo.proporcao + " · " + tipo.canais;
|
||||
item.querySelector("button").onclick = function () { tipoVideoEditar(tipo.id); };
|
||||
lista.appendChild(item);
|
||||
});
|
||||
}
|
||||
|
||||
function tipoVideoNovo() {
|
||||
tipoVideoAtualId = null;
|
||||
tipoVideoPreencher(tipoVideoCompletar({ id: "", nome: "", duracao_maxima_segundos: 60, descricao: "", canais: "", proporcao: "9:16", ritmo: "equilibrado", emocao: "", storytelling: true, estrutura: "", cortes: "", broll: "", texto: "", som: "", diretriz: "" }));
|
||||
document.getElementById("tipoVideoEditorTitulo").textContent = "Novo tipo de vídeo";
|
||||
document.getElementById("tipoVideoEditorStatus").textContent = "Rascunho";
|
||||
document.getElementById("tipoVideoEditorCard").hidden = false;
|
||||
tiposVideoRenderizarLista();
|
||||
}
|
||||
|
||||
function tipoVideoEditar(id) {
|
||||
var tipo = tiposVideoLer().filter(function (item) { return item.id === id; })[0];
|
||||
if (!tipo) return;
|
||||
tipoVideoAtualId = id;
|
||||
tipoVideoPreencher(tipo);
|
||||
document.getElementById("tipoVideoEditorTitulo").textContent = "Editar tipo de vídeo";
|
||||
document.getElementById("tipoVideoEditorStatus").textContent = "Cadastrado";
|
||||
document.getElementById("tipoVideoEditorCard").hidden = false;
|
||||
tiposVideoRenderizarLista();
|
||||
}
|
||||
|
||||
function tipoVideoPreencher(tipo) {
|
||||
tipo = tipoVideoCompletar(tipo);
|
||||
["nome", "descricao", "canais", "proporcao", "ritmo", "emocao", "estrutura", "cortes", "broll", "texto", "som", "diretriz", "categoria", "objetivo", "objetivo_secundario", "publico", "mensagem", "tipo_narrativa", "foco_narrativo", "tom", "construcao_emocao", "restricoes", "qualidade", "prioridade_voz"].forEach(function (campo) {
|
||||
var elemento = document.getElementById("tipoVideo" + campo.charAt(0).toUpperCase() + campo.slice(1));
|
||||
if (elemento) elemento.value = tipo[campo] || "";
|
||||
});
|
||||
document.getElementById("tipoVideoDuracao").value = tipo.duracao_maxima_segundos || "";
|
||||
document.getElementById("tipoVideoDuracaoMinima").value = tipo.duracao_minima || "";
|
||||
document.getElementById("tipoVideoStorytelling").checked = !!tipo.storytelling;
|
||||
document.getElementById("tipoVideoAtivo").checked = tipo.ativo !== false;
|
||||
document.getElementById("tipoVideoIntensidade").value = tipo.intensidade || 3;
|
||||
document.getElementById("tipoVideoIntensidadeMusica").value = tipo.intensidade_musica || 0;
|
||||
document.getElementById("tipoVideoUsaBroll").checked = !!tipo.usa_broll;
|
||||
document.getElementById("tipoVideoUsaLegendas").checked = !!tipo.usa_legendas;
|
||||
document.getElementById("tipoVideoUsaTextos").checked = !!tipo.usa_textos;
|
||||
document.getElementById("tipoVideoUsaGraficos").checked = !!tipo.usa_graficos;
|
||||
document.getElementById("tipoVideoUsaZoom").checked = !!tipo.usa_zoom;
|
||||
document.getElementById("tipoVideoUsaMusica").checked = !!tipo.usa_musica;
|
||||
tipoVideoRenderizarPrioridades(tipo.prioridades);
|
||||
tipoVideoAtualizarIntensidade();
|
||||
tipoVideoAtualizarIntensidadeMusica();
|
||||
}
|
||||
|
||||
function tipoVideoRenderizarPrioridades(prioridades) {
|
||||
var lista = document.getElementById("tipoVideoPrioridades");
|
||||
lista.innerHTML = "";
|
||||
(prioridades || []).slice(0, 5).forEach(function (valor, indice) {
|
||||
var linha = document.createElement("div");
|
||||
linha.className = "priority-row";
|
||||
linha.innerHTML = '<span class="priority-number">' + (indice + 1) + '</span><input class="text-field priority-input" type="text" value="">';
|
||||
linha.querySelector("input").value = valor;
|
||||
lista.appendChild(linha);
|
||||
});
|
||||
}
|
||||
|
||||
function tipoVideoPrioridadesDoFormulario() {
|
||||
return Array.prototype.slice.call(document.querySelectorAll("#tipoVideoPrioridades .priority-input")).map(function (input) { return input.value.trim(); }).filter(Boolean);
|
||||
}
|
||||
|
||||
function tipoVideoAtualizarIntensidade() {
|
||||
var valor = document.getElementById("tipoVideoIntensidade");
|
||||
var saida = document.getElementById("tipoVideoIntensidadeValor");
|
||||
if (valor && saida) saida.textContent = valor.value + " / 5";
|
||||
}
|
||||
|
||||
function tipoVideoAtualizarIntensidadeMusica() {
|
||||
var valor = document.getElementById("tipoVideoIntensidadeMusica");
|
||||
var saida = document.getElementById("tipoVideoIntensidadeMusicaValor");
|
||||
if (valor && saida) saida.textContent = valor.value + "%";
|
||||
}
|
||||
|
||||
function tipoVideoDoFormulario() {
|
||||
var nome = document.getElementById("tipoVideoNome").value.trim();
|
||||
if (!nome) throw new Error("Informe o nome do tipo de vídeo.");
|
||||
var base = tipoVideoAtualId ? tiposVideoLer().filter(function (item) { return item.id === tipoVideoAtualId; })[0] : null;
|
||||
return {
|
||||
id: tipoVideoAtualId || (nome.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") + "-" + Date.now()),
|
||||
nome: nome,
|
||||
descricao: document.getElementById("tipoVideoDescricao").value.trim(),
|
||||
ativo: document.getElementById("tipoVideoAtivo").checked,
|
||||
categoria: document.getElementById("tipoVideoCategoria").value,
|
||||
objetivo: document.getElementById("tipoVideoObjetivo").value.trim(),
|
||||
objetivo_secundario: document.getElementById("tipoVideoObjetivoSecundario").value.trim(),
|
||||
publico: document.getElementById("tipoVideoPublico").value.trim(),
|
||||
mensagem: document.getElementById("tipoVideoMensagem").value.trim(),
|
||||
tipo_narrativa: document.getElementById("tipoVideoTipoNarrativa").value,
|
||||
foco_narrativo: document.getElementById("tipoVideoFocoNarrativo").value.trim(),
|
||||
intensidade: Number(document.getElementById("tipoVideoIntensidade").value) || 3,
|
||||
tom: document.getElementById("tipoVideoTom").value,
|
||||
construcao_emocao: document.getElementById("tipoVideoConstrucaoEmocao").value.trim(),
|
||||
duracao_maxima_segundos: Number(document.getElementById("tipoVideoDuracao").value) || 0,
|
||||
duracao_minima: Number(document.getElementById("tipoVideoDuracaoMinima").value) || 0,
|
||||
canais: document.getElementById("tipoVideoCanais").value.trim(),
|
||||
proporcao: document.getElementById("tipoVideoProporcao").value,
|
||||
ritmo: document.getElementById("tipoVideoRitmo").value,
|
||||
emocao: document.getElementById("tipoVideoEmocao").value.trim(),
|
||||
storytelling: document.getElementById("tipoVideoStorytelling").checked,
|
||||
estrutura: document.getElementById("tipoVideoEstrutura").value.trim(),
|
||||
cortes: document.getElementById("tipoVideoCortes").value.trim(),
|
||||
broll: document.getElementById("tipoVideoBroll").value.trim(),
|
||||
texto: document.getElementById("tipoVideoTexto").value.trim(),
|
||||
som: document.getElementById("tipoVideoSom").value.trim(),
|
||||
diretriz: document.getElementById("tipoVideoDiretriz").value.trim(),
|
||||
prioridades: tipoVideoPrioridadesDoFormulario(),
|
||||
usa_broll: document.getElementById("tipoVideoUsaBroll").checked,
|
||||
usa_legendas: document.getElementById("tipoVideoUsaLegendas").checked,
|
||||
usa_textos: document.getElementById("tipoVideoUsaTextos").checked,
|
||||
usa_graficos: document.getElementById("tipoVideoUsaGraficos").checked,
|
||||
usa_zoom: document.getElementById("tipoVideoUsaZoom").checked,
|
||||
usa_musica: document.getElementById("tipoVideoUsaMusica").checked,
|
||||
intensidade_musica: Number(document.getElementById("tipoVideoIntensidadeMusica").value) || 0,
|
||||
prioridade_voz: document.getElementById("tipoVideoPrioridadeVoz").value,
|
||||
restricoes: document.getElementById("tipoVideoRestricoes").value.trim(),
|
||||
qualidade: document.getElementById("tipoVideoQualidade").value.trim(),
|
||||
criado_em: base && base.criado_em ? base.criado_em : new Date().toISOString(),
|
||||
atualizado_em: new Date().toISOString()
|
||||
};
|
||||
}
|
||||
|
||||
function tipoVideoSalvar() {
|
||||
try {
|
||||
var item = tipoVideoDoFormulario();
|
||||
var lista = tiposVideoLer();
|
||||
var indice = lista.findIndex(function (tipo) { return tipo.id === item.id; });
|
||||
if (indice >= 0) lista[indice] = item; else lista.push(item);
|
||||
tiposVideoSalvarNoCatalogo(lista);
|
||||
tipoVideoAtualId = item.id;
|
||||
document.getElementById("tipoVideoEditorStatus").textContent = "Salvo";
|
||||
document.getElementById("tiposVideoStatus").textContent = "Catálogo salvo localmente · " + lista.length + " tipo(s) cadastrado(s).";
|
||||
tiposVideoRenderizarLista();
|
||||
showToast("ok", "Tipo de vídeo salvo no catálogo.");
|
||||
} catch (erro) { showToast("err", erro.message); }
|
||||
}
|
||||
|
||||
function tipoVideoCancelar() {
|
||||
tipoVideoAtualId = null;
|
||||
document.getElementById("tipoVideoEditorCard").hidden = true;
|
||||
tiposVideoRenderizarLista();
|
||||
}
|
||||
|
||||
function tipoVideoCopiarJson() {
|
||||
try {
|
||||
var json = JSON.stringify({ tipo_de_video: tipoVideoDoFormulario() }, null, 2);
|
||||
var copia = childProcess.spawn("pbcopy");
|
||||
copia.stdin.end(json);
|
||||
showToast("ok", "Configuração copiada em JSON para a IA.");
|
||||
} catch (erro) { showToast("err", erro.message); }
|
||||
}
|
||||
|
||||
// ---- Análises ---------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user