Polish navigation, Quran flows, and sharing UX
This commit is contained in:
@@ -21,6 +21,8 @@ class HiveBoxes {
|
||||
static const String dzikirCounters = 'dzikir_counters';
|
||||
static const String bookmarks = 'bookmarks';
|
||||
static const String cachedPrayerTimes = 'cached_prayer_times';
|
||||
static const String notificationInbox = 'notification_inbox';
|
||||
static const String notificationRuntime = 'notification_runtime';
|
||||
}
|
||||
|
||||
/// Initialize Hive and open all boxes.
|
||||
@@ -56,6 +58,8 @@ Future<void> initHive() async {
|
||||
await Hive.openBox<DzikirCounter>(HiveBoxes.dzikirCounters);
|
||||
await Hive.openBox<QuranBookmark>(HiveBoxes.bookmarks);
|
||||
await Hive.openBox<CachedPrayerTimes>(HiveBoxes.cachedPrayerTimes);
|
||||
await Hive.openBox(HiveBoxes.notificationInbox);
|
||||
await Hive.openBox(HiveBoxes.notificationRuntime);
|
||||
|
||||
// MIGRATION: Delete legacy logs that crash due to type casts (Map<String, bool> vs Map<String, ShalatLog>)
|
||||
final keysToDelete = [];
|
||||
@@ -69,7 +73,7 @@ Future<void> initHive() async {
|
||||
keysToDelete.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (keysToDelete.isNotEmpty) {
|
||||
await worshipBox.deleteAll(keysToDelete);
|
||||
debugPrint('Deleted ${keysToDelete.length} legacy worship logs.');
|
||||
@@ -89,26 +93,53 @@ Future<void> seedDefaults() async {
|
||||
if (checklistBox.isEmpty) {
|
||||
final defaults = [
|
||||
ChecklistItem(
|
||||
id: 'fajr', title: 'Sholat Fajr', category: 'sholat_fardhu', sortOrder: 0),
|
||||
id: 'fajr',
|
||||
title: 'Sholat Fajr',
|
||||
category: 'sholat_fardhu',
|
||||
sortOrder: 0),
|
||||
ChecklistItem(
|
||||
id: 'dhuhr', title: 'Sholat Dhuhr', category: 'sholat_fardhu', sortOrder: 1),
|
||||
id: 'dhuhr',
|
||||
title: 'Sholat Dhuhr',
|
||||
category: 'sholat_fardhu',
|
||||
sortOrder: 1),
|
||||
ChecklistItem(
|
||||
id: 'asr', title: 'Sholat Asr', category: 'sholat_fardhu', sortOrder: 2),
|
||||
id: 'asr',
|
||||
title: 'Sholat Asr',
|
||||
category: 'sholat_fardhu',
|
||||
sortOrder: 2),
|
||||
ChecklistItem(
|
||||
id: 'maghrib', title: 'Sholat Maghrib', category: 'sholat_fardhu', sortOrder: 3),
|
||||
id: 'maghrib',
|
||||
title: 'Sholat Maghrib',
|
||||
category: 'sholat_fardhu',
|
||||
sortOrder: 3),
|
||||
ChecklistItem(
|
||||
id: 'isha', title: 'Sholat Isha', category: 'sholat_fardhu', sortOrder: 4),
|
||||
id: 'isha',
|
||||
title: 'Sholat Isha',
|
||||
category: 'sholat_fardhu',
|
||||
sortOrder: 4),
|
||||
ChecklistItem(
|
||||
id: 'tilawah', title: 'Tilawah Quran', category: 'tilawah',
|
||||
subtitle: '1 Juz', sortOrder: 5),
|
||||
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),
|
||||
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),
|
||||
id: 'dzikir_petang',
|
||||
title: 'Dzikir Petang',
|
||||
category: 'dzikir',
|
||||
subtitle: '1 session',
|
||||
sortOrder: 7),
|
||||
ChecklistItem(
|
||||
id: 'rawatib', title: 'Sholat Sunnah Rawatib', category: 'sunnah', sortOrder: 8),
|
||||
id: 'rawatib',
|
||||
title: 'Sholat Sunnah Rawatib',
|
||||
category: 'sunnah',
|
||||
sortOrder: 8),
|
||||
ChecklistItem(
|
||||
id: 'shodaqoh', title: 'Shodaqoh', category: 'charity', sortOrder: 9),
|
||||
];
|
||||
|
||||
@@ -77,6 +77,33 @@ class AppSettings extends HiveObject {
|
||||
@HiveField(23)
|
||||
bool dzikirHapticOnCount;
|
||||
|
||||
@HiveField(24)
|
||||
bool alertsEnabled;
|
||||
|
||||
@HiveField(25)
|
||||
bool inboxEnabled;
|
||||
|
||||
@HiveField(26)
|
||||
bool streakRiskEnabled;
|
||||
|
||||
@HiveField(27)
|
||||
bool dailyChecklistReminderEnabled;
|
||||
|
||||
@HiveField(28)
|
||||
bool weeklySummaryEnabled;
|
||||
|
||||
@HiveField(29)
|
||||
String quietHoursStart; // HH:mm
|
||||
|
||||
@HiveField(30)
|
||||
String quietHoursEnd; // HH:mm
|
||||
|
||||
@HiveField(31)
|
||||
int maxNonPrayerPushPerDay;
|
||||
|
||||
@HiveField(32)
|
||||
bool mirrorAdzanToInbox;
|
||||
|
||||
AppSettings({
|
||||
this.userName = 'User',
|
||||
this.userEmail = '',
|
||||
@@ -102,6 +129,15 @@ class AppSettings extends HiveObject {
|
||||
this.dzikirCounterButtonPosition = 'bottomPill',
|
||||
this.dzikirAutoAdvance = true,
|
||||
this.dzikirHapticOnCount = true,
|
||||
this.alertsEnabled = true,
|
||||
this.inboxEnabled = true,
|
||||
this.streakRiskEnabled = true,
|
||||
this.dailyChecklistReminderEnabled = false,
|
||||
this.weeklySummaryEnabled = true,
|
||||
this.quietHoursStart = '22:00',
|
||||
this.quietHoursEnd = '05:00',
|
||||
this.maxNonPrayerPushPerDay = 2,
|
||||
this.mirrorAdzanToInbox = false,
|
||||
}) : adhanEnabled = adhanEnabled ??
|
||||
{
|
||||
'fajr': true,
|
||||
|
||||
@@ -20,34 +20,65 @@ class AppSettingsAdapter extends TypeAdapter<AppSettings> {
|
||||
userName: fields.containsKey(0) ? fields[0] as String? ?? '' : '',
|
||||
userEmail: fields.containsKey(1) ? fields[1] as String? ?? '' : '',
|
||||
themeModeIndex: fields.containsKey(2) ? fields[2] as int? ?? 0 : 0,
|
||||
arabicFontSize: fields.containsKey(3) ? fields[3] as double? ?? 26.0 : 26.0,
|
||||
arabicFontSize:
|
||||
fields.containsKey(3) ? fields[3] as double? ?? 26.0 : 26.0,
|
||||
uiLanguage: fields.containsKey(4) ? fields[4] as String? ?? 'id' : 'id',
|
||||
adhanEnabled: fields.containsKey(5) ? (fields[5] as Map?)?.cast<String, bool>() : null,
|
||||
iqamahOffset: fields.containsKey(6) ? (fields[6] as Map?)?.cast<String, int>() : null,
|
||||
checklistReminderTime: fields.containsKey(7) ? fields[7] as String? : null,
|
||||
adhanEnabled: fields.containsKey(5)
|
||||
? (fields[5] as Map?)?.cast<String, bool>()
|
||||
: null,
|
||||
iqamahOffset: fields.containsKey(6)
|
||||
? (fields[6] as Map?)?.cast<String, int>()
|
||||
: null,
|
||||
checklistReminderTime:
|
||||
fields.containsKey(7) ? fields[7] as String? : null,
|
||||
lastLat: fields.containsKey(8) ? fields[8] as double? : null,
|
||||
lastLng: fields.containsKey(9) ? fields[9] as double? : null,
|
||||
lastCityName: fields.containsKey(10) ? fields[10] as String? : null,
|
||||
rawatibLevel: fields.containsKey(11) ? fields[11] as int? ?? 1 : 1,
|
||||
tilawahTargetValue: fields.containsKey(12) ? fields[12] as int? ?? 1 : 1,
|
||||
tilawahTargetUnit: fields.containsKey(13) ? fields[13] as String? ?? 'Juz' : 'Juz',
|
||||
tilawahAutoSync: fields.containsKey(14) ? fields[14] as bool? ?? false : false,
|
||||
tilawahTargetUnit:
|
||||
fields.containsKey(13) ? fields[13] as String? ?? 'Juz' : 'Juz',
|
||||
tilawahAutoSync:
|
||||
fields.containsKey(14) ? fields[14] as bool? ?? false : false,
|
||||
trackDzikir: fields.containsKey(15) ? fields[15] as bool? ?? true : true,
|
||||
trackPuasa: fields.containsKey(16) ? fields[16] as bool? ?? false : false,
|
||||
showLatin: fields.containsKey(17) ? fields[17] as bool? ?? true : true,
|
||||
showTerjemahan: fields.containsKey(18) ? fields[18] as bool? ?? true : true,
|
||||
showTerjemahan:
|
||||
fields.containsKey(18) ? fields[18] as bool? ?? true : true,
|
||||
simpleMode: fields.containsKey(19) ? fields[19] as bool? ?? false : false,
|
||||
dzikirDisplayMode: fields.containsKey(20) ? fields[20] as String? ?? 'list' : 'list',
|
||||
dzikirCounterButtonPosition: fields.containsKey(21) ? fields[21] as String? ?? 'bottomPill' : 'bottomPill',
|
||||
dzikirAutoAdvance: fields.containsKey(22) ? fields[22] as bool? ?? true : true,
|
||||
dzikirHapticOnCount: fields.containsKey(23) ? fields[23] as bool? ?? true : true,
|
||||
dzikirDisplayMode:
|
||||
fields.containsKey(20) ? fields[20] as String? ?? 'list' : 'list',
|
||||
dzikirCounterButtonPosition: fields.containsKey(21)
|
||||
? fields[21] as String? ?? 'bottomPill'
|
||||
: 'bottomPill',
|
||||
dzikirAutoAdvance:
|
||||
fields.containsKey(22) ? fields[22] as bool? ?? true : true,
|
||||
dzikirHapticOnCount:
|
||||
fields.containsKey(23) ? fields[23] as bool? ?? true : true,
|
||||
alertsEnabled:
|
||||
fields.containsKey(24) ? fields[24] as bool? ?? true : true,
|
||||
inboxEnabled: fields.containsKey(25) ? fields[25] as bool? ?? true : true,
|
||||
streakRiskEnabled:
|
||||
fields.containsKey(26) ? fields[26] as bool? ?? true : true,
|
||||
dailyChecklistReminderEnabled:
|
||||
fields.containsKey(27) ? fields[27] as bool? ?? false : false,
|
||||
weeklySummaryEnabled:
|
||||
fields.containsKey(28) ? fields[28] as bool? ?? true : true,
|
||||
quietHoursStart:
|
||||
fields.containsKey(29) ? fields[29] as String? ?? '22:00' : '22:00',
|
||||
quietHoursEnd:
|
||||
fields.containsKey(30) ? fields[30] as String? ?? '05:00' : '05:00',
|
||||
maxNonPrayerPushPerDay:
|
||||
fields.containsKey(31) ? fields[31] as int? ?? 2 : 2,
|
||||
mirrorAdzanToInbox:
|
||||
fields.containsKey(32) ? fields[32] as bool? ?? false : false,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, AppSettings obj) {
|
||||
writer
|
||||
..writeByte(24)
|
||||
..writeByte(33)
|
||||
..writeByte(0)
|
||||
..write(obj.userName)
|
||||
..writeByte(1)
|
||||
@@ -95,7 +126,25 @@ class AppSettingsAdapter extends TypeAdapter<AppSettings> {
|
||||
..writeByte(22)
|
||||
..write(obj.dzikirAutoAdvance)
|
||||
..writeByte(23)
|
||||
..write(obj.dzikirHapticOnCount);
|
||||
..write(obj.dzikirHapticOnCount)
|
||||
..writeByte(24)
|
||||
..write(obj.alertsEnabled)
|
||||
..writeByte(25)
|
||||
..write(obj.inboxEnabled)
|
||||
..writeByte(26)
|
||||
..write(obj.streakRiskEnabled)
|
||||
..writeByte(27)
|
||||
..write(obj.dailyChecklistReminderEnabled)
|
||||
..writeByte(28)
|
||||
..write(obj.weeklySummaryEnabled)
|
||||
..writeByte(29)
|
||||
..write(obj.quietHoursStart)
|
||||
..writeByte(30)
|
||||
..write(obj.quietHoursEnd)
|
||||
..writeByte(31)
|
||||
..write(obj.maxNonPrayerPushPerDay)
|
||||
..writeByte(32)
|
||||
..write(obj.mirrorAdzanToInbox);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
Reference in New Issue
Block a user