Files
carinha-control-panel/web/src/lib/paleta.svelte.ts
T
julioandClaude Opus 5.5 d7a17b5683 feat(rosto): atividades (momentos dele) e seis gestos novos
Atividades: a tela se divide, o rosto vai para a esquerda e encolhe, e
à direita um bonequinho do Carinha (silhueta na cor dos olhos) faz algo:
ler (vira a página), cantar (microfone e notas), jogar bola
(embaixadinha), videogame (TV com joguinho), pintar (cavalete que ganha
pinceladas) e malhar (halteres e suor). Os olhos grandes acompanham:
leem as linhas, seguem a bola, olham a TV. Camada própria atrás dos
olhos, vale para todos os rostos; em pé (retrato) a cena vai para baixo.

- Comando {tipo: "atividade", valor: nome|parar}; toque na tela, dormir
  e E-Stop encerram; o celular informa a atividade na telemetria.
- Modo vida escolhe pelo humor (feliz canta e joga bola, tranquilo lê
  e pinta, entediado joga videogame), nunca de madrugada, e não
  interrompe uma atividade em andamento.
- Gestos novos: rir, comemorar, tímido, confuso, bocejar e tonto; o
  humor e o modo vida também os usam.
- Painel: favoritos vão até 20 e o bravo volta junto com os novos;
  botões de atividade no Ao vivo, no Ctrl+K e tópico no guia.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 21:12:14 -03:00

65 lines
2.6 KiB
TypeScript

/** Registro da command palette (Ctrl+K): cada parte do painel contribui com itens. */
import {
atividade, ATIVIDADES_INFO, cor, CORES, formato, FORMATOS_INFO, gesto, GESTOS_INFO, gestosDisponiveis, nomeRosto, pararTudo, rearmar, recarregarCelular, rosto,
} from './comandos.svelte';
import { estado } from './estado.svelte';
import { ORDEM_GUIA, TOPICOS } from './guia';
import { nav, ROTAS } from './rotas.svelte';
export interface ItemPaleta {
id: string;
grupo: string;
titulo: string;
dica?: string;
fazer: () => unknown;
}
type Fonte = () => ItemPaleta[];
const fontes = new Set<Fonte>();
export function registrarNaPaleta(fonte: Fonte): () => void {
fontes.add(fonte);
return () => fontes.delete(fonte);
}
class Paleta {
aberta = $state(false);
abrir = () => (this.aberta = true);
fechar = () => (this.aberta = false);
}
export const paleta = new Paleta();
export function itensDaPaleta(): ItemPaleta[] {
return [...fontes].flatMap((f) => f());
}
// Itens base: navegação, ações gerais, gestos, rostos e cores.
registrarNaPaleta(() => [
...ROTAS.map((r) => ({ id: 'ir-' + r.id, grupo: 'Ir para', titulo: r.titulo, fazer: () => nav.ir(r.id) })),
{ id: 'ir-rosto', grupo: 'Ir para', titulo: 'Rosto (estilo, formato e cor)', fazer: () => nav.ir('rosto') },
...Object.entries(ATIVIDADES_INFO).map(([id, a]) => ({
id: 'atividade-' + id, grupo: 'Atividades', titulo: a.emoji + ' ' + a.nome, fazer: () => atividade(id),
})),
{ id: 'atividade-parar', grupo: 'Atividades', titulo: '⏹ Parar a atividade', fazer: () => atividade('parar') },
...ORDEM_GUIA.map((t) => ({
id: 'guia-' + t,
grupo: 'Guia',
titulo: TOPICOS[t].emoji + ' ' + TOPICOS[t].titulo,
dica: TOPICOS[t].onde,
fazer: () => (location.hash = '/guia?t=' + t),
})),
...estado.formatos.map((f) => ({ id: 'formato-' + f, grupo: 'Formato dos olhos', titulo: FORMATOS_INFO[f] ?? f, fazer: () => formato(f) })),
estado.estop.ativo
? { id: 'rearmar', grupo: 'Ações', titulo: 'Rearmar motores', fazer: rearmar }
: { id: 'estop', grupo: 'Ações', titulo: 'Parar tudo (E-Stop)', dica: 'Shift+Espaço', fazer: pararTudo },
{ id: 'recarregar', grupo: 'Ações', titulo: 'Recarregar tela do celular', fazer: recarregarCelular },
...gestosDisponiveis().map((g) => ({
id: 'gesto-' + g,
grupo: 'Gestos',
titulo: `${GESTOS_INFO[g].emoji} ${GESTOS_INFO[g].nome}`,
fazer: () => gesto(g),
})),
...estado.rostos.map((r) => ({ id: 'rosto-' + r, grupo: 'Rosto', titulo: 'Rosto ' + nomeRosto(r), fazer: () => rosto(r) })),
...CORES.map((c) => ({ id: 'cor-' + c.nome, grupo: 'Cor dos olhos', titulo: c.nome, fazer: () => cor(c.rgb) })),
]);