import { Component, ElementRef, EventEmitter, Input, Output, ViewChild, computed, inject, signal, } from '@angular/core'; import { I18nService } from '../../core/i18n.service'; import { TtsService } from '../../core/tts.service'; import { TaskView } from '../../core/models'; import { ToggleEvent } from './task-card.component'; /** Vista FOCO: una sola tarea a pantalla completa, clave para reducir carga en TDAH. */ @Component({ selector: 'app-focus-view', imports: [], template: ` @if (current(); as task) {
{{ task.icon }}

{{ i18n.label(task.labelEs, task.labelCa) }}

@for (t of tasks; track t.id; let i = $index) { }
@if (ttsEnabled && tts.supported) { }

{{ i18n.t('left') }} {{ remaining() }} ยท {{ i18n.t('next') }}: {{ nextLabel() }}

} `, styles: [ ` .focus { display: flex; flex-direction: column; align-items: center; gap: var(--space-5); padding: var(--space-5) 0; } .focus__nav { display: flex; align-items: center; gap: var(--space-5); } .focus__stage { display: flex; flex-direction: column; align-items: center; gap: var(--space-4); min-width: 260px; } .hero { width: var(--hero-size); height: var(--hero-size); border-radius: 44px; display: flex; align-items: center; justify-content: center; font-size: 120px; background: color-mix(in srgb, var(--c) 16%, #fff); border: 4px solid color-mix(in srgb, var(--c) 35%, #fff); animation: floatY 3.5s ease-in-out infinite; } .hero--done { background: color-mix(in srgb, var(--c) 22%, #fff); border-color: var(--c); animation: pop 0.4s ease; } .focus__label { margin: 0; font-size: 2rem; text-transform: uppercase; text-align: center; color: var(--text-strong); } .navbtn { all: unset; cursor: pointer; width: var(--touch-nav); height: var(--touch-nav); border-radius: 50%; background: var(--surface); box-shadow: var(--shadow-btn); display: flex; align-items: center; justify-content: center; font-size: 38px; color: var(--text-4); } .navbtn:disabled { opacity: 0.3; cursor: default; } .dots { display: flex; gap: 10px; } .dot { width: 14px; height: 14px; border-radius: 50%; background: var(--border-2); transition: background 0.2s, transform 0.2s; } .dot--done { background: var(--accent-green); } .dot--current { transform: scale(1.4); box-shadow: 0 0 0 3px var(--surface-softer); } .focus__actions { display: flex; align-items: center; gap: var(--space-4); } .bigbtn { font-family: var(--font-display); font-weight: 700; font-size: 1.6rem; color: #fff; border: 0; border-radius: 24px; padding: 18px 48px; min-height: 72px; cursor: pointer; background: var(--accent-blue); transition: transform 0.12s; } .bigbtn--done { background: var(--accent-green); } .bigbtn:active { transform: scale(0.97); } .speakbtn { all: unset; cursor: pointer; font-size: 34px; } .focus__foot { margin: 0; color: var(--text-2); font-family: var(--font-display); font-weight: 600; } `, ], }) export class FocusViewComponent { @Input() set tasksInput(value: TaskView[]) { this.tasks = value; if (this.index() >= value.length) { this.index.set(Math.max(0, value.length - 1)); } } @Input() ttsEnabled = true; @Output() toggle = new EventEmitter(); @ViewChild('doneBtn') private doneBtn?: ElementRef; protected tasks: TaskView[] = []; protected readonly index = signal(0); protected readonly i18n = inject(I18nService); protected readonly tts = inject(TtsService); protected readonly current = computed(() => this.tasks[this.index()] ?? null); protected readonly remaining = computed(() => this.tasks.filter((t) => !t.done).length); protected readonly nextLabel = computed(() => { const nextTask = this.tasks[this.index() + 1]; return nextTask ? this.i18n.label(nextTask.labelEs, nextTask.labelCa) : 'โ€”'; }); prev(): void { this.index.update((i) => Math.max(0, i - 1)); } next(): void { this.index.update((i) => Math.min(this.tasks.length - 1, i + 1)); } emitToggle(): void { const task = this.current(); if (!task) { return; } const rect = this.doneBtn?.nativeElement.getBoundingClientRect(); this.toggle.emit({ taskId: task.id, x: rect ? rect.left + rect.width / 2 : window.innerWidth / 2, y: rect ? rect.top : window.innerHeight / 2, }); } speak(task: TaskView): void { this.tts.speak(this.i18n.label(task.labelEs, task.labelCa), this.i18n.lang()); } }