mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-08-15 23:50:38 +02:00
feat: add local library scanning with duplicate detection
- Add Go backend library scanner for FLAC, M4A, MP3, Opus, OGG files - Read metadata from file tags (ISRC, track name, artist, album, bit depth, sample rate) - Fallback to filename parsing when tags unavailable - Add SQLite database for O(1) duplicate lookups - Show 'In Library' badge on search results for existing tracks - Match by ISRC (exact) or track name + artist (fuzzy) - Add Library Settings page with scan, cleanup, and clear actions - Add 30+ localization strings for library feature
This commit is contained in:
@@ -42,8 +42,13 @@ class AppSettings {
|
||||
final String cloudProvider; // 'none', 'webdav', 'sftp', 'gdrive'
|
||||
final String cloudServerUrl; // WebDAV/SFTP server URL
|
||||
final String cloudUsername; // Server username
|
||||
final String cloudPassword; // Server password (encrypted)
|
||||
final String cloudPassword; // Server password (stored securely)
|
||||
final String cloudRemotePath; // Remote folder path (e.g. /Music/SpotiFLAC)
|
||||
|
||||
// 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
|
||||
|
||||
const AppSettings({
|
||||
this.defaultService = 'tidal',
|
||||
@@ -85,6 +90,10 @@ class AppSettings {
|
||||
this.cloudUsername = '',
|
||||
this.cloudPassword = '',
|
||||
this.cloudRemotePath = '/Music/SpotiFLAC',
|
||||
// Local Library defaults
|
||||
this.localLibraryEnabled = false,
|
||||
this.localLibraryPath = '',
|
||||
this.localLibraryShowDuplicates = true,
|
||||
});
|
||||
|
||||
AppSettings copyWith({
|
||||
@@ -128,6 +137,10 @@ class AppSettings {
|
||||
String? cloudUsername,
|
||||
String? cloudPassword,
|
||||
String? cloudRemotePath,
|
||||
// Local Library
|
||||
bool? localLibraryEnabled,
|
||||
String? localLibraryPath,
|
||||
bool? localLibraryShowDuplicates,
|
||||
}) {
|
||||
return AppSettings(
|
||||
defaultService: defaultService ?? this.defaultService,
|
||||
@@ -169,6 +182,10 @@ class AppSettings {
|
||||
cloudUsername: cloudUsername ?? this.cloudUsername,
|
||||
cloudPassword: cloudPassword ?? this.cloudPassword,
|
||||
cloudRemotePath: cloudRemotePath ?? this.cloudRemotePath,
|
||||
// Local Library
|
||||
localLibraryEnabled: localLibraryEnabled ?? this.localLibraryEnabled,
|
||||
localLibraryPath: localLibraryPath ?? this.localLibraryPath,
|
||||
localLibraryShowDuplicates: localLibraryShowDuplicates ?? this.localLibraryShowDuplicates,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,10 @@ AppSettings _$AppSettingsFromJson(Map<String, dynamic> json) => AppSettings(
|
||||
cloudUsername: json['cloudUsername'] as String? ?? '',
|
||||
cloudPassword: json['cloudPassword'] as String? ?? '',
|
||||
cloudRemotePath: json['cloudRemotePath'] as String? ?? '/Music/SpotiFLAC',
|
||||
localLibraryEnabled: json['localLibraryEnabled'] as bool? ?? false,
|
||||
localLibraryPath: json['localLibraryPath'] as String? ?? '',
|
||||
localLibraryShowDuplicates:
|
||||
json['localLibraryShowDuplicates'] as bool? ?? true,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$AppSettingsToJson(AppSettings instance) =>
|
||||
@@ -90,4 +94,7 @@ Map<String, dynamic> _$AppSettingsToJson(AppSettings instance) =>
|
||||
'cloudUsername': instance.cloudUsername,
|
||||
'cloudPassword': instance.cloudPassword,
|
||||
'cloudRemotePath': instance.cloudRemotePath,
|
||||
'localLibraryEnabled': instance.localLibraryEnabled,
|
||||
'localLibraryPath': instance.localLibraryPath,
|
||||
'localLibraryShowDuplicates': instance.localLibraryShowDuplicates,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user