mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-07-17 09:37:20 +02:00
refactor: remove legacy API clients, Yoinkify fallback, and unused lyrics provider
- Delete dead metadata client and extract shared types to metadata_types.go - Remove Yoinkify download fallback from Deezer, use MusicDL only - Clean up retired settings fields and metadataSource - Remove dead l10n keys for retired provider - Add migration to strip retired provider from existing users' lyrics config
This commit is contained in:
@@ -4647,12 +4647,6 @@ abstract class AppLocalizations {
|
||||
/// **'You have unsaved changes that will be lost.'**
|
||||
String get lyricsProvidersDiscardContent;
|
||||
|
||||
/// Description for Spotify Lyrics API provider
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Spotify-sourced synced lyrics via community API'**
|
||||
String get lyricsProviderSpotifyApiDesc;
|
||||
|
||||
/// Description for LRCLIB provider
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
||||
@@ -2706,10 +2706,6 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get lyricsProvidersDiscardContent =>
|
||||
'You have unsaved changes that will be lost.';
|
||||
|
||||
@override
|
||||
String get lyricsProviderSpotifyApiDesc =>
|
||||
'Spotify-sourced synced lyrics via community API';
|
||||
|
||||
@override
|
||||
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
|
||||
|
||||
|
||||
@@ -2674,10 +2674,6 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get lyricsProvidersDiscardContent =>
|
||||
'You have unsaved changes that will be lost.';
|
||||
|
||||
@override
|
||||
String get lyricsProviderSpotifyApiDesc =>
|
||||
'Spotify-sourced synced lyrics via community API';
|
||||
|
||||
@override
|
||||
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
|
||||
|
||||
|
||||
@@ -2674,10 +2674,6 @@ class AppLocalizationsEs extends AppLocalizations {
|
||||
String get lyricsProvidersDiscardContent =>
|
||||
'You have unsaved changes that will be lost.';
|
||||
|
||||
@override
|
||||
String get lyricsProviderSpotifyApiDesc =>
|
||||
'Spotify-sourced synced lyrics via community API';
|
||||
|
||||
@override
|
||||
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
|
||||
|
||||
|
||||
@@ -2675,10 +2675,6 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get lyricsProvidersDiscardContent =>
|
||||
'You have unsaved changes that will be lost.';
|
||||
|
||||
@override
|
||||
String get lyricsProviderSpotifyApiDesc =>
|
||||
'Spotify-sourced synced lyrics via community API';
|
||||
|
||||
@override
|
||||
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
|
||||
|
||||
|
||||
@@ -2673,10 +2673,6 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
String get lyricsProvidersDiscardContent =>
|
||||
'You have unsaved changes that will be lost.';
|
||||
|
||||
@override
|
||||
String get lyricsProviderSpotifyApiDesc =>
|
||||
'Spotify-sourced synced lyrics via community API';
|
||||
|
||||
@override
|
||||
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
|
||||
|
||||
|
||||
@@ -2684,10 +2684,6 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
String get lyricsProvidersDiscardContent =>
|
||||
'You have unsaved changes that will be lost.';
|
||||
|
||||
@override
|
||||
String get lyricsProviderSpotifyApiDesc =>
|
||||
'Spotify-sourced synced lyrics via community API';
|
||||
|
||||
@override
|
||||
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
|
||||
|
||||
|
||||
@@ -2660,10 +2660,6 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
String get lyricsProvidersDiscardContent =>
|
||||
'You have unsaved changes that will be lost.';
|
||||
|
||||
@override
|
||||
String get lyricsProviderSpotifyApiDesc =>
|
||||
'Spotify-sourced synced lyrics via community API';
|
||||
|
||||
@override
|
||||
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
|
||||
|
||||
|
||||
@@ -2653,10 +2653,6 @@ class AppLocalizationsKo extends AppLocalizations {
|
||||
String get lyricsProvidersDiscardContent =>
|
||||
'You have unsaved changes that will be lost.';
|
||||
|
||||
@override
|
||||
String get lyricsProviderSpotifyApiDesc =>
|
||||
'Spotify-sourced synced lyrics via community API';
|
||||
|
||||
@override
|
||||
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
|
||||
|
||||
|
||||
@@ -2673,10 +2673,6 @@ class AppLocalizationsNl extends AppLocalizations {
|
||||
String get lyricsProvidersDiscardContent =>
|
||||
'You have unsaved changes that will be lost.';
|
||||
|
||||
@override
|
||||
String get lyricsProviderSpotifyApiDesc =>
|
||||
'Spotify-sourced synced lyrics via community API';
|
||||
|
||||
@override
|
||||
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
|
||||
|
||||
|
||||
@@ -2674,10 +2674,6 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
String get lyricsProvidersDiscardContent =>
|
||||
'You have unsaved changes that will be lost.';
|
||||
|
||||
@override
|
||||
String get lyricsProviderSpotifyApiDesc =>
|
||||
'Spotify-sourced synced lyrics via community API';
|
||||
|
||||
@override
|
||||
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
|
||||
|
||||
|
||||
@@ -2733,10 +2733,6 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String get lyricsProvidersDiscardContent =>
|
||||
'You have unsaved changes that will be lost.';
|
||||
|
||||
@override
|
||||
String get lyricsProviderSpotifyApiDesc =>
|
||||
'Spotify-sourced synced lyrics via community API';
|
||||
|
||||
@override
|
||||
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
|
||||
|
||||
|
||||
@@ -2679,10 +2679,6 @@ class AppLocalizationsTr extends AppLocalizations {
|
||||
String get lyricsProvidersDiscardContent =>
|
||||
'You have unsaved changes that will be lost.';
|
||||
|
||||
@override
|
||||
String get lyricsProviderSpotifyApiDesc =>
|
||||
'Spotify-sourced synced lyrics via community API';
|
||||
|
||||
@override
|
||||
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
|
||||
|
||||
|
||||
@@ -2674,10 +2674,6 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String get lyricsProvidersDiscardContent =>
|
||||
'You have unsaved changes that will be lost.';
|
||||
|
||||
@override
|
||||
String get lyricsProviderSpotifyApiDesc =>
|
||||
'Spotify-sourced synced lyrics via community API';
|
||||
|
||||
@override
|
||||
String get lyricsProviderLrclibDesc => 'Open-source synced lyrics database';
|
||||
|
||||
|
||||
@@ -3551,10 +3551,6 @@
|
||||
"@lyricsProvidersDiscardContent": {
|
||||
"description": "Body text of the discard-changes dialog on lyrics provider page"
|
||||
},
|
||||
"lyricsProviderSpotifyApiDesc": "Spotify-sourced synced lyrics via community API",
|
||||
"@lyricsProviderSpotifyApiDesc": {
|
||||
"description": "Description for Spotify Lyrics API provider"
|
||||
},
|
||||
"lyricsProviderLrclibDesc": "Open-source synced lyrics database",
|
||||
"@lyricsProviderLrclibDesc": {
|
||||
"description": "Description for LRCLIB provider"
|
||||
|
||||
@@ -30,10 +30,6 @@ class AppSettings {
|
||||
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;
|
||||
@@ -107,10 +103,6 @@ class AppSettings {
|
||||
this.historyViewMode = 'grid',
|
||||
this.historyFilterMode = 'all',
|
||||
this.askQualityBeforeDownload = true,
|
||||
this.spotifyClientId = '',
|
||||
this.spotifyClientSecret = '',
|
||||
this.useCustomSpotifyCredentials = false,
|
||||
this.metadataSource = 'deezer',
|
||||
this.enableLogging = false,
|
||||
this.useExtensionProviders = true,
|
||||
this.searchProvider,
|
||||
@@ -134,7 +126,6 @@ class AppSettings {
|
||||
this.hasCompletedTutorial = false,
|
||||
this.lyricsProviders = const [
|
||||
'lrclib',
|
||||
'spotify_api',
|
||||
'musixmatch',
|
||||
'netease',
|
||||
'apple_music',
|
||||
@@ -172,10 +163,6 @@ class AppSettings {
|
||||
String? historyViewMode,
|
||||
String? historyFilterMode,
|
||||
bool? askQualityBeforeDownload,
|
||||
String? spotifyClientId,
|
||||
String? spotifyClientSecret,
|
||||
bool? useCustomSpotifyCredentials,
|
||||
String? metadataSource,
|
||||
bool? enableLogging,
|
||||
bool? useExtensionProviders,
|
||||
String? searchProvider,
|
||||
@@ -235,11 +222,6 @@ class AppSettings {
|
||||
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,
|
||||
|
||||
@@ -32,11 +32,6 @@ AppSettings _$AppSettingsFromJson(Map<String, dynamic> json) => AppSettings(
|
||||
historyViewMode: json['historyViewMode'] as String? ?? 'grid',
|
||||
historyFilterMode: json['historyFilterMode'] as String? ?? 'all',
|
||||
askQualityBeforeDownload: json['askQualityBeforeDownload'] as bool? ?? true,
|
||||
spotifyClientId: json['spotifyClientId'] as String? ?? '',
|
||||
spotifyClientSecret: json['spotifyClientSecret'] as String? ?? '',
|
||||
useCustomSpotifyCredentials:
|
||||
json['useCustomSpotifyCredentials'] as bool? ?? false,
|
||||
metadataSource: json['metadataSource'] as String? ?? 'deezer',
|
||||
enableLogging: json['enableLogging'] as bool? ?? false,
|
||||
useExtensionProviders: json['useExtensionProviders'] as bool? ?? true,
|
||||
searchProvider: json['searchProvider'] as String?,
|
||||
@@ -65,14 +60,7 @@ AppSettings _$AppSettingsFromJson(Map<String, dynamic> json) => AppSettings(
|
||||
(json['lyricsProviders'] as List<dynamic>?)
|
||||
?.map((e) => e as String)
|
||||
.toList() ??
|
||||
const [
|
||||
'lrclib',
|
||||
'spotify_api',
|
||||
'musixmatch',
|
||||
'netease',
|
||||
'apple_music',
|
||||
'qqmusic',
|
||||
],
|
||||
const ['lrclib', 'musixmatch', 'netease', 'apple_music', 'qqmusic'],
|
||||
lyricsIncludeTranslationNetease:
|
||||
json['lyricsIncludeTranslationNetease'] as bool? ?? false,
|
||||
lyricsIncludeRomanizationNetease:
|
||||
@@ -111,10 +99,6 @@ Map<String, dynamic> _$AppSettingsToJson(
|
||||
'historyViewMode': instance.historyViewMode,
|
||||
'historyFilterMode': instance.historyFilterMode,
|
||||
'askQualityBeforeDownload': instance.askQualityBeforeDownload,
|
||||
'spotifyClientId': instance.spotifyClientId,
|
||||
'spotifyClientSecret': instance.spotifyClientSecret,
|
||||
'useCustomSpotifyCredentials': instance.useCustomSpotifyCredentials,
|
||||
'metadataSource': instance.metadataSource,
|
||||
'enableLogging': instance.enableLogging,
|
||||
'useExtensionProviders': instance.useExtensionProviders,
|
||||
'searchProvider': instance.searchProvider,
|
||||
|
||||
@@ -662,9 +662,8 @@ class ExtensionNotifier extends Notifier<ExtensionState> {
|
||||
|
||||
if (settings.searchProvider == extensionId) {
|
||||
ref.read(settingsProvider.notifier).setSearchProvider(null);
|
||||
ref.read(settingsProvider.notifier).setMetadataSource('deezer');
|
||||
_log.d(
|
||||
'Cleared search provider and reset to Deezer because extension $extensionId was disabled',
|
||||
'Cleared search provider because extension $extensionId was disabled',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import 'package:spotiflac_android/utils/logger.dart';
|
||||
|
||||
const _settingsKey = 'app_settings';
|
||||
const _migrationVersionKey = 'settings_migration_version';
|
||||
const _currentMigrationVersion = 7;
|
||||
const _currentMigrationVersion = 9;
|
||||
const _spotifyClientSecretKey = 'spotify_client_secret';
|
||||
final _log = AppLogger('SettingsProvider');
|
||||
|
||||
@@ -44,7 +44,7 @@ class SettingsNotifier extends Notifier<AppSettings> {
|
||||
await _normalizeSongLinkRegionIfNeeded();
|
||||
}
|
||||
|
||||
await _retireBuiltInSpotifyProvider();
|
||||
await _cleanupRetiredSpotifySettings();
|
||||
|
||||
LogBuffer.loggingEnabled = state.enableLogging;
|
||||
|
||||
@@ -86,13 +86,6 @@ class SettingsNotifier extends Notifier<AppSettings> {
|
||||
Future<void> _runMigrations(SharedPreferences prefs) async {
|
||||
final lastMigration = prefs.getInt(_migrationVersionKey) ?? 0;
|
||||
|
||||
if (lastMigration < 1) {
|
||||
if (!state.useCustomSpotifyCredentials) {
|
||||
state = state.copyWith(metadataSource: 'deezer');
|
||||
await _saveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
if (lastMigration < _currentMigrationVersion) {
|
||||
if (state.downloadTreeUri.isNotEmpty && state.storageMode != 'saf') {
|
||||
state = state.copyWith(storageMode: 'saf');
|
||||
@@ -101,26 +94,20 @@ class SettingsNotifier extends Notifier<AppSettings> {
|
||||
if (!state.isFirstLaunch && !state.hasCompletedTutorial) {
|
||||
state = state.copyWith(hasCompletedTutorial: true);
|
||||
}
|
||||
// Migration 4: include Spotify Lyrics API in provider order for existing users
|
||||
if (!state.lyricsProviders.contains('spotify_api')) {
|
||||
final updatedProviders = List<String>.from(state.lyricsProviders);
|
||||
final lrclibIndex = updatedProviders.indexOf('lrclib');
|
||||
if (lrclibIndex >= 0) {
|
||||
updatedProviders.insert(lrclibIndex + 1, 'spotify_api');
|
||||
} else {
|
||||
updatedProviders.add('spotify_api');
|
||||
}
|
||||
state = state.copyWith(lyricsProviders: updatedProviders);
|
||||
}
|
||||
if (state.metadataSource != 'deezer' ||
|
||||
state.spotifyClientId.isNotEmpty ||
|
||||
state.spotifyClientSecret.isNotEmpty ||
|
||||
state.useCustomSpotifyCredentials) {
|
||||
if (state.lyricsProviders.contains('spotify_api')) {
|
||||
final updatedProviders = state.lyricsProviders
|
||||
.where((provider) => provider != 'spotify_api')
|
||||
.toList();
|
||||
state = state.copyWith(
|
||||
metadataSource: 'deezer',
|
||||
spotifyClientId: '',
|
||||
spotifyClientSecret: '',
|
||||
useCustomSpotifyCredentials: false,
|
||||
lyricsProviders: updatedProviders.isEmpty
|
||||
? const [
|
||||
'lrclib',
|
||||
'musixmatch',
|
||||
'netease',
|
||||
'apple_music',
|
||||
'qqmusic',
|
||||
]
|
||||
: updatedProviders,
|
||||
);
|
||||
}
|
||||
state = state.copyWith(lastSeenVersion: AppInfo.version);
|
||||
@@ -134,8 +121,7 @@ class SettingsNotifier extends Notifier<AppSettings> {
|
||||
}
|
||||
|
||||
Future<void> _saveSettings() async {
|
||||
final settingsToSave = state.copyWith(spotifyClientSecret: '');
|
||||
_pendingSettingsJson = jsonEncode(settingsToSave.toJson());
|
||||
_pendingSettingsJson = jsonEncode(state.toJson());
|
||||
|
||||
if (_isSavingSettings) {
|
||||
_saveQueued = true;
|
||||
@@ -186,28 +172,13 @@ class SettingsNotifier extends Notifier<AppSettings> {
|
||||
await _saveSettings();
|
||||
}
|
||||
|
||||
Future<void> _retireBuiltInSpotifyProvider() async {
|
||||
Future<void> _cleanupRetiredSpotifySettings() async {
|
||||
final storedSecret = await _secureStorage.read(
|
||||
key: _spotifyClientSecretKey,
|
||||
);
|
||||
if (storedSecret != null && storedSecret.isNotEmpty) {
|
||||
await _secureStorage.delete(key: _spotifyClientSecretKey);
|
||||
}
|
||||
|
||||
if (state.metadataSource == 'deezer' &&
|
||||
state.spotifyClientId.isEmpty &&
|
||||
state.spotifyClientSecret.isEmpty &&
|
||||
!state.useCustomSpotifyCredentials) {
|
||||
return;
|
||||
}
|
||||
|
||||
state = state.copyWith(
|
||||
metadataSource: 'deezer',
|
||||
spotifyClientId: '',
|
||||
spotifyClientSecret: '',
|
||||
useCustomSpotifyCredentials: false,
|
||||
);
|
||||
await _saveSettings();
|
||||
}
|
||||
|
||||
void setDefaultService(String service) {
|
||||
@@ -380,11 +351,6 @@ class SettingsNotifier extends Notifier<AppSettings> {
|
||||
_saveSettings();
|
||||
}
|
||||
|
||||
void setMetadataSource(String source) {
|
||||
state = state.copyWith(metadataSource: source);
|
||||
_saveSettings();
|
||||
}
|
||||
|
||||
void setSearchProvider(String? provider) {
|
||||
if (provider == null || provider.isEmpty) {
|
||||
state = state.copyWith(clearSearchProvider: true);
|
||||
|
||||
@@ -1563,7 +1563,6 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
|
||||
}
|
||||
|
||||
static const _providerDisplayNames = <String, String>{
|
||||
'spotify_api': 'Spotify Lyrics API',
|
||||
'lrclib': 'LRCLIB',
|
||||
'netease': 'Netease',
|
||||
'musixmatch': 'Musixmatch',
|
||||
|
||||
@@ -17,7 +17,6 @@ class _LyricsProviderPriorityPageState
|
||||
extends ConsumerState<LyricsProviderPriorityPage> {
|
||||
static const _allProviderIds = [
|
||||
'lrclib',
|
||||
'spotify_api',
|
||||
'netease',
|
||||
'musixmatch',
|
||||
'apple_music',
|
||||
@@ -133,9 +132,7 @@ class _LyricsProviderPriorityPageState
|
||||
void _disableProvider(String id) {
|
||||
if (_enabledProviders.length <= 1) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(context.l10n.lyricsProvidersAtLeastOne),
|
||||
),
|
||||
SnackBar(content: Text(context.l10n.lyricsProvidersAtLeastOne)),
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -184,12 +181,6 @@ class _LyricsProviderPriorityPageState
|
||||
BuildContext context,
|
||||
) {
|
||||
switch (id) {
|
||||
case 'spotify_api':
|
||||
return _LyricsProviderInfo(
|
||||
name: 'Spotify Lyrics API',
|
||||
description: context.l10n.lyricsProviderSpotifyApiDesc,
|
||||
icon: Icons.music_note_outlined,
|
||||
);
|
||||
case 'lrclib':
|
||||
return _LyricsProviderInfo(
|
||||
name: 'LRCLIB',
|
||||
|
||||
@@ -70,15 +70,7 @@ class OptionsSettingsPage extends ConsumerWidget {
|
||||
),
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
child: SettingsGroup(
|
||||
children: [
|
||||
_MetadataSourceSelector(
|
||||
onChanged: (v) => ref
|
||||
.read(settingsProvider.notifier)
|
||||
.setMetadataSource(v),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: SettingsGroup(children: [const _MetadataSourceSelector()]),
|
||||
),
|
||||
|
||||
SliverToBoxAdapter(
|
||||
@@ -706,8 +698,7 @@ class _ChannelChip extends StatelessWidget {
|
||||
}
|
||||
|
||||
class _MetadataSourceSelector extends ConsumerWidget {
|
||||
final ValueChanged<String> onChanged;
|
||||
const _MetadataSourceSelector({required this.onChanged});
|
||||
const _MetadataSourceSelector();
|
||||
|
||||
static const _builtInProviders = {'tidal': 'Tidal', 'qobuz': 'Qobuz'};
|
||||
|
||||
@@ -770,7 +761,6 @@ class _MetadataSourceSelector extends ConsumerWidget {
|
||||
if (hasNonDefaultProvider) {
|
||||
ref.read(settingsProvider.notifier).setSearchProvider(null);
|
||||
}
|
||||
onChanged('deezer');
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
@@ -782,7 +772,6 @@ class _MetadataSourceSelector extends ConsumerWidget {
|
||||
ref
|
||||
.read(settingsProvider.notifier)
|
||||
.setSearchProvider('tidal');
|
||||
onChanged('tidal');
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
@@ -794,7 +783,6 @@ class _MetadataSourceSelector extends ConsumerWidget {
|
||||
ref
|
||||
.read(settingsProvider.notifier)
|
||||
.setSearchProvider('qobuz');
|
||||
onChanged('qobuz');
|
||||
},
|
||||
),
|
||||
],
|
||||
|
||||
@@ -426,7 +426,6 @@ class _SetupScreenState extends ConsumerState<SetupScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
ref.read(settingsProvider.notifier).setMetadataSource('deezer');
|
||||
ref.read(settingsProvider.notifier).setFirstLaunchComplete();
|
||||
|
||||
if (mounted) context.go('/tutorial');
|
||||
|
||||
Reference in New Issue
Block a user