164 lines
9.1 KiB
HTML
164 lines
9.1 KiB
HTML
<!doctype html>
|
|
<html lang="pt-BR">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Conversar com IA · Carinha</title>
|
|
<meta name="description" content="Converse por voz ou texto com o Carinha usando Google Gemini com memória de longo prazo.">
|
|
<link rel="stylesheet" href="/dashboard.css">
|
|
<link rel="stylesheet" href="/conversa.css">
|
|
<script src="/dashboard.js" defer></script>
|
|
</head>
|
|
<body>
|
|
<!-- Cabeçalho da Página -->
|
|
<div style="display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:16px;margin-bottom:12px">
|
|
<div>
|
|
<h1>Conversar com o Carinha</h1>
|
|
<p style="margin:4px 0 0">Converse por voz ou texto. As expressões do rosto mudam em tempo real conforme a conversa.</p>
|
|
</div>
|
|
<div style="display:flex;gap:12px;align-items:center;flex-wrap:wrap">
|
|
<label style="display:flex;align-items:center;gap:8px;font-size:13px;margin:0;cursor:pointer">
|
|
<input type="checkbox" id="conversaVozAuto" checked style="width:16px;height:16px">
|
|
<span>Falar respostas (TTS)</span>
|
|
</label>
|
|
<span class="badge ativo"><span class="badge-dot"></span> Gemini Online</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- WORKSPACE STICKY: Rosto fica fixado enquanto a conversa rola -->
|
|
<div class="conversa-workspace">
|
|
|
|
<!-- Coluna Fixa (Sticky: Rosto + Status) -->
|
|
<aside class="conversa-sticky-col">
|
|
|
|
<!-- Preview do Rosto ao Vivo -->
|
|
<section class="card sticky-preview-card" style="margin-bottom:18px">
|
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px">
|
|
<h2>
|
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="var(--ciano)" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M8 14s1.5 2 4 2 4-2 4-2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>
|
|
Rosto ao Vivo
|
|
</h2>
|
|
<span class="badge ativo" style="font-size:11px">📌 Sempre Visível</span>
|
|
</div>
|
|
|
|
<iframe id="conversaCarinhaPreview"
|
|
src="/carinha.html?espelho=1&audio=0"
|
|
title="Expressão atual do Carinha"
|
|
style="width:100%;height:220px;border-radius:var(--raio-md);border:1px solid var(--borda-brilho);background:#000;box-shadow:inset 0 0 30px rgba(0,0,0,0.8),0 0 20px var(--ciano-glow)">
|
|
</iframe>
|
|
|
|
<!-- Status da Expressão Atual -->
|
|
<div id="conversaExpressaoAtual" style="margin-top:10px;font-size:13px;color:var(--ciano);min-height:22px;text-align:center">
|
|
Aguardando conversa…
|
|
</div>
|
|
|
|
<!-- Motor de IA selecionado -->
|
|
<div style="margin-top:12px">
|
|
<label for="conversaProvedor" style="font-size:12px;text-transform:uppercase;letter-spacing:0.05em;color:var(--muito-fraco);margin-bottom:6px">Motor de IA</label>
|
|
<select id="conversaProvedor" style="width:100%;margin:0">
|
|
<option value="gemini">✨ Google Gemini · Nuvem</option>
|
|
<option value="local">📱 Qwen · Local no Celular</option>
|
|
</select>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Gestos Rápidos -->
|
|
<section class="card">
|
|
<h2 style="font-size:15px;margin-bottom:12px">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="var(--ciano)" stroke-width="2"><path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/></svg>
|
|
Gestos Rápidos
|
|
</h2>
|
|
<div class="toolbar" style="flex-wrap:wrap;gap:8px;margin:0">
|
|
<button type="button" class="btn-gesto-rapido" data-gesto="feliz" style="padding:7px 12px;font-size:13px">😊 Feliz</button>
|
|
<button type="button" class="btn-gesto-rapido" data-gesto="surpreso" style="padding:7px 12px;font-size:13px">😲 Surpreso</button>
|
|
<button type="button" class="btn-gesto-rapido" data-gesto="piscar" style="padding:7px 12px;font-size:13px">😉 Piscar</button>
|
|
<button type="button" class="btn-gesto-rapido" data-gesto="coracao" style="padding:7px 12px;font-size:13px">💖 Amor</button>
|
|
<button type="button" class="btn-gesto-rapido" data-gesto="dormir" style="padding:7px 12px;font-size:13px">🌙 Dormir</button>
|
|
<button type="button" class="btn-gesto-rapido" data-gesto="acordar" style="padding:7px 12px;font-size:13px">☀️ Acordar</button>
|
|
</div>
|
|
<p id="conversaGestoEstado" role="status" style="margin:10px 0 0;font-size:12.5px;color:var(--fraco);min-height:18px"></p>
|
|
</section>
|
|
|
|
</aside>
|
|
|
|
<!-- Coluna Rolável (Chat) -->
|
|
<main class="conversa-chat-col">
|
|
<section class="card chat-card" style="margin:0">
|
|
<div class="chat-header-bar">
|
|
<div style="display:flex;align-items:center;gap:12px">
|
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="var(--ciano)" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
|
|
<span style="font-weight:700;font-size:16px">Histórico</span>
|
|
</div>
|
|
<p id="conversaEstado" role="status" style="margin:0;font-size:12.5px;color:var(--fraco)">Carregando conversa…</p>
|
|
</div>
|
|
|
|
<!-- Caixa de Histórico de Mensagens -->
|
|
<div id="conversaHistorico" class="chat-box" role="log" aria-label="Histórico da conversa"></div>
|
|
|
|
<!-- Indicador de Digitando / Pensando -->
|
|
<div id="conversaTyping" class="chat-typing" style="display:none">
|
|
<span>Carinha está pensando</span>
|
|
<span class="dot-pulse"></span>
|
|
<span class="dot-pulse"></span>
|
|
<span class="dot-pulse"></span>
|
|
</div>
|
|
|
|
<!-- Sugestões Rápidas de Diálogo -->
|
|
<div class="chat-suggestions">
|
|
<button type="button" class="suggestion-chip" data-msg="Oi, Carinha! Como você está?">👋 Como você está?</button>
|
|
<button type="button" class="suggestion-chip" data-msg="Me conte uma curiosidade sobre robôs!">🤖 Curiosidade robótica</button>
|
|
<button type="button" class="suggestion-chip" data-msg="Faça uma cara bem engraçada e feliz!">😄 Faça uma cara feliz</button>
|
|
<button type="button" class="suggestion-chip" data-msg="Você gosta de música? Qual é seu som favorito?">🎶 Gosta de música?</button>
|
|
</div>
|
|
|
|
<!-- Formulário de Envio de Mensagem com Microfone -->
|
|
<form id="conversaForm" style="margin:0">
|
|
<div class="chat-input-container">
|
|
<button id="conversaMicBtn" class="btn-mic" type="button" title="Falar no microfone (Reconhecimento de Voz)">🎤</button>
|
|
<input id="conversaTexto" maxlength="600" required placeholder="Digite uma mensagem ou clique no microfone para falar..." autocomplete="off">
|
|
<button id="conversaEnviar" class="primary" type="submit" style="padding:10px 22px;border-radius:var(--raio-md)">
|
|
<span>Enviar</span>
|
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- Gerenciador de Lembranças e Memória Persistente -->
|
|
<details style="margin-top:10px">
|
|
<summary>
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="var(--ciano)" stroke-width="2"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>
|
|
Lembranças & Memória de Longo Prazo
|
|
</summary>
|
|
<p style="margin:8px 0 12px">Fatos e preferências ensinados ao Carinha que enriquecem o prompt do Gemini sem alterar os pesos do modelo.</p>
|
|
<form id="memoriaForm" style="display:flex;gap:10px;align-items:center;margin-bottom:14px">
|
|
<input id="memoriaTexto" maxlength="300" required placeholder="Ex.: Meu nome é Jullio e prefiro explicações diretas" style="margin:0">
|
|
<button type="submit" style="white-space:nowrap">Salvar Memória</button>
|
|
</form>
|
|
<div id="conversaMemorias" style="display:flex;flex-direction:column;gap:8px"></div>
|
|
<div style="margin-top:16px;border-top:1px solid var(--borda);padding-top:12px;display:flex;justify-content:flex-end">
|
|
<button id="conversaLimpar" type="button" class="danger" style="font-size:12px">🗑️ Apagar histórico e memórias</button>
|
|
</div>
|
|
</details>
|
|
</section>
|
|
</main>
|
|
|
|
</div>
|
|
|
|
<script src="/painel-conversa.js"></script>
|
|
<script>
|
|
// Gestos rápidos no painel lateral
|
|
document.querySelectorAll('.btn-gesto-rapido').forEach(btn => {
|
|
btn.addEventListener('click', async () => {
|
|
const gesto = btn.dataset.gesto;
|
|
try {
|
|
const r = await fetch('/gesto/' + encodeURIComponent(gesto));
|
|
if (r.ok) {
|
|
const el = document.getElementById('conversaGestoEstado');
|
|
if (el) { el.textContent = 'Gesto: ' + gesto + ' ✓'; setTimeout(() => { el.textContent = ''; }, 2500); }
|
|
}
|
|
} catch (e) { console.log('gesto rápido:', e); }
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |