mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-20 14:37:33 +02:00
refactor(setup): move SharedPreferences access behind SetupProgressStore and SafMigrationPromptStore
The setup draft and the SAF migration prompt flag were read and written directly from screens. Keys, JSON shape and defaults are unchanged.
This commit is contained in:
1 parent
8af7efb6ce
commit
7628800604
5 files changed
+53
-14
No files matched your search
@@ -11,6 +11,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:spotiflac_android/l10n/l10n.dart';
|
||||
import 'package:spotiflac_android/constants/app_info.dart';
|
||||
import 'package:spotiflac_android/screens/upgrade_intro_screen.dart';
|
||||
import 'package:spotiflac_android/services/saf_migration_prompt_store.dart';
|
||||
import 'package:spotiflac_android/services/upgrade_intro_service.dart';
|
||||
import 'package:spotiflac_android/providers/download_queue_provider.dart';
|
||||
import 'package:spotiflac_android/providers/music_player_provider.dart';
|
||||
|
||||
@@ -168,7 +168,7 @@ extension _MainShellStartupPrompts on _MainShellState {
|
||||
);
|
||||
}
|
||||
|
||||
static const _safMigrationShownKey = 'saf_migration_prompt_shown';
|
||||
static const _safMigrationPromptStore = SafMigrationPromptStore();
|
||||
|
||||
Future<void> _checkSafMigration() async {
|
||||
if (!Platform.isAndroid) return;
|
||||
@@ -181,9 +181,8 @@ extension _MainShellStartupPrompts on _MainShellState {
|
||||
final androidInfo = await deviceInfo.androidInfo;
|
||||
if (androidInfo.version.sdkInt < 29) return;
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
if (prefs.getBool(_safMigrationShownKey) == true) return;
|
||||
await prefs.setBool(_safMigrationShownKey, true);
|
||||
if (await _safMigrationPromptStore.wasShown()) return;
|
||||
await _safMigrationPromptStore.markShown();
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:spotiflac_android/services/setup_progress_store.dart';
|
||||
import 'package:spotiflac_android/providers/settings_provider.dart';
|
||||
import 'package:spotiflac_android/l10n/l10n.dart';
|
||||
import 'package:spotiflac_android/constants/language_choices.dart';
|
||||
@@ -46,8 +46,7 @@ class SetupScreen extends ConsumerStatefulWidget {
|
||||
|
||||
class _SetupScreenState extends ConsumerState<SetupScreen>
|
||||
with WidgetsBindingObserver {
|
||||
static const _progressKey = 'setup_progress_v1';
|
||||
final _prefs = SharedPreferences.getInstance();
|
||||
final _progressStore = SetupProgressStore();
|
||||
final _platform = defaultTargetPlatform;
|
||||
PageController? _pageController;
|
||||
final ScrollController _languageScrollController = ScrollController();
|
||||
@@ -98,10 +97,9 @@ class _SetupScreenState extends ConsumerState<SetupScreen>
|
||||
final androidInfo = await DeviceInfoPlugin().androidInfo;
|
||||
_androidSdkVersion = androidInfo.version.sdkInt;
|
||||
}
|
||||
final prefs = await _prefs;
|
||||
final saved = await _progressStore.readDraft();
|
||||
if (!mounted) return;
|
||||
_selectedLocale = ref.read(settingsProvider).locale;
|
||||
final saved = prefs.getString(_progressKey);
|
||||
if (saved != null) {
|
||||
final draft = jsonDecode(saved) as Map<String, dynamic>;
|
||||
_currentStep = ((draft['step'] as int?) ?? 0).clamp(0, _totalSteps - 1);
|
||||
@@ -141,16 +139,13 @@ class _SetupScreenState extends ConsumerState<SetupScreen>
|
||||
}
|
||||
|
||||
Future<void> _saveProgress({int? step}) async {
|
||||
final draft = jsonEncode({
|
||||
await _progressStore.writeDraft({
|
||||
'step': step ?? _currentStep,
|
||||
'directory': _selectedDirectory,
|
||||
'bookmark': _selectedDirectoryBookmark,
|
||||
'treeUri': _selectedTreeUri,
|
||||
'skipNotifications': _notificationPermissionSkipped,
|
||||
});
|
||||
if (!await (await _prefs).setString(_progressKey, draft)) {
|
||||
throw StateError('Could not save setup progress');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _restoreSelectedFolder() => _folderRecovery ??=
|
||||
@@ -607,7 +602,7 @@ class _SetupScreenState extends ConsumerState<SetupScreen>
|
||||
}
|
||||
|
||||
await ref.read(settingsProvider.notifier).setFirstLaunchComplete();
|
||||
await (await _prefs).remove(_progressKey);
|
||||
await _progressStore.clear();
|
||||
|
||||
if (mounted) context.go('/tutorial');
|
||||
} catch (e) {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
/// Remembers that the one-time SAF migration prompt was already shown.
|
||||
class SafMigrationPromptStore {
|
||||
const SafMigrationPromptStore();
|
||||
|
||||
static const _shownKey = 'saf_migration_prompt_shown';
|
||||
|
||||
Future<bool> wasShown() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getBool(_shownKey) == true;
|
||||
}
|
||||
|
||||
Future<void> markShown() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setBool(_shownKey, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
/// Persists the first-run setup draft so an interrupted setup can resume.
|
||||
class SetupProgressStore {
|
||||
SetupProgressStore() : _prefs = SharedPreferences.getInstance();
|
||||
|
||||
static const _progressKey = 'setup_progress_v1';
|
||||
|
||||
final Future<SharedPreferences> _prefs;
|
||||
|
||||
/// The stored draft as raw JSON text, or null when none was saved.
|
||||
Future<String?> readDraft() async => (await _prefs).getString(_progressKey);
|
||||
|
||||
Future<void> writeDraft(Map<String, Object?> draft) async {
|
||||
final encoded = jsonEncode(draft);
|
||||
if (!await (await _prefs).setString(_progressKey, encoded)) {
|
||||
throw StateError('Could not save setup progress');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> clear() async {
|
||||
await (await _prefs).remove(_progressKey);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user