diff --git a/lib/main.dart b/lib/main.dart index a03edb7..462eee8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,7 +6,7 @@ import 'package:daily_diary/storage.dart'; import 'package:daily_diary/themes.dart'; import 'package:daily_diary/screens/home.dart'; -import 'package:shared_storage/saf.dart'; +import 'package:shared_preferences/shared_preferences.dart'; // This will be removed when widgets can react to spell check changes bool? startupCheckSpelling; @@ -31,7 +31,8 @@ main() async { class App extends StatelessWidget { const App({Key? key}) : super(key: key); - static final SettingsNotifier settingsNotifier = SettingsNotifier(savePath!); + static final settingsNotifier = SettingsNotifier(savePath!); + static final preferences = SharedPreferences.getInstance(); @override Widget build(BuildContext context) { diff --git a/lib/path.dart b/lib/path.dart index 799651d..14b89ad 100644 --- a/lib/path.dart +++ b/lib/path.dart @@ -2,8 +2,9 @@ import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:daily_diary/main.dart'; + import 'package:path_provider/path_provider.dart'; -import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_storage/saf.dart'; class SavePath { @@ -53,7 +54,7 @@ class SavePath { Future getPath() async { WidgetsFlutterBinding.ensureInitialized(); - final preferences = await SharedPreferences.getInstance(); + final preferences = await App.preferences; String? path = preferences.getString('save_path'); bool? isAndroidScoped = preferences.getBool('is_android_scoped'); if (path != null) { @@ -63,14 +64,26 @@ Future getPath() async { } return SavePath.normal(path); } else { - String path = await defaultPath; - preferences.setString('save_path', path); - preferences.setBool('is_android_scoped', false); - return SavePath.normal(path); + return resetPathToDefault(); } } -Future get defaultPath async { +/// Resets the savePath to default in `SharedPreferences` and returns the +/// `SavePath` it was set to. It does NOT set the global `savePath`. +/// +/// To set `savePath` do: +/// ``` +/// savePath = await resetPathToDefault(); +/// ``` +Future resetPathToDefault() async { + final preferences = await App.preferences; + String path = await _defaultPath; + preferences.setString('save_path', path); + preferences.setBool('is_android_scoped', false); + return SavePath.normal(path); +} + +Future get _defaultPath async { final directory = await _directory; return directory.path; } diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 6fc30c1..0133425 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -2,14 +2,13 @@ import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:daily_diary/main.dart'; +import 'package:daily_diary/path.dart'; + import 'package:file_picker/file_picker.dart'; import 'package:flutter_colorpicker/flutter_colorpicker.dart'; -import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_storage/shared_storage.dart' as saf; -import 'package:daily_diary/main.dart'; -import 'package:daily_diary/path.dart'; - class SettingsScreen extends StatelessWidget { const SettingsScreen({super.key}); @@ -340,17 +339,10 @@ class SavePathSetting extends StatefulWidget implements SettingTile { @override Future newDefault() async { - await resetSavePath(); + savePath = await resetPathToDefault(); return const SavePathSetting(); } - Future resetSavePath() async { - savePath = SavePath.normal(await defaultPath); - final preferences = await SharedPreferences.getInstance(); - preferences.setString('save_path', await defaultPath); - preferences.setBool('is_android_scoped', false); - } - @override State createState() => _SavePathSettingState(); } @@ -372,27 +364,19 @@ class _SavePathSettingState extends State { if (Platform.isAndroid) { return _askForPathAndroid(); } - // Load SharedPreferences while user is picking a path - final preferencesFuture = SharedPreferences.getInstance(); String? path = await FilePicker.platform.getDirectoryPath(); if (path == null) { return null; } - final preferences = await preferencesFuture; + final preferences = await App.preferences; preferences.setString('save_path', path); preferences.setBool('is_android_scoped', false); return SavePath.normal(path); } Future _askForPathAndroid() async { - // Load SharedPreferences while user is picking a path - final preferencesFuture = SharedPreferences.getInstance(); - // Remove previous permissions - if (savePath != null && savePath!.uri != null) { - final previousPath = savePath!.uri!; - saf.releasePersistableUriPermission(previousPath); - } + _removePreviousPermissions(); // Ask user for path and permissions Uri? uri; @@ -404,12 +388,22 @@ class _SavePathSettingState extends State { final asDocumentFile = await uri.toDocumentFile(); Map asMap = asDocumentFile!.toMap(); String asString = json.encode(asMap); - final preferences = await preferencesFuture; + final preferences = await App.preferences; preferences.setString('save_path', asString); preferences.setBool('is_android_scoped', true); return SavePath.android(uri); } + Future _removePreviousPermissions() async { + SavePath? path = savePath; + if (path == null) return; + + Uri? previousPath = path.uri; + if (previousPath == null) return; + + await saf.releasePersistableUriPermission(previousPath); + } + @override Widget build(BuildContext context) { return Column(