Clean TV navigation traces and update app icons
This commit is contained in:
@@ -10,6 +10,7 @@ import '../../core/sacred_tokens.dart';
|
||||
import '../../providers.dart';
|
||||
import '../../data/services/sync_service.dart';
|
||||
import '../../data/services/myquran_service.dart';
|
||||
import '../../data/services/sound_service.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'dart:io';
|
||||
|
||||
@@ -120,7 +121,7 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
_simulasiFocusNodes = [
|
||||
_simulasiEntryFocusNode,
|
||||
...List.generate(
|
||||
6,
|
||||
8,
|
||||
(index) => FocusNode(debugLabel: 'simulasi_row_${index + 1}'),
|
||||
),
|
||||
];
|
||||
@@ -1005,16 +1006,8 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
setState(() => _selectedTab = index);
|
||||
}
|
||||
|
||||
void _traceNav(String message) {
|
||||
assert(() {
|
||||
debugPrint('[TV NAV] $message');
|
||||
return true;
|
||||
}());
|
||||
}
|
||||
|
||||
void _focusNavTab(int index) {
|
||||
if (index < 0 || index >= _navFocusNodes.length) return;
|
||||
_traceNav('focus nav[$index]');
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) {
|
||||
_navFocusNodes[index].requestFocus();
|
||||
@@ -1025,7 +1018,6 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
void _focusIdentityRow(int index) {
|
||||
if (_selectedTab != 0) return;
|
||||
if (index < 0 || index >= _identityFocusNodes.length) return;
|
||||
_traceNav('focus identitas[$index]');
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) {
|
||||
_identityFocusNodes[index].requestFocus();
|
||||
@@ -1036,7 +1028,6 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
void _focusJumatRow(int index) {
|
||||
if (_selectedTab != 3) return;
|
||||
if (index < 0 || index >= _jumatFocusNodes.length) return;
|
||||
_traceNav('focus jumat[$index]');
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) {
|
||||
_jumatFocusNodes[index].requestFocus();
|
||||
@@ -1047,7 +1038,6 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
void _focusSimulasiRow(int index) {
|
||||
if (_selectedTab != 4) return;
|
||||
if (index < 0 || index >= _simulasiFocusNodes.length) return;
|
||||
_traceNav('focus simulasi[$index]');
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) {
|
||||
_simulasiFocusNodes[index].requestFocus();
|
||||
@@ -1210,7 +1200,6 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
final key = event.logicalKey;
|
||||
_traceNav('identitas[$index] key=$key');
|
||||
if (key == LogicalKeyboardKey.arrowUp) {
|
||||
_focusIdentityRow(index - 1);
|
||||
return KeyEventResult.handled;
|
||||
@@ -1274,7 +1263,6 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
final key = event.logicalKey;
|
||||
_traceNav('simulasi[$index] key=$key');
|
||||
if (key == LogicalKeyboardKey.arrowUp) {
|
||||
_focusSimulasiRow(index - 1);
|
||||
return KeyEventResult.handled;
|
||||
@@ -3393,6 +3381,18 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
rowIndex: 0,
|
||||
),
|
||||
SizedBox(height: 16 * s),
|
||||
_simulasiCard(
|
||||
s: s,
|
||||
title: '15 Detik Sebelum Adzan',
|
||||
icon: HugeIcons.strokeRoundedNotification03,
|
||||
desc: 'Melompat ke 15 detik sebelum Adzan Dzuhur untuk memeriksa transisi terakhir menuju Adzan.',
|
||||
onTap: () => _activateSimulation(
|
||||
() => _simulateEvent('pre_adzan_15'),
|
||||
),
|
||||
focusNode: _simulasiFocusNodes[1],
|
||||
rowIndex: 1,
|
||||
),
|
||||
SizedBox(height: 16 * s),
|
||||
_simulasiCard(
|
||||
s: s,
|
||||
title: 'Menuju Adzan',
|
||||
@@ -3401,8 +3401,8 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
onTap: () => _activateSimulation(
|
||||
() => _simulateEvent('pre_adzan'),
|
||||
),
|
||||
focusNode: _simulasiFocusNodes[1],
|
||||
rowIndex: 1,
|
||||
focusNode: _simulasiFocusNodes[2],
|
||||
rowIndex: 2,
|
||||
),
|
||||
SizedBox(height: 16 * s),
|
||||
_simulasiCard(
|
||||
@@ -3413,8 +3413,20 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
onTap: () => _activateSimulation(
|
||||
() => _simulateEvent('adzan'),
|
||||
),
|
||||
focusNode: _simulasiFocusNodes[2],
|
||||
rowIndex: 2,
|
||||
focusNode: _simulasiFocusNodes[3],
|
||||
rowIndex: 3,
|
||||
),
|
||||
SizedBox(height: 16 * s),
|
||||
_simulasiCard(
|
||||
s: s,
|
||||
title: '15 Detik Sebelum Iqamah',
|
||||
icon: HugeIcons.strokeRoundedTimer02,
|
||||
desc: 'Melompat ke 15 detik sebelum Iqamah Dzuhur untuk memeriksa hitungan mundur terakhir.',
|
||||
onTap: () => _activateSimulation(
|
||||
() => _simulateEvent('pre_iqomah_15'),
|
||||
),
|
||||
focusNode: _simulasiFocusNodes[4],
|
||||
rowIndex: 4,
|
||||
),
|
||||
SizedBox(height: 16 * s),
|
||||
_simulasiCard(
|
||||
@@ -3425,8 +3437,8 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
onTap: () => _activateSimulation(
|
||||
() => _simulateEvent('iqomah'),
|
||||
),
|
||||
focusNode: _simulasiFocusNodes[3],
|
||||
rowIndex: 3,
|
||||
focusNode: _simulasiFocusNodes[5],
|
||||
rowIndex: 5,
|
||||
),
|
||||
SizedBox(height: 16 * s),
|
||||
_simulasiCard(
|
||||
@@ -3437,8 +3449,8 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
onTap: () => _activateSimulation(
|
||||
() => _simulateEvent('jumat_incoming'),
|
||||
),
|
||||
focusNode: _simulasiFocusNodes[4],
|
||||
rowIndex: 4,
|
||||
focusNode: _simulasiFocusNodes[6],
|
||||
rowIndex: 6,
|
||||
),
|
||||
SizedBox(height: 16 * s),
|
||||
_simulasiCard(
|
||||
@@ -3449,8 +3461,8 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
onTap: () => _activateSimulation(
|
||||
() => _simulateEvent('jumat_khutbah'),
|
||||
),
|
||||
focusNode: _simulasiFocusNodes[5],
|
||||
rowIndex: 5,
|
||||
focusNode: _simulasiFocusNodes[7],
|
||||
rowIndex: 7,
|
||||
),
|
||||
SizedBox(height: 16 * s),
|
||||
_simulasiCard(
|
||||
@@ -3461,8 +3473,8 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
onTap: () => _activateSimulation(
|
||||
() => _simulateEvent('shalat'),
|
||||
),
|
||||
focusNode: _simulasiFocusNodes[6],
|
||||
rowIndex: 6,
|
||||
focusNode: _simulasiFocusNodes[8],
|
||||
rowIndex: 8,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -3598,12 +3610,21 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
DateTime targetTime;
|
||||
|
||||
switch (eventType) {
|
||||
case 'pre_adzan_15':
|
||||
targetTime = dzuhurTime.subtract(const Duration(seconds: 15));
|
||||
break;
|
||||
case 'pre_adzan':
|
||||
targetTime = dzuhurTime.subtract(const Duration(minutes: 2));
|
||||
break;
|
||||
case 'adzan':
|
||||
targetTime = dzuhurTime;
|
||||
break;
|
||||
case 'pre_iqomah_15':
|
||||
final settings = ref.read(settingsProvider);
|
||||
targetTime = dzuhurTime
|
||||
.add(Duration(minutes: settings.iqomahDzuhur))
|
||||
.subtract(const Duration(seconds: 15));
|
||||
break;
|
||||
case 'iqomah':
|
||||
targetTime = dzuhurTime.add(const Duration(seconds: 45)); // During iqomah
|
||||
break;
|
||||
@@ -3630,6 +3651,17 @@ class _AdminScreenState extends ConsumerState<AdminScreen> {
|
||||
|
||||
final offset = targetTime.difference(realNow);
|
||||
_simulateTimeOffset(offset);
|
||||
|
||||
switch (eventType) {
|
||||
case 'adzan':
|
||||
unawaited(SoundService.instance.playAdzanBeep());
|
||||
break;
|
||||
case 'iqomah':
|
||||
unawaited(SoundService.instance.playIqomahCountdown());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void _activateSimulation(VoidCallback action) {
|
||||
|
||||
Reference in New Issue
Block a user