✨ Allow player keep original cache provider
♿ Support chain fallback
			
			
This commit is contained in:
		| @@ -1,5 +1,7 @@ | ||||
| import 'package:collection/collection.dart'; | ||||
| import 'package:drift/drift.dart'; | ||||
| import 'package:get/get.dart'; | ||||
| import 'package:rhythm_box/providers/database.dart'; | ||||
| import 'package:rhythm_box/providers/error_notifier.dart'; | ||||
| import 'package:rhythm_box/providers/user_preferences.dart'; | ||||
| import 'package:rhythm_box/services/database/database.dart'; | ||||
| @@ -97,9 +99,43 @@ abstract class SourcedTrack extends Track { | ||||
|  | ||||
|   static Future<SourcedTrack> fetchFromTrack({ | ||||
|     required Track track, | ||||
|     AudioSource? fallbackTo, | ||||
|   }) async { | ||||
|     final preferences = Get.find<UserPreferencesProvider>().state.value; | ||||
|     final audioSource = preferences.audioSource; | ||||
|     var audioSource = preferences.audioSource; | ||||
|  | ||||
|     if (!preferences.overrideCacheProvider && fallbackTo == null) { | ||||
|       final DatabaseProvider db = Get.find(); | ||||
|       final cachedSource = | ||||
|           await (db.database.select(db.database.sourceMatchTable) | ||||
|                 ..where((s) => s.trackId.equals(track.id!)) | ||||
|                 ..limit(1) | ||||
|                 ..orderBy([ | ||||
|                   (s) => OrderingTerm( | ||||
|                       expression: s.createdAt, mode: OrderingMode.desc), | ||||
|                 ])) | ||||
|               .get() | ||||
|               .then((s) => s.firstOrNull); | ||||
|  | ||||
|       final ytOrPiped = preferences.audioSource == AudioSource.youtube | ||||
|           ? AudioSource.youtube | ||||
|           : AudioSource.piped; | ||||
|       final sourceTypeTrackMap = { | ||||
|         SourceType.youtube: ytOrPiped, | ||||
|         SourceType.youtubeMusic: ytOrPiped, | ||||
|         SourceType.netease: AudioSource.netease, | ||||
|         SourceType.kugou: AudioSource.kugou, | ||||
|       }; | ||||
|  | ||||
|       if (cachedSource != null) { | ||||
|         final cachedAudioSource = sourceTypeTrackMap[cachedSource.sourceType]!; | ||||
|         audioSource = cachedAudioSource; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (fallbackTo != null) { | ||||
|       audioSource = fallbackTo; | ||||
|     } | ||||
|  | ||||
|     try { | ||||
|       return switch (audioSource) { | ||||
| @@ -115,14 +151,20 @@ abstract class SourcedTrack extends Track { | ||||
|       Get.find<ErrorNotifier>().showError( | ||||
|         '${err.toString()} via ${preferences.audioSource.label}, querying in fallback sources...', | ||||
|       ); | ||||
|       return switch (preferences.audioSource) { | ||||
|         AudioSource.piped || | ||||
|         AudioSource.youtube => | ||||
|           await NeteaseSourcedTrack.fetchFromTrack(track: track), | ||||
|  | ||||
|       if (fallbackTo != null) { | ||||
|         // Prevent infinite fallback | ||||
|         if (audioSource == AudioSource.youtube || | ||||
|             audioSource == AudioSource.piped) rethrow; | ||||
|       } | ||||
|  | ||||
|       return switch (audioSource) { | ||||
|         AudioSource.netease => | ||||
|           await KugouSourcedTrack.fetchFromTrack(track: track), | ||||
|           await fetchFromTrack(track: track, fallbackTo: AudioSource.kugou), | ||||
|         AudioSource.kugou => | ||||
|           await YoutubeSourcedTrack.fetchFromTrack(track: track), | ||||
|           await fetchFromTrack(track: track, fallbackTo: AudioSource.youtube), | ||||
|         _ => | ||||
|           await fetchFromTrack(track: track, fallbackTo: AudioSource.netease), | ||||
|       }; | ||||
|     } on HttpClientClosedException catch (_) { | ||||
|       return await PipedSourcedTrack.fetchFromTrack(track: track); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user