feat(gestos): gestos com maos nos favoritos e ate 12 favoritos

Acenar, esconder, espiar, pensar e dancar entram nos favoritos padrao
(logo apos feliz e coracao). Quem ja tinha favoritos salvos recebe esses
gestos uma vez, sem perder os seus. Teclas 1 a 9 para os nove primeiros.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
julio
2026-10-06 02:48:21 -03:00
co-authored by Claude Opus 5.5
parent 230ca991a2
commit f550930f56
4 changed files with 20 additions and 7 deletions
+16 -3
View File
@@ -30,12 +30,24 @@ export const GESTOS_INFO: Record<string, { nome: string; emoji: string }> = {
export const gestosDisponiveis = () => estado.gestos.filter((g) => g in GESTOS_INFO); export const gestosDisponiveis = () => estado.gestos.filter((g) => g in GESTOS_INFO);
const CHAVE_FAVORITOS = 'carinha_favoritos'; const CHAVE_FAVORITOS = 'carinha_favoritos';
const PADRAO_FAVORITOS = ['feliz', 'coracao', 'piscadinha', 'surpreso', 'triste', 'olhar_esq', 'olhar_dir', 'dormir', 'acordar']; const CHAVE_MAOS = 'carinha_favoritos_maos'; // marca que os gestos com mãos já entraram
/** Até 12 favoritos; as teclas 1 a 9 valem para os nove primeiros. */
export const MAX_FAVORITOS = 12;
const GESTOS_MAOS = ['acenar', 'esconder', 'espiar', 'pensar', 'musica'];
const PADRAO_FAVORITOS = ['feliz', 'coracao', 'acenar', 'esconder', 'espiar', 'pensar', 'musica', 'piscadinha', 'surpreso', 'triste', 'dormir', 'acordar'];
function lerFavoritos(): string[] { function lerFavoritos(): string[] {
try { try {
const v = JSON.parse(localStorage.getItem(CHAVE_FAVORITOS) || 'null'); const v = JSON.parse(localStorage.getItem(CHAVE_FAVORITOS) || 'null');
if (Array.isArray(v) && v.every((x) => typeof x === 'string')) return v.slice(0, 9); if (Array.isArray(v) && v.every((x) => typeof x === 'string')) {
if (localStorage.getItem(CHAVE_MAOS)) return v.slice(0, MAX_FAVORITOS);
// Quem já tinha favoritos salvos ganha os gestos com mãos logo depois dos dois primeiros.
const novos = GESTOS_MAOS.filter((g) => !v.includes(g));
const lista = [...v.slice(0, 2), ...novos, ...v.slice(2)].slice(0, MAX_FAVORITOS);
localStorage.setItem(CHAVE_FAVORITOS, JSON.stringify(lista));
localStorage.setItem(CHAVE_MAOS, '1');
return lista;
}
} catch { } catch {
/* sem armazenamento */ /* sem armazenamento */
} }
@@ -45,9 +57,10 @@ function lerFavoritos(): string[] {
class Favoritos { class Favoritos {
lista = $state<string[]>(lerFavoritos()); lista = $state<string[]>(lerFavoritos());
alternar(g: string) { alternar(g: string) {
this.lista = this.lista.includes(g) ? this.lista.filter((x) => x !== g) : [...this.lista, g].slice(0, 9); this.lista = this.lista.includes(g) ? this.lista.filter((x) => x !== g) : [...this.lista, g].slice(0, MAX_FAVORITOS);
try { try {
localStorage.setItem(CHAVE_FAVORITOS, JSON.stringify(this.lista)); localStorage.setItem(CHAVE_FAVORITOS, JSON.stringify(this.lista));
localStorage.setItem(CHAVE_MAOS, '1');
} catch { } catch {
/* ok */ /* ok */
} }
+2 -2
View File
@@ -11,10 +11,10 @@
{#each lista as g, i (g)} {#each lista as g, i (g)}
{@const info = GESTOS_INFO[g]} {@const info = GESTOS_INFO[g]}
<div class="item"> <div class="item">
<button class="gesto" onclick={() => gesto(g)} title={completo ? info.nome : `${info.nome} (tecla ${i + 1})`}> <button class="gesto" onclick={() => gesto(g)} title={completo || i > 8 ? info.nome : `${info.nome} (tecla ${i + 1})`}>
<span class="emoji" aria-hidden="true">{info.emoji}</span> <span class="emoji" aria-hidden="true">{info.emoji}</span>
<span class="nome">{info.nome}</span> <span class="nome">{info.nome}</span>
{#if !completo}<kbd>{i + 1}</kbd>{/if} {#if !completo && i < 9}<kbd>{i + 1}</kbd>{/if}
</button> </button>
{#if completo} {#if completo}
<button <button
+1 -1
View File
@@ -146,7 +146,7 @@
<Linha icone={Settings2} cor="#8e8e93" rotulo="Qualidade, câmera frontal/traseira e sensores" href="#/ajustes" /> <Linha icone={Settings2} cor="#8e8e93" rotulo="Qualidade, câmera frontal/traseira e sensores" href="#/ajustes" />
</Grupo> </Grupo>
<Grupo titulo="Gestos" rodape="Teclas 1 a 9 no teclado. Ctrl+K busca qualquer gesto."> <Grupo titulo="Gestos" rodape="Teclas 1 a 9 disparam os nove primeiros. Ctrl+K busca qualquer gesto.">
<Linha icone={Smile} cor="#ffcc00" rotulo="Favoritos"> <Linha icone={Smile} cor="#ffcc00" rotulo="Favoritos">
<Gestos /> <Gestos />
</Linha> </Linha>
+1 -1
View File
@@ -204,7 +204,7 @@
</Card> </Card>
</div> </div>
{:else if aba === 'gestos'} {:else if aba === 'gestos'}
<Card titulo="Gestos do rosto" descricao="Toque para mandar ao celular. A estrela fixa o gesto nos favoritos (atalhos 1 a 9)."> <Card titulo="Gestos do rosto" descricao="Toque para mandar ao celular. A estrela fixa o gesto nos favoritos (até 12; as teclas 1 a 9 valem para os nove primeiros).">
<Gestos completo /> <Gestos completo />
</Card> </Card>
{:else} {:else}