import 'package:shared_preferences/shared_preferences.dart'; import 'package:gitjournal/core/sorting_mode.dart'; class Settings { static List changeObservers = []; // singleton static final Settings _singleton = Settings._internal(); factory Settings() => _singleton; Settings._internal(); static Settings get instance => _singleton; // Properties String gitAuthor = "GitJournal"; String gitAuthorEmail = "app@gitjournal.io"; NoteFileNameFormat noteFileNameFormat; bool collectUsageStatistics = true; bool collectCrashReports = true; String yamlModifiedKey = "modified"; bool yamlHeaderEnabled = true; String defaultNewNoteFolder = "journal"; RemoteSyncFrequency remoteSyncFrequency = RemoteSyncFrequency.Default; SortingMode sortingMode = SortingMode.Default; SettingsEditorType defaultEditor = SettingsEditorType.Default; SettingsFolderViewType defaultView = SettingsFolderViewType.Default; bool showNoteSummary = true; String folderViewHeaderType = "TitleGenerated"; int version = 0; void load(SharedPreferences pref) { gitAuthor = pref.getString("gitAuthor") ?? gitAuthor; gitAuthorEmail = pref.getString("gitAuthorEmail") ?? gitAuthorEmail; noteFileNameFormat = NoteFileNameFormat.fromInternalString( pref.getString("noteFileNameFormat")); collectUsageStatistics = pref.getBool("collectCrashReports") ?? collectUsageStatistics; collectCrashReports = pref.getBool("collectCrashReports") ?? collectCrashReports; yamlModifiedKey = pref.getString("yamlModifiedKey") ?? yamlModifiedKey; yamlHeaderEnabled = pref.getBool("yamlHeaderEnabled") ?? yamlHeaderEnabled; defaultNewNoteFolder = pref.getString("defaultNewNoteFolder") ?? defaultNewNoteFolder; remoteSyncFrequency = RemoteSyncFrequency.fromInternalString( pref.getString("remoteSyncFrequency")); sortingMode = SortingMode.fromInternalString(pref.getString("sortingMode")); defaultEditor = SettingsEditorType.fromInternalString(pref.getString("defaultEditor")); defaultView = SettingsFolderViewType.fromInternalString( pref.getString("defaultView")); showNoteSummary = pref.getBool("showNoteSummary") ?? showNoteSummary; folderViewHeaderType = pref.getString("folderViewHeaderType") ?? folderViewHeaderType; version = pref.getInt("settingsVersion") ?? version; } Future save() async { var pref = await SharedPreferences.getInstance(); pref.setString("gitAuthor", gitAuthor); pref.setString("gitAuthorEmail", gitAuthorEmail); pref.setString("noteFileNameFormat", noteFileNameFormat.toInternalString()); pref.setBool("collectUsageStatistics", collectUsageStatistics); pref.setBool("collectCrashReports", collectCrashReports); pref.setString("yamlModifiedKey", yamlModifiedKey); pref.setBool("yamlHeaderEnabled", yamlHeaderEnabled); pref.setString("defaultNewNoteFolder", defaultNewNoteFolder); pref.setString( "remoteSyncFrequency", remoteSyncFrequency.toInternalString()); pref.setString("sortingMode", sortingMode.toInternalString()); pref.setString("defaultEditor", defaultEditor.toInternalString()); pref.setString("defaultView", defaultView.toInternalString()); pref.setBool("showNoteSummary", showNoteSummary); pref.setString("folderViewHeaderType", folderViewHeaderType); pref.setInt("settingsVersion", version); // Shouldn't we check if something has actually changed? for (var f in changeObservers) { f(); } } Map toMap() { return { "gitAuthor": gitAuthor, "gitAuthorEmail": gitAuthorEmail, "noteFileNameFormat": noteFileNameFormat.toInternalString(), "collectUsageStatistics": collectUsageStatistics, "collectCrashReports": collectCrashReports, "yamlModifiedKey": yamlModifiedKey, "yamlHeaderEnabled": yamlHeaderEnabled, "defaultNewNoteFolder": defaultNewNoteFolder, "defaultEditor": defaultEditor.toInternalString(), "defaultView": defaultView.toInternalString(), "sortingMode": sortingMode.toInternalString(), "remoteSyncFrequency": remoteSyncFrequency.toInternalString(), "showNoteSummary": showNoteSummary, "folderViewHeaderType": folderViewHeaderType, "version": version, }; } Map toLoggableMap() { var m = toMap(); m.remove("gitAuthor"); m.remove("gitAuthorEmail"); m.remove("defaultNewNoteFolder"); return m; } } class NoteFileNameFormat { static const Iso8601WithTimeZone = NoteFileNameFormat("Iso8601WithTimeZone", "ISO8601 With TimeZone"); static const Iso8601 = NoteFileNameFormat("Iso8601", "Iso8601"); static const Iso8601WithTimeZoneWithoutColon = NoteFileNameFormat( "Iso8601WithTimeZoneWithoutColon", "ISO8601 without Colons"); static const FromTitle = NoteFileNameFormat("FromTitle", "Title"); static const SimpleDate = NoteFileNameFormat("SimpleDate", "yyyy-mm-dd-hh-mm-ss"); static const Default = FromTitle; static const options = [ SimpleDate, FromTitle, Iso8601, Iso8601WithTimeZone, Iso8601WithTimeZoneWithoutColon, ]; static NoteFileNameFormat fromInternalString(String str) { for (var opt in options) { if (opt.toInternalString() == str) { return opt; } } return Default; } static NoteFileNameFormat fromPublicString(String str) { for (var opt in options) { if (opt.toPublicString() == str) { return opt; } } return Default; } final String _str; final String _publicStr; const NoteFileNameFormat(this._str, this._publicStr); String toInternalString() { return _str; } String toPublicString() { return _publicStr; } @override String toString() { assert(false, "NoteFileNameFormat toString should never be called"); return ""; } } class RemoteSyncFrequency { static const Automatic = RemoteSyncFrequency("Automatic"); static const Manual = RemoteSyncFrequency("Manual"); static const Default = Automatic; final String _str; const RemoteSyncFrequency(this._str); String toInternalString() { return _str; } String toPublicString() { return _str; } static const options = [ Automatic, Manual, ]; static RemoteSyncFrequency fromInternalString(String str) { for (var opt in options) { if (opt.toInternalString() == str) { return opt; } } return Default; } static RemoteSyncFrequency fromPublicString(String str) { for (var opt in options) { if (opt.toPublicString() == str) { return opt; } } return Default; } @override String toString() { assert(false, "RemoteSyncFrequency toString should never be called"); return ""; } } class SettingsEditorType { static const Markdown = SettingsEditorType("Markdown", "Markdown"); static const Raw = SettingsEditorType("Raw", "Raw"); static const Default = Markdown; final String _str; final String _publicString; const SettingsEditorType(this._publicString, this._str); String toInternalString() { return _str; } String toPublicString() { return _publicString; } static const options = [ Markdown, Raw, ]; static SettingsEditorType fromInternalString(String str) { for (var opt in options) { if (opt.toInternalString() == str) { return opt; } } return Default; } static SettingsEditorType fromPublicString(String str) { for (var opt in options) { if (opt.toPublicString() == str) { return opt; } } return Default; } @override String toString() { assert(false, "EditorType toString should never be called"); return ""; } } class SettingsFolderViewType { static const Standard = SettingsFolderViewType("Standard", "Standard"); static const Journal = SettingsFolderViewType("Journal", "Journal"); static const Card = SettingsFolderViewType("Card", "Card"); static const Default = Standard; final String _str; final String _publicString; const SettingsFolderViewType(this._publicString, this._str); String toInternalString() { return _str; } String toPublicString() { return _publicString; } static const options = [ Standard, Journal, Card, ]; static SettingsFolderViewType fromInternalString(String str) { for (var opt in options) { if (opt.toInternalString() == str) { return opt; } } return Default; } static SettingsFolderViewType fromPublicString(String str) { for (var opt in options) { if (opt.toPublicString() == str) { return opt; } } return Default; } @override String toString() { assert(false, "FolderViewType toString should never be called"); return ""; } }