diff --git a/lib/app.dart b/lib/app.dart index bc240106..ac6869b4 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -46,10 +46,11 @@ class JournalApp extends StatefulWidget { var appState = AppState(pref); appState.dumpToLog(); - Log.i("Setting ${Settings.instance.toLoggableMap()}"); + var settings = Settings.instance; + Log.i("Setting ${settings.toLoggableMap()}"); - if (Settings.instance.collectUsageStatistics) { - _enableAnalyticsIfPossible(); + if (settings.collectUsageStatistics) { + _enableAnalyticsIfPossible(settings); } if (appState.gitBaseDirectory.isEmpty) { @@ -79,16 +80,19 @@ class JournalApp extends StatefulWidget { appState.save(pref); } - var app = ChangeNotifierProvider( - create: (_) { - return StateContainer(appState); - }, + var app = ChangeNotifierProvider.value( + value: settings, child: ChangeNotifierProvider( - child: JournalApp(appState), create: (_) { - assert(appState.notesFolder != null); - return appState.notesFolder; + return StateContainer(appState); }, + child: ChangeNotifierProvider( + child: JournalApp(appState), + create: (_) { + assert(appState.notesFolder != null); + return appState.notesFolder; + }, + ), ), ); @@ -105,7 +109,7 @@ class JournalApp extends StatefulWidget { )); } - static void _enableAnalyticsIfPossible() async { + static void _enableAnalyticsIfPossible(Settings settings) async { JournalApp.isInDebugMode = foundation.kDebugMode; var isPhysicalDevice = true; @@ -136,7 +140,7 @@ class JournalApp extends StatefulWidget { if (enabled) { JournalApp.analytics.logEvent( name: "settings", - parameters: Settings.instance.toLoggableMap(), + parameters: settings.toLoggableMap(), ); } } @@ -281,12 +285,13 @@ class _JournalAppState extends State { MaterialApp buildApp(BuildContext context, ThemeData themeData) { var stateContainer = Provider.of(context); + var settings = Provider.of(context); var initialRoute = '/'; if (!stateContainer.appState.onBoardingCompleted) { initialRoute = '/onBoarding'; } - if (Settings.instance.homeScreen == SettingsHomeScreen.AllFolders) { + if (settings.homeScreen == SettingsHomeScreen.AllFolders) { initialRoute = '/folders'; } diff --git a/lib/editors/markdown_editor.dart b/lib/editors/markdown_editor.dart index 21edcdd9..bfdf75f2 100644 --- a/lib/editors/markdown_editor.dart +++ b/lib/editors/markdown_editor.dart @@ -2,6 +2,8 @@ import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + import 'package:gitjournal/core/note.dart'; import 'package:gitjournal/editors/common.dart'; import 'package:gitjournal/editors/disposable_change_notifier.dart'; @@ -129,7 +131,8 @@ class MarkdownEditorState extends State Widget body = editingMode ? editor : NoteViewer(note: note); - if (Settings.instance.experimentalMarkdownToolbar && editingMode) { + var settings = Provider.of(context); + if (settings.experimentalMarkdownToolbar && editingMode) { body = Container( height: 600, child: Column( @@ -165,19 +168,19 @@ class MarkdownEditorState extends State } void _switchMode() { + var settings = Provider.of(context); + setState(() { editingMode = !editingMode; switch (editingMode) { case true: - Settings.instance.markdownLastUsedView = - SettingsMarkdownDefaultView.Edit; + settings.markdownLastUsedView = SettingsMarkdownDefaultView.Edit; break; case false: - Settings.instance.markdownLastUsedView = - SettingsMarkdownDefaultView.View; + settings.markdownLastUsedView = SettingsMarkdownDefaultView.View; break; } - Settings.instance.save(); + settings.save(); _updateNote(); }); } diff --git a/lib/editors/scaffold.dart b/lib/editors/scaffold.dart index bea2ec92..db4fdfd4 100644 --- a/lib/editors/scaffold.dart +++ b/lib/editors/scaffold.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + import 'package:gitjournal/core/notes_folder_fs.dart'; import 'package:gitjournal/editors/common.dart'; import 'package:gitjournal/settings.dart'; @@ -46,7 +48,9 @@ class _EditorScaffoldState extends State { } void _editorChanged() { - if (Settings.instance.zenMode && !hideUIElements) { + var settings = Provider.of(context); + + if (settings.zenMode && !hideUIElements) { setState(() { hideUIElements = true; }); @@ -55,11 +59,13 @@ class _EditorScaffoldState extends State { @override Widget build(BuildContext context) { + var settings = Provider.of(context); + return Scaffold( body: GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { - if (Settings.instance.zenMode) { + if (settings.zenMode) { setState(() { hideUIElements = false; }); @@ -84,13 +90,13 @@ class _EditorScaffoldState extends State { editorState: widget.editorState, parentFolder: widget.parentFolder, allowEdits: widget.allowEdits, - zenMode: Settings.instance.zenMode, + zenMode: settings.zenMode, onZenModeChanged: () { setState(() { - Settings.instance.zenMode = !Settings.instance.zenMode; - Settings.instance.save(); + settings.zenMode = !settings.zenMode; + settings.save(); - if (Settings.instance.zenMode) { + if (settings.zenMode) { hideUIElements = true; } }); diff --git a/lib/screens/debug_screen.dart b/lib/screens/debug_screen.dart index 50b0e20b..f636c861 100644 --- a/lib/screens/debug_screen.dart +++ b/lib/screens/debug_screen.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:provider/provider.dart'; import 'package:gitjournal/settings.dart'; import 'package:gitjournal/utils/logger.dart'; @@ -12,7 +13,6 @@ class DebugScreen extends StatefulWidget { class _DebugScreenState extends State { ScrollController _controller = ScrollController(); - String filterLevel = Settings.instance.debugLogLevel; List _logs; @@ -79,6 +79,9 @@ class _DebugScreenState extends State { } bool _shouldDisplay(LogMessage msg) { + var settings = Provider.of(context); + var filterLevel = settings.debugLogLevel; + if (filterLevel == null || filterLevel.isEmpty) { return true; } @@ -196,6 +199,9 @@ class _DebugScreenState extends State { } void _showFilterSelection() async { + var settings = Provider.of(context); + var filterLevel = settings.debugLogLevel; + var dialog = AlertDialog( title: Text(tr('settings.debug.levels')), content: Column( @@ -211,12 +217,8 @@ class _DebugScreenState extends State { ); var l = await showDialog(context: context, builder: (context) => dialog); if (l != null) { - setState(() { - Settings.instance.debugLogLevel = l; - Settings.instance.save(); - - filterLevel = l; - }); + settings.debugLogLevel = l; + settings.save(); } } } diff --git a/lib/screens/settings_editors.dart b/lib/screens/settings_editors.dart index c6766a41..9236ff90 100644 --- a/lib/screens/settings_editors.dart +++ b/lib/screens/settings_editors.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:provider/provider.dart'; import 'package:gitjournal/core/notes_folder_fs.dart'; import 'package:gitjournal/screens/settings_screen.dart'; @@ -18,9 +19,8 @@ class SettingsEditorsScreen extends StatefulWidget { class SettingsEditorsScreenState extends State { @override Widget build(BuildContext context) { - var settings = Settings.instance; - var defaultNewFolder = - Settings.instance.journalEditordefaultNewNoteFolderSpec; + var settings = Provider.of(context); + var defaultNewFolder = settings.journalEditordefaultNewNoteFolderSpec; if (defaultNewFolder.isEmpty) { defaultNewFolder = tr("rootFolder"); } else { @@ -28,8 +28,8 @@ class SettingsEditorsScreenState extends State { setState(() { defaultNewFolder = tr("rootFolder"); - Settings.instance.journalEditordefaultNewNoteFolderSpec = ""; - Settings.instance.save(); + settings.journalEditordefaultNewNoteFolderSpec = ""; + settings.save(); }); } } @@ -42,8 +42,8 @@ class SettingsEditorsScreenState extends State { SettingsEditorType.options.map((f) => f.toPublicString()).toList(), onChange: (String publicStr) { var val = SettingsEditorType.fromPublicString(publicStr); - Settings.instance.defaultEditor = val; - Settings.instance.save(); + settings.defaultEditor = val; + settings.save(); setState(() {}); }, ), @@ -56,8 +56,8 @@ class SettingsEditorsScreenState extends State { .toList(), onChange: (String publicStr) { var val = SettingsMarkdownDefaultView.fromPublicString(publicStr); - Settings.instance.markdownDefaultView = val; - Settings.instance.save(); + settings.markdownDefaultView = val; + settings.save(); setState(() {}); }, ), @@ -72,9 +72,9 @@ class SettingsEditorsScreenState extends State { builder: (context) => FolderSelectionDialog(), ); - Settings.instance.journalEditordefaultNewNoteFolderSpec = + settings.journalEditordefaultNewNoteFolderSpec = destFolder != null ? destFolder.pathSpec() : ""; - Settings.instance.save(); + settings.save(); setState(() {}); }, ), diff --git a/lib/screens/settings_git_remote.dart b/lib/screens/settings_git_remote.dart index f9fefb59..25290a75 100644 --- a/lib/screens/settings_git_remote.dart +++ b/lib/screens/settings_git_remote.dart @@ -39,7 +39,7 @@ class _GitRemoteSettingsScreenState extends State { @override Widget build(BuildContext context) { var textTheme = Theme.of(context).textTheme; - var settings = Settings.instance; + var settings = Provider.of(context); var body = Column( children: [ @@ -72,8 +72,8 @@ class _GitRemoteSettingsScreenState extends State { .toList(), onChange: (String publicStr) { var val = RemoteSyncFrequency.fromPublicString(publicStr); - Settings.instance.remoteSyncFrequency = val; - Settings.instance.save(); + settings.remoteSyncFrequency = val; + settings.save(); setState(() {}); }, ), diff --git a/lib/screens/settings_images.dart b/lib/screens/settings_images.dart index 44f484e5..d52e39e7 100644 --- a/lib/screens/settings_images.dart +++ b/lib/screens/settings_images.dart @@ -17,14 +17,14 @@ class SettingsImagesScreen extends StatefulWidget { class SettingsImagesScreenState extends State { @override Widget build(BuildContext context) { - var settings = Settings.instance; + var settings = Provider.of(context); var folder = Provider.of(context) .getFolderWithSpec(settings.imageLocationSpec); // If the Custom Folder specified no longer exists if (settings.imageLocationSpec != "." && folder == null) { - Settings.instance.imageLocationSpec = "."; - Settings.instance.save(); + settings.imageLocationSpec = "."; + settings.save(); } var sameFolder = tr("settings.images.currentFolder"); @@ -38,11 +38,11 @@ class SettingsImagesScreenState extends State { options: [sameFolder, customFolder], onChange: (String publicStr) { if (publicStr == sameFolder) { - Settings.instance.imageLocationSpec = "."; + settings.imageLocationSpec = "."; } else { - Settings.instance.imageLocationSpec = ""; + settings.imageLocationSpec = ""; } - Settings.instance.save(); + settings.save(); setState(() {}); }, ), @@ -56,9 +56,9 @@ class SettingsImagesScreenState extends State { builder: (context) => FolderSelectionDialog(), ); - Settings.instance.imageLocationSpec = + settings.imageLocationSpec = destFolder != null ? destFolder.pathSpec() : ""; - Settings.instance.save(); + settings.save(); setState(() {}); }, ), diff --git a/lib/screens/settings_note_metadata.dart b/lib/screens/settings_note_metadata.dart index 30f90d7b..5d3ea1f5 100644 --- a/lib/screens/settings_note_metadata.dart +++ b/lib/screens/settings_note_metadata.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:provider/provider.dart'; import 'package:gitjournal/core/md_yaml_doc.dart'; import 'package:gitjournal/core/md_yaml_doc_codec.dart'; @@ -23,6 +24,7 @@ class _NoteMetadataSettingsScreenState @override Widget build(BuildContext context) { var textTheme = Theme.of(context).textTheme; + var settings = Provider.of(context); var note = Note(null, "fileName.md"); note.title = tr("settings.noteMetaData.exampleTitle"); @@ -51,14 +53,14 @@ class _NoteMetadataSettingsScreenState const Divider(), SwitchListTile( title: Text(tr("settings.noteMetaData.enableHeader")), - value: Settings.instance.yamlHeaderEnabled, + value: settings.yamlHeaderEnabled, onChanged: (bool newVal) { setState(() { - Settings.instance.yamlHeaderEnabled = newVal; + settings.yamlHeaderEnabled = newVal; if (newVal == false) { - Settings.instance.saveTitleInH1 = true; + settings.saveTitleInH1 = true; } - Settings.instance.save(); + settings.save(); }); }, ), @@ -71,14 +73,14 @@ class _NoteMetadataSettingsScreenState "lastmodified", "lastmod", ], - currentOption: Settings.instance.yamlModifiedKey, + currentOption: settings.yamlModifiedKey, onChange: (String newVal) { setState(() { - Settings.instance.yamlModifiedKey = newVal; - Settings.instance.save(); + settings.yamlModifiedKey = newVal; + settings.save(); }); }, - enabled: Settings.instance.yamlHeaderEnabled, + enabled: settings.yamlHeaderEnabled, ), ), ProOverlay( @@ -88,14 +90,14 @@ class _NoteMetadataSettingsScreenState "created", "date", ], - currentOption: Settings.instance.yamlCreatedKey, + currentOption: settings.yamlCreatedKey, onChange: (String newVal) { setState(() { - Settings.instance.yamlCreatedKey = newVal; - Settings.instance.save(); + settings.yamlCreatedKey = newVal; + settings.save(); }); }, - enabled: Settings.instance.yamlHeaderEnabled, + enabled: settings.yamlHeaderEnabled, ), ), ProOverlay( @@ -105,14 +107,14 @@ class _NoteMetadataSettingsScreenState "tags", "categories", ], - currentOption: Settings.instance.yamlTagsKey, + currentOption: settings.yamlTagsKey, onChange: (String newVal) { setState(() { - Settings.instance.yamlTagsKey = newVal; - Settings.instance.save(); + settings.yamlTagsKey = newVal; + settings.save(); }); }, - enabled: Settings.instance.yamlHeaderEnabled, + enabled: settings.yamlHeaderEnabled, ), ), ProOverlay( @@ -120,17 +122,17 @@ class _NoteMetadataSettingsScreenState title: tr("settings.noteMetaData.titleMetaData.title"), options: [ tr("settings.noteMetaData.titleMetaData.fromH1"), - if (Settings.instance.yamlHeaderEnabled) + if (settings.yamlHeaderEnabled) tr("settings.noteMetaData.titleMetaData.fromYaml"), ], - currentOption: Settings.instance.saveTitleInH1 + currentOption: settings.saveTitleInH1 ? tr("settings.noteMetaData.titleMetaData.fromH1") : tr("settings.noteMetaData.titleMetaData.fromYaml"), onChange: (String newVal) { setState(() { - Settings.instance.saveTitleInH1 = + settings.saveTitleInH1 = newVal == tr("settings.noteMetaData.titleMetaData.fromH1"); - Settings.instance.save(); + settings.save(); }); }, ), diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index e79699a9..6b913f2e 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -54,11 +54,11 @@ class SettingsListState extends State { var stateContainer = Provider.of(context, listen: false); var remoteGitConfigured = stateContainer.appState.remoteGitRepoConfigured; - var settings = Settings.instance; + var settings = Provider.of(context); var saveGitAuthor = (String gitAuthor) { - Settings.instance.gitAuthor = gitAuthor; - Settings.instance.save(); + settings.gitAuthor = gitAuthor; + settings.save(); }; var gitAuthorForm = Form( @@ -80,7 +80,7 @@ class SettingsListState extends State { textInputAction: TextInputAction.done, onFieldSubmitted: saveGitAuthor, onSaved: saveGitAuthor, - initialValue: Settings.instance.gitAuthor, + initialValue: settings.gitAuthor, ), onChanged: () { if (!gitAuthorKey.currentState.validate()) return; @@ -90,8 +90,8 @@ class SettingsListState extends State { ); var saveGitAuthorEmail = (String gitAuthorEmail) { - Settings.instance.gitAuthorEmail = gitAuthorEmail; - Settings.instance.save(); + settings.gitAuthorEmail = gitAuthorEmail; + settings.save(); }; var gitAuthorEmailForm = Form( child: TextFormField( @@ -121,7 +121,7 @@ class SettingsListState extends State { textInputAction: TextInputAction.done, onFieldSubmitted: saveGitAuthorEmail, onSaved: saveGitAuthorEmail, - initialValue: Settings.instance.gitAuthorEmail, + initialValue: settings.gitAuthorEmail, ), onChanged: () { if (!gitAuthorEmailKey.currentState.validate()) return; @@ -131,7 +131,7 @@ class SettingsListState extends State { ); var brightness = DynamicTheme.of(context).brightness; - var defaultNewFolder = Settings.instance.defaultNewNoteFolderSpec; + var defaultNewFolder = settings.defaultNewNoteFolderSpec; if (defaultNewFolder.isEmpty) { defaultNewFolder = tr("rootFolder"); } else { @@ -139,8 +139,8 @@ class SettingsListState extends State { setState(() { defaultNewFolder = tr("rootFolder"); - Settings.instance.defaultNewNoteFolderSpec = ""; - Settings.instance.save(); + settings.defaultNewNoteFolderSpec = ""; + settings.save(); }); } } @@ -165,8 +165,8 @@ class SettingsListState extends State { .toList(), onChange: (String publicStr) { var s = SettingsHomeScreen.fromPublicString(publicStr); - Settings.instance.homeScreen = s; - Settings.instance.save(); + settings.homeScreen = s; + settings.save(); setState(() {}); }, ), @@ -181,8 +181,8 @@ class SettingsListState extends State { builder: (context) => FolderSelectionDialog(), ); if (destFolder != null) { - Settings.instance.defaultNewNoteFolderSpec = destFolder.pathSpec(); - Settings.instance.save(); + settings.defaultNewNoteFolderSpec = destFolder.pathSpec(); + settings.save(); setState(() {}); } }, @@ -222,8 +222,8 @@ class SettingsListState extends State { NoteFileNameFormat.options.map((f) => f.toPublicString()).toList(), onChange: (String publicStr) { var format = NoteFileNameFormat.fromPublicString(publicStr); - Settings.instance.noteFileNameFormat = format; - Settings.instance.save(); + settings.noteFileNameFormat = format; + settings.save(); setState(() {}); }, ), @@ -253,19 +253,19 @@ class SettingsListState extends State { SettingsHeader(tr('settings.analytics')), SwitchListTile( title: Text(tr('settings.usageStats')), - value: Settings.instance.collectUsageStatistics, + value: settings.collectUsageStatistics, onChanged: (bool val) { - Settings.instance.collectUsageStatistics = val; - Settings.instance.save(); + settings.collectUsageStatistics = val; + settings.save(); setState(() {}); }, ), SwitchListTile( title: Text(tr('settings.crashReports')), - value: Settings.instance.collectCrashReports, + value: settings.collectCrashReports, onChanged: (bool val) { - Settings.instance.collectCrashReports = val; - Settings.instance.save(); + settings.collectCrashReports = val; + settings.save(); setState(() {}); }, ), diff --git a/lib/settings.dart b/lib/settings.dart index 3ca45a4e..1d91f18a 100644 --- a/lib/settings.dart +++ b/lib/settings.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:shared_preferences/shared_preferences.dart'; import 'package:uuid/uuid.dart'; @@ -5,7 +7,7 @@ import 'package:gitjournal/core/sorting_mode.dart'; import 'package:gitjournal/folder_views/common.dart'; import 'package:gitjournal/screens/note_editor.dart'; -class Settings { +class Settings extends ChangeNotifier { // singleton static final Settings _singleton = Settings._internal(); factory Settings() => _singleton; @@ -203,6 +205,8 @@ class Settings { _setBool(pref, "saveTitleInH1", saveTitleInH1, defaultSet.saveTitleInH1); pref.setInt("settingsVersion", version); + + notifyListeners(); } Future _setString( diff --git a/lib/setup/screens.dart b/lib/setup/screens.dart index f317ba06..1ef80cd9 100644 --- a/lib/setup/screens.dart +++ b/lib/setup/screens.dart @@ -514,10 +514,12 @@ class GitHostSetupScreenState extends State { folderPath: repoPath, ); await repo.add('.gitignore'); + + var settings = Provider.of(context, listen: false); await repo.commit( message: "Add gitignore file", - authorEmail: Settings.instance.gitAuthorEmail, - authorName: Settings.instance.gitAuthor, + authorEmail: settings.gitAuthorEmail, + authorName: settings.gitAuthor, ); } diff --git a/lib/widgets/app_drawer.dart b/lib/widgets/app_drawer.dart index 59260539..d5ac866b 100644 --- a/lib/widgets/app_drawer.dart +++ b/lib/widgets/app_drawer.dart @@ -43,6 +43,7 @@ class AppDrawer extends StatelessWidget { } var divider = Row(children: [const Expanded(child: Divider())]); + var settings = Provider.of(context); return Drawer( child: ListView( @@ -51,7 +52,7 @@ class AppDrawer extends StatelessWidget { children: [ _AppDrawerHeader(), if (setupGitButton != null) ...[setupGitButton, divider], - if (!Settings.instance.proMode) + if (!settings.proMode) _buildDrawerTile( context, icon: Icons.power, @@ -65,7 +66,7 @@ class AppDrawer extends StatelessWidget { ); }, ), - if (!Settings.instance.proMode) divider, + if (!settings.proMode) divider, _buildDrawerTile( context, icon: Icons.note, @@ -80,7 +81,7 @@ class AppDrawer extends StatelessWidget { onTap: () => _navTopLevel(context, '/folders'), selected: currentRoute == "/folders", ), - if (Settings.instance.experimentalFs) + if (settings.experimentalFs) _buildDrawerTile( context, icon: FontAwesomeIcons.solidFolderOpen, diff --git a/lib/widgets/pro_overlay.dart b/lib/widgets/pro_overlay.dart index f15c9567..5ba32927 100644 --- a/lib/widgets/pro_overlay.dart +++ b/lib/widgets/pro_overlay.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:provider/provider.dart'; import 'package:gitjournal/settings.dart'; @@ -11,9 +12,11 @@ class ProOverlay extends StatelessWidget { @override Widget build(BuildContext context) { - if (Settings.instance.proMode) { + var settings = Provider.of(context); + if (settings.proMode) { return child; } + return GestureDetector( behavior: HitTestBehavior.opaque, child: Banner( diff --git a/lib/widgets/purchase_widget.dart b/lib/widgets/purchase_widget.dart index d640345b..d56765b5 100644 --- a/lib/widgets/purchase_widget.dart +++ b/lib/widgets/purchase_widget.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:in_app_purchase/in_app_purchase.dart'; +import 'package:provider/provider.dart'; import 'package:gitjournal/analytics.dart'; import 'package:gitjournal/iap.dart'; @@ -171,9 +172,10 @@ class _PurchaseWidgetState extends State { } void _deliverProduct(SubscriptionStatus status) { - Settings.instance.proMode = status.isPro; - Settings.instance.proExpirationDate = status.expiryDate.toIso8601String(); - Settings.instance.save(); + var settings = Provider.of(context); + settings.proMode = status.isPro; + settings.proExpirationDate = status.expiryDate.toIso8601String(); + settings.save(); getAnalytics().logEvent( name: "purchase_screen_thank_you",