feat: complete Simple Mode contextual routing and navigation state synchronization

This commit is contained in:
dwindown
2026-03-15 07:24:13 +07:00
parent faadc1865d
commit 25728583b3
21 changed files with 1095 additions and 320 deletions

View File

@@ -1,6 +1,8 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:lucide_icons/lucide_icons.dart';
import '../../../app/theme/app_colors.dart';
import '../../../core/providers/theme_provider.dart';
import '../../../core/widgets/ios_toggle.dart';
@@ -136,7 +138,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
),
IconButton(
onPressed: () => _showEditProfileDialog(context),
icon: Icon(Icons.edit,
icon: Icon(LucideIcons.pencil,
size: 20, color: AppColors.primary),
),
],
@@ -149,7 +151,22 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
const SizedBox(height: 12),
_settingRow(
isDark,
icon: Icons.dark_mode,
icon: LucideIcons.layoutDashboard,
iconColor: const Color(0xFF0984E3),
title: 'Mode Aplikasi',
subtitle: _settings.simpleMode ? 'Simpel — Jadwal & Al-Quran' : 'Lengkap — Dengan Checklist & Poin',
trailing: IosToggle(
value: !_settings.simpleMode,
onChanged: (v) {
_settings.simpleMode = !v;
_saveSettings();
},
),
),
const SizedBox(height: 10),
_settingRow(
isDark,
icon: LucideIcons.moon,
iconColor: const Color(0xFF6C5CE7),
title: 'Mode Gelap',
trailing: IosToggle(
@@ -160,7 +177,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
const SizedBox(height: 10),
_settingRow(
isDark,
icon: Icons.notifications,
icon: LucideIcons.bell,
iconColor: const Color(0xFFE17055),
title: 'Notifikasi',
trailing: IosToggle(
@@ -170,32 +187,32 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
),
const SizedBox(height: 24),
// ── CHECKLIST IBADAH ──
// ── CHECKLIST IBADAH (always visible, even in Simple Mode per user request) ──
_sectionLabel('CHECKLIST IBADAH'),
const SizedBox(height: 12),
_settingRow(
isDark,
icon: Icons.mosque_outlined,
icon: LucideIcons.building,
iconColor: Colors.teal,
title: 'Tingkat Sholat Rawatib',
subtitle: _settings.rawatibLevel == 0 ? 'Mati' : (_settings.rawatibLevel == 1 ? 'Muakkad Saja' : 'Lengkap (Semua)'),
trailing: const Icon(Icons.chevron_right, size: 20),
trailing: const Icon(LucideIcons.chevronRight, size: 20),
onTap: () => _showRawatibDialog(context),
),
const SizedBox(height: 10),
_settingRow(
isDark,
icon: Icons.menu_book,
icon: LucideIcons.bookOpen,
iconColor: Colors.amber,
title: 'Target Tilawah',
subtitle: '${_settings.tilawahTargetValue} ${_settings.tilawahTargetUnit}',
trailing: const Icon(Icons.chevron_right, size: 20),
trailing: const Icon(LucideIcons.chevronRight, size: 20),
onTap: () => _showTilawahDialog(context),
),
const SizedBox(height: 10),
_settingRow(
isDark,
icon: Icons.sync,
icon: LucideIcons.refreshCw,
iconColor: Colors.blue,
title: 'Auto-Sync Tilawah',
subtitle: 'Catat otomatis dari menu Al-Quran',
@@ -218,11 +235,11 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
const SizedBox(height: 10),
_settingRow(
isDark,
icon: Icons.library_add_check,
icon: LucideIcons.listChecks,
iconColor: Colors.indigo,
title: 'Amalan Tambahan',
subtitle: 'Dzikir & Puasa Sunnah',
trailing: const Icon(Icons.chevron_right, size: 20),
trailing: const Icon(LucideIcons.chevronRight, size: 20),
onTap: () => _showAmalanDialog(context),
),
const SizedBox(height: 24),
@@ -232,31 +249,31 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
const SizedBox(height: 12),
_settingRow(
isDark,
icon: Icons.mosque,
icon: LucideIcons.building,
iconColor: AppColors.primary,
title: 'Metode Perhitungan',
subtitle: 'Kemenag RI',
trailing: const Icon(Icons.chevron_right, size: 20),
trailing: const Icon(LucideIcons.chevronRight, size: 20),
onTap: () => _showMethodDialog(context),
),
const SizedBox(height: 10),
_settingRow(
isDark,
icon: Icons.location_on,
icon: LucideIcons.mapPin,
iconColor: const Color(0xFF00B894),
title: 'Lokasi',
subtitle: _displayCityName,
trailing: const Icon(Icons.chevron_right, size: 20),
trailing: const Icon(LucideIcons.chevronRight, size: 20),
onTap: () => _showLocationDialog(context),
),
const SizedBox(height: 10),
_settingRow(
isDark,
icon: Icons.timer,
icon: LucideIcons.timer,
iconColor: const Color(0xFFFDAA5E),
title: 'Waktu Iqamah',
subtitle: 'Atur per waktu sholat',
trailing: const Icon(Icons.chevron_right, size: 20),
trailing: const Icon(LucideIcons.chevronRight, size: 20),
onTap: () => _showIqamahDialog(context),
),
const SizedBox(height: 24),
@@ -266,7 +283,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
const SizedBox(height: 12),
_settingRow(
isDark,
icon: Icons.text_fields,
icon: LucideIcons.type,
iconColor: const Color(0xFF636E72),
title: 'Ukuran Font Arab',
subtitle: '${_settings.arabicFontSize.round()}pt',
@@ -292,7 +309,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
const SizedBox(height: 12),
_settingRow(
isDark,
icon: Icons.info_outline,
icon: LucideIcons.info,
iconColor: AppColors.sage,
title: 'Versi Aplikasi',
subtitle: '1.0.0',
@@ -300,10 +317,10 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
const SizedBox(height: 10),
_settingRow(
isDark,
icon: Icons.favorite_outline,
icon: LucideIcons.heart,
iconColor: Colors.red,
title: 'Beri Nilai Kami',
trailing: const Icon(Icons.chevron_right, size: 20),
trailing: const Icon(LucideIcons.chevronRight, size: 20),
onTap: () {},
),
const SizedBox(height: 24),
@@ -324,7 +341,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
child: const Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.logout, color: Colors.red, size: 20),
Icon(LucideIcons.logOut, color: Colors.red, size: 20),
SizedBox(width: 8),
Text(
'Hapus Semua Data',
@@ -447,6 +464,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
final searchCtrl = TextEditingController();
bool isSearching = false;
List<Map<String, dynamic>> results = [];
Timer? debounce;
showDialog(
context: context,
@@ -466,7 +484,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
hintText: 'Cth: Jakarta',
border: const OutlineInputBorder(),
suffixIcon: IconButton(
icon: const Icon(Icons.search),
icon: const Icon(LucideIcons.search),
onPressed: () async {
if (searchCtrl.text.trim().isEmpty) return;
setDialogState(() => isSearching = true);
@@ -479,15 +497,45 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
},
),
),
onChanged: (val) {
if (val.trim().length < 3) return;
if (debounce?.isActive ?? false) debounce!.cancel();
debounce = Timer(const Duration(milliseconds: 500), () async {
if (!mounted) return;
setDialogState(() => isSearching = true);
try {
final res = await MyQuranSholatService.instance.searchCity(val.trim());
if (mounted) {
setDialogState(() {
results = res;
});
}
} catch (e) {
debugPrint('Error searching city: $e');
} finally {
if (mounted) {
setDialogState(() {
isSearching = false;
});
}
}
});
},
onSubmitted: (val) async {
if (val.trim().isEmpty) return;
if (debounce?.isActive ?? false) debounce!.cancel();
setDialogState(() => isSearching = true);
final res = await MyQuranSholatService.instance
.searchCity(val.trim());
setDialogState(() {
results = res;
isSearching = false;
});
if (mounted) {
setDialogState(() {
results = res;
isSearching = false;
});
}
},
),
const SizedBox(height: 16),
@@ -670,7 +718,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
const Text('Sholat Rawatib', style: TextStyle(fontSize: 18)),
const Spacer(),
IconButton(
icon: const Icon(Icons.info_outline, color: AppColors.primary),
icon: const Icon(LucideIcons.info, color: AppColors.primary),
onPressed: () {
showModalBottomSheet(
context: context,