feat: v3.5.0 - SAF storage, onboarding redesign, library scan fixes

- SAF Storage Access Framework for Android 10+ downloads
- Redesigned Setup/Tutorial screens with Material 3 Expressive
- Library scan hero card now shows real-time scanned count
- Library folder picker uses SAF (no MANAGE_EXTERNAL_STORAGE needed)
- SAF migration prompt for users updating from pre-SAF versions
- Home feed caching, donate page, per-app language support
- Merged 3.6.0-beta.1 changelog entries into 3.5.0
This commit is contained in:
zarzet committed 2026-02-07 11:48:37 +07:00
1 parent c0a9cb756f
commit ad606cca53
36 files changed
+4948 -719

No files matched your search

+9
View File
@@ -43,6 +43,9 @@ class AppSettings {
final bool localLibraryEnabled; // Enable local library scanning
final String localLibraryPath; // Path to scan for audio files
final bool localLibraryShowDuplicates; // Show indicator when searching for existing tracks
// Tutorial/Onboarding
final bool hasCompletedTutorial; // Track if user has completed the app tutorial
const AppSettings({
this.defaultService = 'tidal',
@@ -83,6 +86,8 @@ class AppSettings {
this.localLibraryEnabled = false,
this.localLibraryPath = '',
this.localLibraryShowDuplicates = true,
// Tutorial default
this.hasCompletedTutorial = false,
});
AppSettings copyWith({
@@ -125,6 +130,8 @@ class AppSettings {
bool? localLibraryEnabled,
String? localLibraryPath,
bool? localLibraryShowDuplicates,
// Tutorial
bool? hasCompletedTutorial,
}) {
return AppSettings(
defaultService: defaultService ?? this.defaultService,
@@ -165,6 +172,8 @@ class AppSettings {
localLibraryEnabled: localLibraryEnabled ?? this.localLibraryEnabled,
localLibraryPath: localLibraryPath ?? this.localLibraryPath,
localLibraryShowDuplicates: localLibraryShowDuplicates ?? this.localLibraryShowDuplicates,
// Tutorial
hasCompletedTutorial: hasCompletedTutorial ?? this.hasCompletedTutorial,
);
}
+2
View File
@@ -48,6 +48,7 @@ AppSettings _$AppSettingsFromJson(Map<String, dynamic> json) => AppSettings(
localLibraryPath: json['localLibraryPath'] as String? ?? '',
localLibraryShowDuplicates:
json['localLibraryShowDuplicates'] as bool? ?? true,
hasCompletedTutorial: json['hasCompletedTutorial'] as bool? ?? false,
);
Map<String, dynamic> _$AppSettingsToJson(AppSettings instance) =>
@@ -89,4 +90,5 @@ Map<String, dynamic> _$AppSettingsToJson(AppSettings instance) =>
'localLibraryEnabled': instance.localLibraryEnabled,
'localLibraryPath': instance.localLibraryPath,
'localLibraryShowDuplicates': instance.localLibraryShowDuplicates,
'hasCompletedTutorial': instance.hasCompletedTutorial,
};