- Murattal: Spotify-style 5-button controls [Shuffle, Prev, Play, Next, Playlist] - Murattal: Animated 7-bar equalizer visualization in player circle - Murattal: Unsplash API background with frosted glass player overlay - Murattal: Transparent AppBar with backdrop blur - Murattal: Surah playlist bottom sheet with full 114 Surah list - Murattal: Auto-play disabled on screen open, enabled on navigation - Murattal: Shuffle mode for random Surah playback - Murattal: Photographer attribution per Unsplash guidelines - Dashboard: Auto-scroll prayer schedule to next active prayer - Fix: setState lifecycle errors on Reading & Murattal screens - Setup: flutter_dotenv, cached_network_image, url_launcher deps
120 lines
4.3 KiB
Dart
120 lines
4.3 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:hive_flutter/hive_flutter.dart';
|
|
import 'models/app_settings.dart';
|
|
import 'models/checklist_item.dart';
|
|
import 'models/daily_worship_log.dart';
|
|
import 'models/dzikir_counter.dart';
|
|
import 'models/quran_bookmark.dart';
|
|
import 'models/cached_prayer_times.dart';
|
|
import 'models/shalat_log.dart';
|
|
import 'models/tilawah_log.dart';
|
|
import 'models/dzikir_log.dart';
|
|
import 'models/puasa_log.dart';
|
|
|
|
/// Box name constants for Hive.
|
|
class HiveBoxes {
|
|
HiveBoxes._();
|
|
|
|
static const String settings = 'settings';
|
|
static const String checklistItems = 'checklist_items';
|
|
static const String worshipLogs = 'worship_logs';
|
|
static const String dzikirCounters = 'dzikir_counters';
|
|
static const String bookmarks = 'bookmarks';
|
|
static const String cachedPrayerTimes = 'cached_prayer_times';
|
|
}
|
|
|
|
/// Initialize Hive and open all boxes.
|
|
Future<void> initHive() async {
|
|
await Hive.initFlutter();
|
|
|
|
// Register adapters
|
|
Hive.registerAdapter(AppSettingsAdapter());
|
|
Hive.registerAdapter(ChecklistItemAdapter());
|
|
Hive.registerAdapter(DailyWorshipLogAdapter());
|
|
Hive.registerAdapter(DzikirCounterAdapter());
|
|
Hive.registerAdapter(QuranBookmarkAdapter());
|
|
Hive.registerAdapter(CachedPrayerTimesAdapter());
|
|
Hive.registerAdapter(ShalatLogAdapter());
|
|
Hive.registerAdapter(TilawahLogAdapter());
|
|
Hive.registerAdapter(DzikirLogAdapter());
|
|
Hive.registerAdapter(PuasaLogAdapter());
|
|
|
|
// Open boxes
|
|
try {
|
|
await Hive.openBox<AppSettings>(HiveBoxes.settings);
|
|
} catch (e) {
|
|
debugPrint('Settings box corrupted, resetting: $e');
|
|
if (Hive.isBoxOpen(HiveBoxes.settings)) {
|
|
await Hive.box<AppSettings>(HiveBoxes.settings).close();
|
|
}
|
|
await Hive.deleteBoxFromDisk(HiveBoxes.settings);
|
|
await Hive.openBox<AppSettings>(HiveBoxes.settings);
|
|
}
|
|
|
|
await Hive.openBox<ChecklistItem>(HiveBoxes.checklistItems);
|
|
final worshipBox = await Hive.openBox<DailyWorshipLog>(HiveBoxes.worshipLogs);
|
|
await Hive.openBox<DzikirCounter>(HiveBoxes.dzikirCounters);
|
|
await Hive.openBox<QuranBookmark>(HiveBoxes.bookmarks);
|
|
await Hive.openBox<CachedPrayerTimes>(HiveBoxes.cachedPrayerTimes);
|
|
|
|
// MIGRATION: Delete legacy logs that crash due to type casts (Map<String, bool> vs Map<String, ShalatLog>)
|
|
final keysToDelete = [];
|
|
for (final key in worshipBox.keys) {
|
|
try {
|
|
final log = worshipBox.get(key);
|
|
if (log != null) {
|
|
log.shalatLogs.values.toList(); // Force evaluation
|
|
}
|
|
} catch (_) {
|
|
keysToDelete.add(key);
|
|
}
|
|
}
|
|
|
|
if (keysToDelete.isNotEmpty) {
|
|
await worshipBox.deleteAll(keysToDelete);
|
|
debugPrint('Deleted ${keysToDelete.length} legacy worship logs.');
|
|
}
|
|
}
|
|
|
|
/// Seeds default settings and checklist items on first launch.
|
|
Future<void> seedDefaults() async {
|
|
// Seed AppSettings
|
|
final settingsBox = Hive.box<AppSettings>(HiveBoxes.settings);
|
|
if (settingsBox.isEmpty) {
|
|
await settingsBox.put('default', AppSettings());
|
|
}
|
|
|
|
// Seed default checklist items
|
|
final checklistBox = Hive.box<ChecklistItem>(HiveBoxes.checklistItems);
|
|
if (checklistBox.isEmpty) {
|
|
final defaults = [
|
|
ChecklistItem(
|
|
id: 'fajr', title: 'Sholat Fajr', category: 'sholat_fardhu', sortOrder: 0),
|
|
ChecklistItem(
|
|
id: 'dhuhr', title: 'Sholat Dhuhr', category: 'sholat_fardhu', sortOrder: 1),
|
|
ChecklistItem(
|
|
id: 'asr', title: 'Sholat Asr', category: 'sholat_fardhu', sortOrder: 2),
|
|
ChecklistItem(
|
|
id: 'maghrib', title: 'Sholat Maghrib', category: 'sholat_fardhu', sortOrder: 3),
|
|
ChecklistItem(
|
|
id: 'isha', title: 'Sholat Isha', category: 'sholat_fardhu', sortOrder: 4),
|
|
ChecklistItem(
|
|
id: 'tilawah', title: 'Tilawah Quran', category: 'tilawah',
|
|
subtitle: '1 Juz', sortOrder: 5),
|
|
ChecklistItem(
|
|
id: 'dzikir_pagi', title: 'Dzikir Pagi', category: 'dzikir',
|
|
subtitle: '1 session', sortOrder: 6),
|
|
ChecklistItem(
|
|
id: 'dzikir_petang', title: 'Dzikir Petang', category: 'dzikir',
|
|
subtitle: '1 session', sortOrder: 7),
|
|
ChecklistItem(
|
|
id: 'rawatib', title: 'Sholat Sunnah Rawatib', category: 'sunnah', sortOrder: 8),
|
|
ChecklistItem(
|
|
id: 'shodaqoh', title: 'Shodaqoh', category: 'charity', sortOrder: 9),
|
|
];
|
|
for (final item in defaults) {
|
|
await checklistBox.put(item.id, item);
|
|
}
|
|
}
|
|
}
|