mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-04-01 09:30:34 +02:00
- Add 'Use Primary Artist Only' setting to strip featured artists from folder names - Fix flutter_local_notifications v20 breaking changes (positional params) - Fix SAF duplicate folder bug: synchronized ensureDocumentDir to prevent race condition creating empty folders with (1), (2) suffixes during concurrent downloads
194 lines
7.6 KiB
Dart
194 lines
7.6 KiB
Dart
import 'package:json_annotation/json_annotation.dart';
|
|
|
|
part 'settings.g.dart';
|
|
|
|
@JsonSerializable()
|
|
class AppSettings {
|
|
final String defaultService;
|
|
final String audioQuality;
|
|
final String filenameFormat;
|
|
final String downloadDirectory;
|
|
final String storageMode; // 'app' or 'saf'
|
|
final String downloadTreeUri; // SAF persistable tree URI
|
|
final bool autoFallback;
|
|
final bool embedLyrics;
|
|
final bool maxQualityCover;
|
|
final bool isFirstLaunch;
|
|
final int concurrentDownloads;
|
|
final bool checkForUpdates;
|
|
final String updateChannel;
|
|
final bool hasSearchedBefore;
|
|
final String folderOrganization;
|
|
final bool useAlbumArtistForFolders;
|
|
final bool usePrimaryArtistOnly; // Strip featured artists from folder name
|
|
final String historyViewMode;
|
|
final String historyFilterMode;
|
|
final bool askQualityBeforeDownload;
|
|
final String spotifyClientId;
|
|
final String spotifyClientSecret;
|
|
final bool useCustomSpotifyCredentials;
|
|
final String metadataSource;
|
|
final bool enableLogging;
|
|
final bool useExtensionProviders;
|
|
final String? searchProvider;
|
|
final bool separateSingles;
|
|
final String albumFolderStructure;
|
|
final bool showExtensionStore;
|
|
final String locale;
|
|
final String lyricsMode;
|
|
final String tidalHighFormat; // Format for Tidal HIGH quality: 'mp3_320', 'opus_256', or 'opus_128'
|
|
final bool useAllFilesAccess; // Android 13+ only: enable MANAGE_EXTERNAL_STORAGE
|
|
final bool autoExportFailedDownloads; // Auto export failed downloads to TXT file
|
|
final String downloadNetworkMode; // 'any' = WiFi + Mobile, 'wifi_only' = WiFi only
|
|
|
|
// Local Library Settings
|
|
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',
|
|
this.audioQuality = 'LOSSLESS',
|
|
this.filenameFormat = '{title} - {artist}',
|
|
this.downloadDirectory = '',
|
|
this.storageMode = 'app',
|
|
this.downloadTreeUri = '',
|
|
this.autoFallback = true,
|
|
this.embedLyrics = true,
|
|
this.maxQualityCover = true,
|
|
this.isFirstLaunch = true,
|
|
this.concurrentDownloads = 1,
|
|
this.checkForUpdates = true,
|
|
this.updateChannel = 'stable',
|
|
this.hasSearchedBefore = false,
|
|
this.folderOrganization = 'none',
|
|
this.useAlbumArtistForFolders = true,
|
|
this.usePrimaryArtistOnly = false,
|
|
this.historyViewMode = 'grid',
|
|
this.historyFilterMode = 'all',
|
|
this.askQualityBeforeDownload = true,
|
|
this.spotifyClientId = '',
|
|
this.spotifyClientSecret = '',
|
|
this.useCustomSpotifyCredentials = true,
|
|
this.metadataSource = 'deezer',
|
|
this.enableLogging = false,
|
|
this.useExtensionProviders = true,
|
|
this.searchProvider,
|
|
this.separateSingles = false,
|
|
this.albumFolderStructure = 'artist_album',
|
|
this.showExtensionStore = true,
|
|
this.locale = 'system',
|
|
this.lyricsMode = 'embed',
|
|
this.tidalHighFormat = 'mp3_320',
|
|
this.useAllFilesAccess = false,
|
|
this.autoExportFailedDownloads = false,
|
|
this.downloadNetworkMode = 'any',
|
|
// Local Library defaults
|
|
this.localLibraryEnabled = false,
|
|
this.localLibraryPath = '',
|
|
this.localLibraryShowDuplicates = true,
|
|
// Tutorial default
|
|
this.hasCompletedTutorial = false,
|
|
});
|
|
|
|
AppSettings copyWith({
|
|
String? defaultService,
|
|
String? audioQuality,
|
|
String? filenameFormat,
|
|
String? downloadDirectory,
|
|
String? storageMode,
|
|
String? downloadTreeUri,
|
|
bool? autoFallback,
|
|
bool? embedLyrics,
|
|
bool? maxQualityCover,
|
|
bool? isFirstLaunch,
|
|
int? concurrentDownloads,
|
|
bool? checkForUpdates,
|
|
String? updateChannel,
|
|
bool? hasSearchedBefore,
|
|
String? folderOrganization,
|
|
bool? useAlbumArtistForFolders,
|
|
bool? usePrimaryArtistOnly,
|
|
String? historyViewMode,
|
|
String? historyFilterMode,
|
|
bool? askQualityBeforeDownload,
|
|
String? spotifyClientId,
|
|
String? spotifyClientSecret,
|
|
bool? useCustomSpotifyCredentials,
|
|
String? metadataSource,
|
|
bool? enableLogging,
|
|
bool? useExtensionProviders,
|
|
String? searchProvider,
|
|
bool clearSearchProvider = false,
|
|
bool? separateSingles,
|
|
String? albumFolderStructure,
|
|
bool? showExtensionStore,
|
|
String? locale,
|
|
String? lyricsMode,
|
|
String? tidalHighFormat,
|
|
bool? useAllFilesAccess,
|
|
bool? autoExportFailedDownloads,
|
|
String? downloadNetworkMode,
|
|
// Local Library
|
|
bool? localLibraryEnabled,
|
|
String? localLibraryPath,
|
|
bool? localLibraryShowDuplicates,
|
|
// Tutorial
|
|
bool? hasCompletedTutorial,
|
|
}) {
|
|
return AppSettings(
|
|
defaultService: defaultService ?? this.defaultService,
|
|
audioQuality: audioQuality ?? this.audioQuality,
|
|
filenameFormat: filenameFormat ?? this.filenameFormat,
|
|
downloadDirectory: downloadDirectory ?? this.downloadDirectory,
|
|
storageMode: storageMode ?? this.storageMode,
|
|
downloadTreeUri: downloadTreeUri ?? this.downloadTreeUri,
|
|
autoFallback: autoFallback ?? this.autoFallback,
|
|
embedLyrics: embedLyrics ?? this.embedLyrics,
|
|
maxQualityCover: maxQualityCover ?? this.maxQualityCover,
|
|
isFirstLaunch: isFirstLaunch ?? this.isFirstLaunch,
|
|
concurrentDownloads: concurrentDownloads ?? this.concurrentDownloads,
|
|
checkForUpdates: checkForUpdates ?? this.checkForUpdates,
|
|
updateChannel: updateChannel ?? this.updateChannel,
|
|
hasSearchedBefore: hasSearchedBefore ?? this.hasSearchedBefore,
|
|
folderOrganization: folderOrganization ?? this.folderOrganization,
|
|
useAlbumArtistForFolders:
|
|
useAlbumArtistForFolders ?? this.useAlbumArtistForFolders,
|
|
usePrimaryArtistOnly:
|
|
usePrimaryArtistOnly ?? this.usePrimaryArtistOnly,
|
|
historyViewMode: historyViewMode ?? this.historyViewMode,
|
|
historyFilterMode: historyFilterMode ?? this.historyFilterMode,
|
|
askQualityBeforeDownload: askQualityBeforeDownload ?? this.askQualityBeforeDownload,
|
|
spotifyClientId: spotifyClientId ?? this.spotifyClientId,
|
|
spotifyClientSecret: spotifyClientSecret ?? this.spotifyClientSecret,
|
|
useCustomSpotifyCredentials: useCustomSpotifyCredentials ?? this.useCustomSpotifyCredentials,
|
|
metadataSource: metadataSource ?? this.metadataSource,
|
|
enableLogging: enableLogging ?? this.enableLogging,
|
|
useExtensionProviders: useExtensionProviders ?? this.useExtensionProviders,
|
|
searchProvider: clearSearchProvider ? null : (searchProvider ?? this.searchProvider),
|
|
separateSingles: separateSingles ?? this.separateSingles,
|
|
albumFolderStructure: albumFolderStructure ?? this.albumFolderStructure,
|
|
showExtensionStore: showExtensionStore ?? this.showExtensionStore,
|
|
locale: locale ?? this.locale,
|
|
lyricsMode: lyricsMode ?? this.lyricsMode,
|
|
tidalHighFormat: tidalHighFormat ?? this.tidalHighFormat,
|
|
useAllFilesAccess: useAllFilesAccess ?? this.useAllFilesAccess,
|
|
autoExportFailedDownloads: autoExportFailedDownloads ?? this.autoExportFailedDownloads,
|
|
downloadNetworkMode: downloadNetworkMode ?? this.downloadNetworkMode,
|
|
// Local Library
|
|
localLibraryEnabled: localLibraryEnabled ?? this.localLibraryEnabled,
|
|
localLibraryPath: localLibraryPath ?? this.localLibraryPath,
|
|
localLibraryShowDuplicates: localLibraryShowDuplicates ?? this.localLibraryShowDuplicates,
|
|
// Tutorial
|
|
hasCompletedTutorial: hasCompletedTutorial ?? this.hasCompletedTutorial,
|
|
);
|
|
}
|
|
|
|
factory AppSettings.fromJson(Map<String, dynamic> json) =>
|
|
_$AppSettingsFromJson(json);
|
|
Map<String, dynamic> toJson() => _$AppSettingsToJson(this);
|
|
}
|