import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:rxdart/rxdart.dart'; import '../database/database.dart'; import '../log.dart'; import '../state/settings.dart'; abstract class BaseMusicSource { int get id; Future ping(); Stream> allAlbums(); Stream> allArtists(); Stream> allPlaylists(); Stream> allSongs(); Uri streamUri(String songId); Uri downloadUri(String songId); Uri coverArtUri(String coverArtId, {bool thumbnail = true}); Future artistArtUri(String artistId, {bool thumbnail = true}); } class OfflineException implements Exception { @override String toString() => 'OfflineException'; } class MusicSource implements BaseMusicSource { final BaseMusicSource _source; final Ref _ref; const MusicSource(this._source, this._ref); void _testOnline() { if (_ref.read(offlineModeProvider)) { throw OfflineException(); } } @override Stream> allAlbums() { _testOnline(); return _source .allAlbums() .doOnError((e, st) => log.severe('allAlbums', e, st)); } @override Stream> allArtists() { _testOnline(); return _source .allArtists() .doOnError((e, st) => log.severe('allArtists', e, st)); } @override Stream> allPlaylists() { _testOnline(); return _source .allPlaylists() .doOnError((e, st) => log.severe('allPlaylists', e, st)); } @override Stream> allSongs() { _testOnline(); return _source .allSongs() .doOnError((e, st) => log.severe('allSongs', e, st)); } @override Future artistArtUri(String artistId, {bool thumbnail = true}) { _testOnline(); return _source.artistArtUri(artistId, thumbnail: thumbnail); } @override Uri coverArtUri(String coverArtId, {bool thumbnail = true}) => _source.coverArtUri(coverArtId, thumbnail: thumbnail); @override Uri downloadUri(String songId) => _source.downloadUri(songId); @override int get id => _source.id; @override Future ping() => _source.ping(); @override Uri streamUri(String songId) => _source.streamUri(songId); }