import 'dart:convert'; import 'package:contacts_plus_plus/models/friend.dart'; import 'package:contacts_plus_plus/models/sem_ver.dart'; class SettingsEntry { final T? value; final T deflt; const SettingsEntry({this.value, required this.deflt}); factory SettingsEntry.fromMap(Map map) { return SettingsEntry( value: jsonDecode(map["value"]) as T?, deflt: map["default"], ); } Map toMap() { return { "value": jsonEncode(value), "default": deflt, }; } T get valueOrDefault => value ?? deflt; SettingsEntry withValue({required T newValue}) => SettingsEntry(value: newValue, deflt: deflt); SettingsEntry passThrough(T? newValue) { return newValue == null ? this : this.withValue(newValue: newValue); } } class Settings { final SettingsEntry notificationsDenied; final SettingsEntry unreadCheckIntervalMinutes; final SettingsEntry lastOnlineStatus; final SettingsEntry lastDismissedVersion; Settings({ SettingsEntry? notificationsDenied, SettingsEntry? unreadCheckIntervalMinutes, SettingsEntry? lastOnlineStatus, SettingsEntry? lastDismissedVersion }) : notificationsDenied = notificationsDenied ?? const SettingsEntry(deflt: false), unreadCheckIntervalMinutes = unreadCheckIntervalMinutes ?? const SettingsEntry(deflt: 60), lastOnlineStatus = lastOnlineStatus ?? SettingsEntry(deflt: OnlineStatus.online.index), lastDismissedVersion = lastDismissedVersion ?? SettingsEntry(deflt: SemVer.zero().toString()) ; factory Settings.fromMap(Map map) { return Settings( notificationsDenied: retrieveEntryOrNull(map["notificationsDenied"]), unreadCheckIntervalMinutes: retrieveEntryOrNull(map["unreadCheckIntervalMinutes"]), lastOnlineStatus: retrieveEntryOrNull(map["lastOnlineStatus"]), lastDismissedVersion: retrieveEntryOrNull(map["lastDismissedVersion"]) ); } static SettingsEntry? retrieveEntryOrNull(Map? map) { if (map == null) return null; try { return SettingsEntry.fromMap(map); } catch (_) { return null; } } Map toMap() { return { "notificationsDenied": notificationsDenied.toMap(), "unreadCheckIntervalMinutes": unreadCheckIntervalMinutes.toMap(), "lastOnlineStatus": lastOnlineStatus.toMap(), "lastDismissedVersion": lastDismissedVersion.toMap(), }; } Settings copy() => copyWith(); Settings copyWith({ bool? notificationsDenied, int? unreadCheckIntervalMinutes, int? lastOnlineStatus, String? lastDismissedVersion, }) { return Settings( notificationsDenied: this.notificationsDenied.passThrough(notificationsDenied), unreadCheckIntervalMinutes: this.unreadCheckIntervalMinutes.passThrough(unreadCheckIntervalMinutes), lastOnlineStatus: this.lastOnlineStatus.passThrough(lastOnlineStatus), lastDismissedVersion: this.lastDismissedVersion.passThrough(lastDismissedVersion), ); } }