diff --git a/lib/main.dart b/lib/main.dart index da53668e..9a862568 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,7 +8,6 @@ import 'package:flutter/services.dart'; import 'package:flutter_discord_rpc/flutter_discord_rpc.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:get_it/get_it.dart'; import 'package:home_widget/home_widget.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -31,7 +30,6 @@ import 'package:spotube/hooks/configurators/use_has_touch.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart'; import 'package:spotube/provider/audio_player/audio_player_streams.dart'; -import 'package:spotube/provider/database/database.dart'; import 'package:spotube/provider/glance/glance.dart'; import 'package:spotube/provider/server/bonsoir.dart'; import 'package:spotube/provider/server/server.dart'; @@ -73,7 +71,9 @@ Future main(List rawArgs) async { () => KVStoreService.init(), dependsOn: [SharedPreferences], ); + getIt.registerLazySingleton(() => AppDatabase()); getIt.registerSingleton(SpotubeAudioPlayer()); + getIt.registerSingleton(windowManager); await registerWindowsScheme("spotify"); @@ -112,8 +112,6 @@ Future main(List rawArgs) async { await EncryptedKvStoreService.initialize(); - final database = AppDatabase(); - if (kIsDesktop) { await localNotifier.setup(appName: "Spotube"); await WindowManagerTools.initialize(); @@ -124,14 +122,11 @@ Future main(List rawArgs) async { } runApp( - ProviderScope( - overrides: [ - databaseProvider.overrideWith((ref) => database), - ], - observers: const [ + const ProviderScope( + observers: [ AppLoggerProviderObserver(), ], - child: const Spotube(), + child: Spotube(), ), ); }); diff --git a/lib/provider/audio_player/audio_player.dart b/lib/provider/audio_player/audio_player.dart index aa93bd4f..f7292653 100644 --- a/lib/provider/audio_player/audio_player.dart +++ b/lib/provider/audio_player/audio_player.dart @@ -4,13 +4,13 @@ import 'package:drift/drift.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:media_kit/media_kit.dart' hide Track; import 'package:spotify/spotify.dart' hide Playlist; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/extensions/list.dart'; import 'package:spotube/extensions/track.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/models/local_track.dart'; import 'package:spotube/provider/audio_player/state.dart'; import 'package:spotube/provider/blacklist_provider.dart'; -import 'package:spotube/provider/database/database.dart'; import 'package:spotube/provider/discord_provider.dart'; import 'package:spotube/provider/server/sourced_track.dart'; import 'package:spotube/services/audio_player/audio_player.dart'; @@ -20,7 +20,7 @@ class AudioPlayerNotifier extends Notifier { BlackListNotifier get _blacklist => ref.read(blacklistProvider.notifier); Future _syncSavedState() async { - final database = ref.read(databaseProvider); + final database = getIt.get(); var playerState = await database.select(database.audioPlayerStateTable).getSingleOrNull(); @@ -102,7 +102,7 @@ class AudioPlayerNotifier extends Notifier { Future _updatePlayerState( AudioPlayerStateTableCompanion companion, ) async { - final database = ref.read(databaseProvider); + final database = getIt.get(); await (database.update(database.audioPlayerStateTable) ..where((tb) => tb.id.equals(0))) @@ -112,7 +112,7 @@ class AudioPlayerNotifier extends Notifier { Future _updatePlaylist( Playlist playlist, ) async { - final database = ref.read(databaseProvider); + final database = getIt.get(); await database.batch((batch) { batch.update( diff --git a/lib/provider/authentication/authentication.dart b/lib/provider/authentication/authentication.dart index 583955b0..a9101f2e 100644 --- a/lib/provider/authentication/authentication.dart +++ b/lib/provider/authentication/authentication.dart @@ -11,10 +11,10 @@ import 'package:flutter_inappwebview/flutter_inappwebview.dart' hide X509Certificate; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotube/collections/routes.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/components/dialogs/prompt_dialog.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/models/database/database.dart'; -import 'package:spotube/provider/database/database.dart'; import 'package:spotube/services/logger/logger.dart'; import 'package:spotube/utils/platform.dart'; import 'package:otp_util/otp_util.dart'; @@ -51,10 +51,10 @@ class AuthenticationNotifier extends AsyncNotifier { return dio; }(); + AppDatabase get database => getIt.get(); + @override build() async { - final database = ref.watch(databaseProvider); - final data = await (database.select(database.authenticationTable) ..where((s) => s.id.equals(0))) .getSingleOrNull(); @@ -92,7 +92,6 @@ class AuthenticationNotifier extends AsyncNotifier { } Future refreshCredentials() async { - final database = ref.read(databaseProvider); final refreshedCredentials = await credentialsFromCookie(state.asData!.value!.cookie.value); @@ -102,7 +101,6 @@ class AuthenticationNotifier extends AsyncNotifier { } Future login(String cookie) async { - final database = ref.read(databaseProvider); final refreshedCredentials = await credentialsFromCookie(cookie); await database @@ -289,7 +287,6 @@ class AuthenticationNotifier extends AsyncNotifier { Future logout() async { state = const AsyncData(null); - final database = ref.read(databaseProvider); await (database.delete(database.authenticationTable) ..where((s) => s.id.equals(0))) .go(); diff --git a/lib/provider/blacklist_provider.dart b/lib/provider/blacklist_provider.dart index a51d399f..0ce721f9 100644 --- a/lib/provider/blacklist_provider.dart +++ b/lib/provider/blacklist_provider.dart @@ -1,17 +1,17 @@ import 'package:collection/collection.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/models/current_playlist.dart'; import 'package:spotube/models/database/database.dart'; -import 'package:spotube/provider/database/database.dart'; class BlackListNotifier extends AsyncNotifier> { + AppDatabase get db => getIt.get(); + @override build() async { - final database = ref.watch(databaseProvider); - - final subscription = database - .select(database.blacklistTable) + final subscription = db + .select(db.blacklistTable) .watch() .listen((event) => state = AsyncData(event)); @@ -19,17 +19,15 @@ class BlackListNotifier extends AsyncNotifier> { subscription.cancel(); }); - return await database.select(database.blacklistTable).get(); + return await db.select(db.blacklistTable).get(); } - AppDatabase get _database => ref.read(databaseProvider); - Future add(BlacklistTableCompanion element) async { - _database.into(_database.blacklistTable).insert(element); + db.into(db.blacklistTable).insert(element); } Future remove(String elementId) async { - await (_database.delete(_database.blacklistTable) + await (db.delete(db.blacklistTable) ..where((tbl) => tbl.elementId.equals(elementId))) .go(); } diff --git a/lib/provider/database/database.dart b/lib/provider/database/database.dart deleted file mode 100644 index 95976e56..00000000 --- a/lib/provider/database/database.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:spotube/models/database/database.dart'; - -final databaseProvider = Provider((ref) => AppDatabase()); diff --git a/lib/provider/history/history.dart b/lib/provider/history/history.dart index 0c20a9e5..205c6eb6 100644 --- a/lib/provider/history/history.dart +++ b/lib/provider/history/history.dart @@ -1,11 +1,11 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/models/database/database.dart'; -import 'package:spotube/provider/database/database.dart'; class PlaybackHistoryActions { final Ref ref; - AppDatabase get _db => ref.read(databaseProvider); + AppDatabase get _db => getIt.get(); PlaybackHistoryActions(this.ref); diff --git a/lib/provider/history/recent.dart b/lib/provider/history/recent.dart index 1ee2a5d6..2a840219 100644 --- a/lib/provider/history/recent.dart +++ b/lib/provider/history/recent.dart @@ -2,13 +2,13 @@ import 'dart:convert'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/models/database/database.dart'; -import 'package:spotube/provider/database/database.dart'; class RecentlyPlayedItemNotifier extends AsyncNotifier> { @override build() async { - final database = ref.watch(databaseProvider); + final database = getIt.get(); final query = database.customSelect( """ diff --git a/lib/provider/history/summary.dart b/lib/provider/history/summary.dart index 99df4c11..9a1157fb 100644 --- a/lib/provider/history/summary.dart +++ b/lib/provider/history/summary.dart @@ -4,8 +4,8 @@ import 'dart:convert'; import 'package:drift/drift.dart'; import 'package:drift/extensions/json1.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/models/database/database.dart'; -import 'package:spotube/provider/database/database.dart'; class PlaybackHistorySummary { final Duration duration; @@ -47,7 +47,7 @@ class PlaybackHistorySummaryNotifier extends AsyncNotifier { @override build() async { - final database = ref.watch(databaseProvider); + final database = getIt.get(); final uniqItemIdCountingCol = database.historyTable.itemId.count(distinct: true); diff --git a/lib/provider/history/top/albums.dart b/lib/provider/history/top/albums.dart index b11e62d2..165b99b7 100644 --- a/lib/provider/history/top/albums.dart +++ b/lib/provider/history/top/albums.dart @@ -4,7 +4,8 @@ import 'package:collection/collection.dart'; import 'package:drift/drift.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotify/spotify.dart'; -import 'package:spotube/provider/database/database.dart'; +import 'package:spotube/collections/vars.dart'; +import 'package:spotube/models/database/database.dart'; import 'package:spotube/provider/history/top.dart'; import 'package:spotube/provider/spotify/spotify.dart'; @@ -39,7 +40,7 @@ class HistoryTopAlbumsNotifier extends FamilyPaginatedAsyncNotifier< HistoryTopAlbumsNotifier() : super(); Selectable createAlbumsQuery({int? limit, int? offset}) { - final database = ref.read(databaseProvider); + final database = getIt.get(); final duration = switch (arg) { HistoryDuration.allTime => '0', diff --git a/lib/provider/history/top/playlists.dart b/lib/provider/history/top/playlists.dart index 19eb3622..715d2829 100644 --- a/lib/provider/history/top/playlists.dart +++ b/lib/provider/history/top/playlists.dart @@ -2,8 +2,8 @@ import 'package:collection/collection.dart'; import 'package:drift/drift.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/models/database/database.dart'; -import 'package:spotube/provider/database/database.dart'; import 'package:spotube/provider/history/top.dart'; import 'package:spotube/provider/spotify/spotify.dart'; @@ -39,7 +39,7 @@ class HistoryTopPlaylistsNotifier extends FamilyPaginatedAsyncNotifier< SimpleSelectStatement<$HistoryTableTable, HistoryTableData> createPlaylistsQuery() { - final database = ref.read(databaseProvider); + final database = getIt.get(); return database.select(database.historyTable) ..where( diff --git a/lib/provider/history/top/tracks.dart b/lib/provider/history/top/tracks.dart index b737d148..1689885d 100644 --- a/lib/provider/history/top/tracks.dart +++ b/lib/provider/history/top/tracks.dart @@ -2,8 +2,8 @@ import 'package:collection/collection.dart'; import 'package:drift/drift.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/models/database/database.dart'; -import 'package:spotube/provider/database/database.dart'; import 'package:spotube/provider/history/top.dart'; import 'package:spotube/provider/spotify/spotify.dart'; @@ -56,7 +56,7 @@ class HistoryTopTracksNotifier extends FamilyPaginatedAsyncNotifier< SimpleSelectStatement<$HistoryTableTable, HistoryTableData> createTracksQuery() { - final database = ref.read(databaseProvider); + final database = getIt.get(); return database.select(database.historyTable) ..where( diff --git a/lib/provider/scrobbler/scrobbler.dart b/lib/provider/scrobbler/scrobbler.dart index 8aff0438..92f56ff4 100644 --- a/lib/provider/scrobbler/scrobbler.dart +++ b/lib/provider/scrobbler/scrobbler.dart @@ -5,24 +5,24 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:scrobblenaut/scrobblenaut.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/collections/env.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/extensions/artist_simple.dart'; import 'package:spotube/models/database/database.dart'; -import 'package:spotube/provider/database/database.dart'; import 'package:spotube/services/logger/logger.dart'; class ScrobblerNotifier extends AsyncNotifier { final StreamController _scrobbleController = StreamController.broadcast(); + AppDatabase get db => getIt.get(); + @override build() async { - final database = ref.watch(databaseProvider); - - final loginInfo = await (database.select(database.scrobblerTable) + final loginInfo = await (db.select(db.scrobblerTable) ..where((t) => t.id.equals(0))) .getSingleOrNull(); final subscription = - database.select(database.scrobblerTable).watch().listen((event) async { + db.select(db.scrobblerTable).watch().listen((event) async { try { if (event.isNotEmpty) { state = await AsyncValue.guard( @@ -83,8 +83,6 @@ class ScrobblerNotifier extends AsyncNotifier { String username, String password, ) async { - final database = ref.read(databaseProvider); - final lastFm = await LastFM.authenticate( apiKey: Env.lastFmApiKey, apiSecret: Env.lastFmApiSecret, @@ -94,7 +92,7 @@ class ScrobblerNotifier extends AsyncNotifier { if (!lastFm.isAuth) throw Exception("Invalid credentials"); - await database.into(database.scrobblerTable).insert( + await db.into(db.scrobblerTable).insert( ScrobblerTableCompanion.insert( id: const Value(0), username: username, @@ -105,8 +103,8 @@ class ScrobblerNotifier extends AsyncNotifier { Future logout() async { state = const AsyncValue.data(null); - final database = ref.read(databaseProvider); - await database.delete(database.scrobblerTable).go(); + + await db.delete(db.scrobblerTable).go(); } void scrobble(Track track) { diff --git a/lib/provider/skip_segments/skip_segments.dart b/lib/provider/skip_segments/skip_segments.dart index 005797f4..31bfdcd3 100644 --- a/lib/provider/skip_segments/skip_segments.dart +++ b/lib/provider/skip_segments/skip_segments.dart @@ -1,5 +1,5 @@ +import 'package:spotube/collections/vars.dart'; import 'package:spotube/models/database/database.dart'; -import 'package:spotube/provider/database/database.dart'; import 'package:spotube/services/logger/logger.dart'; import 'package:dio/dio.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -17,7 +17,7 @@ class SourcedSegments { Future> getAndCacheSkipSegments( String id, Ref ref) async { - final database = ref.read(databaseProvider); + final database = getIt.get(); try { final cached = await (database.select(database.skipSegmentTable) ..where((s) => s.trackId.equals(id))) diff --git a/lib/provider/spotify/lyrics/synced.dart b/lib/provider/spotify/lyrics/synced.dart index ff2a73f1..c4d191ff 100644 --- a/lib/provider/spotify/lyrics/synced.dart +++ b/lib/provider/spotify/lyrics/synced.dart @@ -123,7 +123,7 @@ class SyncedLyricsNotifier extends FamilyAsyncNotifier { @override FutureOr build(track) async { try { - final database = ref.watch(databaseProvider); + final database = getIt.get(); final spotify = ref.watch(spotifyProvider); final auth = await ref.watch(authenticationProvider.future); diff --git a/lib/provider/spotify/spotify.dart b/lib/provider/spotify/spotify.dart index a0753fcb..2d9db18d 100644 --- a/lib/provider/spotify/spotify.dart +++ b/lib/provider/spotify/spotify.dart @@ -6,9 +6,9 @@ import 'dart:math'; import 'package:drift/drift.dart'; import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/env.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/provider/authentication/authentication.dart'; -import 'package:spotube/provider/database/database.dart'; import 'package:spotube/services/logger/logger.dart'; import 'package:collection/collection.dart'; import 'package:dio/dio.dart'; diff --git a/lib/provider/tray_manager/tray_manager.dart b/lib/provider/tray_manager/tray_manager.dart index d4da60c4..efd1680f 100644 --- a/lib/provider/tray_manager/tray_manager.dart +++ b/lib/provider/tray_manager/tray_manager.dart @@ -1,9 +1,10 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/provider/tray_manager/tray_menu.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; -import 'package:spotube/provider/window_manager/window_manager.dart'; import 'package:spotube/utils/platform.dart'; import 'package:tray_manager/tray_manager.dart'; +import 'package:window_manager/window_manager.dart'; class SystemTrayManager with TrayListener { final Ref ref; @@ -40,7 +41,7 @@ class SystemTrayManager with TrayListener { @override onTrayIconMouseDown() { if (kIsWindows) { - ref.read(windowManagerProvider).show(); + getIt.get().show(); } else { trayManager.popUpContextMenu(); } @@ -49,7 +50,7 @@ class SystemTrayManager with TrayListener { @override onTrayIconRightMouseDown() { if (!kIsWindows) { - ref.read(windowManagerProvider).show(); + getIt.get().show(); } else { trayManager.popUpContextMenu(); } diff --git a/lib/provider/tray_manager/tray_menu.dart b/lib/provider/tray_manager/tray_menu.dart index 3944b08f..83be386b 100644 --- a/lib/provider/tray_manager/tray_menu.dart +++ b/lib/provider/tray_manager/tray_menu.dart @@ -1,11 +1,12 @@ import 'dart:io'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/provider/audio_player/audio_player.dart'; -import 'package:spotube/provider/window_manager/window_manager.dart'; import 'package:spotube/services/audio_player/audio_player.dart'; import 'package:media_kit/media_kit.dart' hide Track; import 'package:tray_manager/tray_manager.dart'; +import 'package:window_manager/window_manager.dart'; final audioPlayerLoopMode = StreamProvider((ref) { return audioPlayer.loopModeStream; @@ -19,7 +20,7 @@ final audioPlayerPlaying = StreamProvider((ref) { }); final trayMenuProvider = Provider((ref) { - final windowManager = ref.watch(windowManagerProvider); + final windowManager = getIt.get(); final playlistNotifier = ref.watch(audioPlayerProvider.notifier); final isPlaybackPlaying = diff --git a/lib/provider/user_preferences/user_preferences_provider.dart b/lib/provider/user_preferences/user_preferences_provider.dart index 68f937aa..fe093409 100644 --- a/lib/provider/user_preferences/user_preferences_provider.dart +++ b/lib/provider/user_preferences/user_preferences_provider.dart @@ -5,11 +5,10 @@ import 'package:path/path.dart'; import 'package:path_provider/path_provider.dart' as paths; import 'package:shadcn_flutter/shadcn_flutter.dart' hide join; import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart'; -import 'package:spotube/provider/database/database.dart'; import 'package:spotube/provider/user_preferences/default_download_dir_provider.dart'; -import 'package:spotube/provider/window_manager/window_manager.dart'; import 'package:spotube/services/audio_player/audio_player.dart'; import 'package:spotube/services/logger/logger.dart'; import 'package:spotube/services/sourced_track/enums.dart'; @@ -20,10 +19,10 @@ import 'package:open_file/open_file.dart'; typedef UserPreferences = PreferencesTableData; class UserPreferencesNotifier extends Notifier { + AppDatabase get db => getIt.get(); + @override build() { - final db = ref.watch(databaseProvider); - (db.select(db.preferencesTable)..where((tbl) => tbl.id.equals(0))) .getSingleOrNull() .then((result) async { @@ -50,7 +49,7 @@ class UserPreferencesNotifier extends Notifier { state = event; if (kIsDesktop) { - await ref.read(windowManagerProvider).setTitleBarStyle( + await getIt.get().setTitleBarStyle( state.systemTitleBar ? TitleBarStyle.normal : TitleBarStyle.hidden, @@ -71,29 +70,25 @@ class UserPreferencesNotifier extends Notifier { return PreferencesTable.defaults(); } - Future _getDefaultDownloadDirectory() async { - if (kIsAndroid) return "/storage/emulated/0/Download/Spotube"; + // Future _getDefaultDownloadDirectory() async { + // if (kIsAndroid) return "/storage/emulated/0/Download/Spotube"; - if (kIsMacOS) { - return join((await paths.getLibraryDirectory()).path, "Caches"); - } + // if (kIsMacOS) { + // return join((await paths.getLibraryDirectory()).path, "Caches"); + // } - return paths.getDownloadsDirectory().then((dir) { - return join(dir!.path, "Spotube"); - }); - } + // return paths.getDownloadsDirectory().then((dir) { + // return join(dir!.path, "Spotube"); + // }); + // } Future setData(PreferencesTableCompanion data) async { - final db = ref.read(databaseProvider); - final query = db.update(db.preferencesTable)..where((t) => t.id.equals(0)); await query.write(data); } Future reset() async { - final db = ref.read(databaseProvider); - final query = db.update(db.preferencesTable); await query.replace(PreferencesTableCompanion.insert(id: const Value(0))); diff --git a/lib/provider/window_manager/window_manager.dart b/lib/provider/window_manager/window_manager.dart deleted file mode 100644 index 3bb5ad35..00000000 --- a/lib/provider/window_manager/window_manager.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:window_manager/window_manager.dart'; - -final windowManagerProvider = Provider((ref) => windowManager); diff --git a/lib/services/sourced_track/sources/invidious.dart b/lib/services/sourced_track/sources/invidious.dart index 4a32ad41..aca13d08 100644 --- a/lib/services/sourced_track/sources/invidious.dart +++ b/lib/services/sourced_track/sources/invidious.dart @@ -2,8 +2,8 @@ import 'package:collection/collection.dart'; import 'package:drift/drift.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/models/database/database.dart'; -import 'package:spotube/provider/database/database.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; import 'package:spotube/services/sourced_track/enums.dart'; import 'package:spotube/services/sourced_track/exceptions.dart'; @@ -66,7 +66,8 @@ class InvidiousSourcedTrack extends SourcedTrack { ); } - final database = ref.read(databaseProvider); + final database = getIt.get(); + final cachedSource = await (database.select(database.sourceMatchTable) ..where((s) => s.trackId.equals(track.id!)) ..limit(1) @@ -258,7 +259,7 @@ class InvidiousSourcedTrack extends SourcedTrack { final manifest = await pipedClient.videos.get(newSourceInfo.id, local: true); - final database = ref.read(databaseProvider); + final database = getIt.get(); await database.into(database.sourceMatchTable).insert( SourceMatchTableCompanion.insert( trackId: id!, diff --git a/lib/services/sourced_track/sources/jiosaavn.dart b/lib/services/sourced_track/sources/jiosaavn.dart index 1434e4f7..ae6c99af 100644 --- a/lib/services/sourced_track/sources/jiosaavn.dart +++ b/lib/services/sourced_track/sources/jiosaavn.dart @@ -2,8 +2,8 @@ import 'package:collection/collection.dart'; import 'package:drift/drift.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/models/database/database.dart'; -import 'package:spotube/provider/database/database.dart'; import 'package:spotube/services/sourced_track/enums.dart'; import 'package:spotube/services/sourced_track/exceptions.dart'; import 'package:spotube/services/sourced_track/models/source_info.dart'; @@ -41,7 +41,7 @@ class JioSaavnSourcedTrack extends SourcedTrack { required Ref ref, bool weakMatch = false, }) async { - final database = ref.read(databaseProvider); + final database = getIt.get(); final cachedSource = await (database.select(database.sourceMatchTable) ..where((s) => s.trackId.equals(track.id!)) ..limit(1) @@ -214,7 +214,7 @@ class JioSaavnSourcedTrack extends SourcedTrack { final (:info, :source) = toSiblingType(item); - final database = ref.read(databaseProvider); + final database = getIt.get(); await database.into(database.sourceMatchTable).insert( SourceMatchTableCompanion.insert( trackId: id!, diff --git a/lib/services/sourced_track/sources/piped.dart b/lib/services/sourced_track/sources/piped.dart index 7ab9df44..150774f3 100644 --- a/lib/services/sourced_track/sources/piped.dart +++ b/lib/services/sourced_track/sources/piped.dart @@ -3,8 +3,8 @@ import 'package:drift/drift.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:piped_client/piped_client.dart'; import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/models/database/database.dart'; -import 'package:spotube/provider/database/database.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; import 'package:spotube/services/sourced_track/enums.dart'; @@ -63,7 +63,7 @@ class PipedSourcedTrack extends SourcedTrack { ); } - final database = ref.read(databaseProvider); + final database = getIt.get(); final cachedSource = await (database.select(database.sourceMatchTable) ..where((s) => s.trackId.equals(track.id!)) ..limit(1) @@ -287,7 +287,7 @@ class PipedSourcedTrack extends SourcedTrack { final manifest = await pipedClient.streams(newSourceInfo.id); - final database = ref.read(databaseProvider); + final database = getIt.get(); await database.into(database.sourceMatchTable).insert( SourceMatchTableCompanion.insert( trackId: id!, diff --git a/lib/services/sourced_track/sources/youtube.dart b/lib/services/sourced_track/sources/youtube.dart index 193bdc0d..08c356ce 100644 --- a/lib/services/sourced_track/sources/youtube.dart +++ b/lib/services/sourced_track/sources/youtube.dart @@ -2,8 +2,8 @@ import 'package:collection/collection.dart'; import 'package:drift/drift.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/models/database/database.dart'; -import 'package:spotube/provider/database/database.dart'; import 'package:spotube/provider/youtube_engine/youtube_engine.dart'; import 'package:spotube/services/logger/logger.dart'; import 'package:spotube/services/song_link/song_link.dart'; @@ -66,7 +66,7 @@ class YoutubeSourcedTrack extends SourcedTrack { return sourcedTrack; } - final database = ref.read(databaseProvider); + final database = getIt.get(); final cachedSource = await (database.select(database.sourceMatchTable) ..where((s) => s.trackId.equals(track.id!)) ..limit(1) @@ -261,8 +261,8 @@ class YoutubeSourcedTrack extends SourcedTrack { .where((item) => item.isNotEmpty); // Single word and duration match with 3 second tolerance if (ytWords.any((word) => spWords.contains(word)) && - (videoInfo.duration - track.duration!) - .abs().inMilliseconds <= 3000) { + (videoInfo.duration - track.duration!).abs().inMilliseconds <= + 3000) { return videoInfo; } return null; @@ -356,7 +356,7 @@ class YoutubeSourcedTrack extends SourcedTrack { .read(youtubeEngineProvider) .getStreamManifest(newSourceInfo.id); - final database = ref.read(databaseProvider); + final database = getIt.get(); await database.into(database.sourceMatchTable).insert( SourceMatchTableCompanion.insert( diff --git a/lib/utils/service_utils.dart b/lib/utils/service_utils.dart index f0eeff05..0cad8484 100644 --- a/lib/utils/service_utils.dart +++ b/lib/utils/service_utils.dart @@ -7,11 +7,12 @@ import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:html/dom.dart' hide Text; import 'package:shadcn_flutter/shadcn_flutter.dart' hide Element; import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/vars.dart'; +import 'package:spotube/models/database/database.dart'; import 'package:spotube/pages/library/user_local_tracks/user_local_tracks.dart'; import 'package:spotube/modules/root/update_dialog.dart'; import 'package:spotube/models/lyrics.dart'; -import 'package:spotube/provider/database/database.dart'; import 'package:spotube/services/dio/dio.dart'; import 'package:spotube/services/logger/logger.dart'; import 'package:spotube/services/sourced_track/sourced_track.dart'; @@ -333,7 +334,7 @@ abstract class ServiceUtils { WidgetRef ref, ) async { if (!Env.enableUpdateChecker) return; - final database = ref.read(databaseProvider); + final database = getIt.get(); final checkUpdate = await (database.selectOnly(database.preferencesTable) ..addColumns([database.preferencesTable.checkUpdate]) ..where(database.preferencesTable.id.equals(0))) diff --git a/test/drift/app_db/generated/schema_v1.dart b/test/drift/app_db/generated/schema_v1.dart index ca848561..005bc927 100644 --- a/test/drift/app_db/generated/schema_v1.dart +++ b/test/drift/app_db/generated/schema_v1.dart @@ -2,6 +2,10 @@ // GENERATED CODE, DO NOT EDIT BY HAND. // ignore_for_file: type=lint import 'package:drift/drift.dart'; +import 'package:flutter/material.dart' show ThemeMode; +import 'package:spotify/spotify.dart'; +import 'package:spotube/models/database/database.dart'; +import 'package:spotube/services/sourced_track/enums.dart'; class AuthenticationTable extends Table with TableInfo { diff --git a/test/drift/app_db/generated/schema_v2.dart b/test/drift/app_db/generated/schema_v2.dart index c9642f86..ca0bd69a 100644 --- a/test/drift/app_db/generated/schema_v2.dart +++ b/test/drift/app_db/generated/schema_v2.dart @@ -2,6 +2,10 @@ // GENERATED CODE, DO NOT EDIT BY HAND. // ignore_for_file: type=lint import 'package:drift/drift.dart'; +import 'package:flutter/material.dart' show ThemeMode; +import 'package:spotify/spotify.dart'; +import 'package:spotube/models/database/database.dart'; +import 'package:spotube/services/sourced_track/enums.dart'; class AuthenticationTable extends Table with TableInfo { diff --git a/test/drift/app_db/generated/schema_v3.dart b/test/drift/app_db/generated/schema_v3.dart index f6416823..2dd9a812 100644 --- a/test/drift/app_db/generated/schema_v3.dart +++ b/test/drift/app_db/generated/schema_v3.dart @@ -2,6 +2,10 @@ // GENERATED CODE, DO NOT EDIT BY HAND. // ignore_for_file: type=lint import 'package:drift/drift.dart'; +import 'package:flutter/material.dart' show ThemeMode; +import 'package:spotify/spotify.dart'; +import 'package:spotube/models/database/database.dart'; +import 'package:spotube/services/sourced_track/enums.dart'; class AuthenticationTable extends Table with TableInfo { diff --git a/test/drift/app_db/generated/schema_v4.dart b/test/drift/app_db/generated/schema_v4.dart index 4206abdb..4cf862c3 100644 --- a/test/drift/app_db/generated/schema_v4.dart +++ b/test/drift/app_db/generated/schema_v4.dart @@ -2,6 +2,10 @@ // GENERATED CODE, DO NOT EDIT BY HAND. // ignore_for_file: type=lint import 'package:drift/drift.dart'; +import 'package:flutter/material.dart' show ThemeMode; +import 'package:spotify/spotify.dart'; +import 'package:spotube/models/database/database.dart'; +import 'package:spotube/services/sourced_track/enums.dart'; class AuthenticationTable extends Table with TableInfo { diff --git a/test/drift/app_db/generated/schema_v5.dart b/test/drift/app_db/generated/schema_v5.dart index 4283aa98..f5cd095d 100644 --- a/test/drift/app_db/generated/schema_v5.dart +++ b/test/drift/app_db/generated/schema_v5.dart @@ -2,6 +2,10 @@ // GENERATED CODE, DO NOT EDIT BY HAND. // ignore_for_file: type=lint import 'package:drift/drift.dart'; +import 'package:flutter/material.dart' show ThemeMode; +import 'package:spotify/spotify.dart'; +import 'package:spotube/models/database/database.dart'; +import 'package:spotube/services/sourced_track/enums.dart'; class AuthenticationTable extends Table with TableInfo { diff --git a/test/drift/app_db/migration_test.dart b/test/drift/app_db/migration_test.dart index cdf646e9..a89789bb 100644 --- a/test/drift/app_db/migration_test.dart +++ b/test/drift/app_db/migration_test.dart @@ -20,13 +20,13 @@ void main() { // These simple tests verify all possible schema updates with a simple (no // data) migration. This is a quick way to ensure that written database // migrations properly alter the schema. - final versions = GeneratedHelper.versions; + const versions = GeneratedHelper.versions; for (final (i, fromVersion) in versions.indexed) { group('from $fromVersion', () { for (final toVersion in versions.skip(i + 1)) { test('to $toVersion', () async { final schema = await verifier.schemaAt(fromVersion); - final db = Database(schema.newConnection()); + final db = AppDatabase(schema.newConnection()); await verifier.migrateAndValidate(db, toVersion); await db.close(); }); diff --git a/test/providers/mocks/audio_player_listeners_mock.dart b/test/providers/mocks/audio_player_listeners_mock.dart deleted file mode 100644 index 300e411f..00000000 --- a/test/providers/mocks/audio_player_listeners_mock.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:mocktail/mocktail.dart'; -import 'package:spotube/provider/audio_player/audio_player_streams.dart'; - -class MockAudioPlayerStreamListeners extends Mock - implements AudioPlayerStreamListeners {} diff --git a/test/providers/mocks/audio_player_mock.dart b/test/providers/mocks/audio_player_mock.dart new file mode 100644 index 00000000..2b0a82f3 --- /dev/null +++ b/test/providers/mocks/audio_player_mock.dart @@ -0,0 +1,6 @@ +part of 'mocks.dart'; + +class MockAudioPlayerStreamListeners extends Mock + implements AudioPlayerStreamListeners {} + +class MockSpotubeAudioPlayer extends Mock implements SpotubeAudioPlayer {} diff --git a/test/providers/mocks/kv_store_mock.dart b/test/providers/mocks/kv_store_mock.dart new file mode 100644 index 00000000..e04c53be --- /dev/null +++ b/test/providers/mocks/kv_store_mock.dart @@ -0,0 +1,3 @@ +part of 'mocks.dart'; + +class MockKVStoreService extends Mock implements KVStoreService {} diff --git a/test/providers/mocks/mocks.dart b/test/providers/mocks/mocks.dart new file mode 100644 index 00000000..ac30b96d --- /dev/null +++ b/test/providers/mocks/mocks.dart @@ -0,0 +1,12 @@ +library mocks; + +import 'package:mocktail/mocktail.dart'; +import 'package:window_manager/window_manager.dart'; + +import 'package:spotube/services/kv_store/kv_store.dart'; +import 'package:spotube/provider/audio_player/audio_player_streams.dart'; +import 'package:spotube/services/audio_player/audio_player.dart'; + +part 'audio_player_mock.dart'; +part 'kv_store_mock.dart'; +part 'window_manager_mock.dart'; diff --git a/test/providers/mocks/window_manager_mock.dart b/test/providers/mocks/window_manager_mock.dart index a1ac0e34..b82cd97e 100644 --- a/test/providers/mocks/window_manager_mock.dart +++ b/test/providers/mocks/window_manager_mock.dart @@ -1,4 +1,3 @@ -import 'package:mocktail/mocktail.dart'; -import 'package:window_manager/window_manager.dart'; +part of 'mocks.dart'; class MockWindowManager extends Mock implements WindowManager {} diff --git a/test/providers/user_preferences/user_preferences_test.dart b/test/providers/user_preferences/user_preferences_test.dart index 3e884fa8..999cd8ee 100644 --- a/test/providers/user_preferences/user_preferences_test.dart +++ b/test/providers/user_preferences/user_preferences_test.dart @@ -4,88 +4,92 @@ import 'package:drift/native.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:mocktail/mocktail.dart'; +import 'package:spotube/collections/vars.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/provider/audio_player/audio_player_streams.dart'; -import 'package:spotube/provider/database/database.dart'; import 'package:spotube/provider/user_preferences/default_download_dir_provider.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; -import 'package:spotube/provider/window_manager/window_manager.dart'; +import 'package:spotube/services/audio_player/audio_player.dart'; +import 'package:spotube/services/kv_store/kv_store.dart'; import 'package:spotube/services/logger/logger.dart'; import 'package:window_manager/window_manager.dart'; import '../create_container.dart'; -import '../mocks/audio_player_listeners_mock.dart'; -import '../mocks/window_manager_mock.dart'; - -List _createDefaultOverrides() => [ - databaseProvider.overrideWith( - (ref) { - final database = AppDatabase(NativeDatabase.memory()); - - ref.onDispose(database.close); - return database; - }, - ), - audioPlayerStreamListenersProvider.overrideWith( - (ref) { - final streamListeners = MockAudioPlayerStreamListeners(); - - when(() => streamListeners.updatePalette()).thenReturn( - Future.value(), - ); - - return streamListeners; - }, - ), - defaultDownloadDirectoryProvider.overrideWith( - (ref) { - return Future.value("/storage/emulated/0/Download/Spotube"); - }, - ) - ]; +import '../mocks/mocks.dart'; void main() { group('UserPreferences', () { + TestWidgetsFlutterBinding.ensureInitialized(); + late ProviderContainer container; + late MockWindowManager mockWindowManager; + setUpAll(() { registerFallbackValue(TitleBarStyle.normal); AppLogger.initialize(false); }); - test('Initial value should be equal the default values', () { - final ref = createContainer(overrides: _createDefaultOverrides()); + setUp(() { + mockWindowManager = MockWindowManager(); - final preferences = ref.read(userPreferencesProvider); + getIt.registerSingleton(MockSpotubeAudioPlayer()); + getIt.registerSingleton(MockKVStoreService()); + getIt.registerSingleton(mockWindowManager); + getIt.registerLazySingleton( + () { + final database = AppDatabase(NativeDatabase.memory()); + + addTearDown(() { + database.close(); + }); + + return database; + }, + ); + + container = createContainer( + overrides: [ + audioPlayerStreamListenersProvider.overrideWith( + (ref) { + final streamListeners = MockAudioPlayerStreamListeners(); + + return streamListeners; + }, + ), + defaultDownloadDirectoryProvider.overrideWith( + (ref) { + return Future.value("/storage/emulated/0/Download/Spotube"); + }, + ), + ], + ); + + when(() => mockWindowManager.setTitleBarStyle(any())) + .thenAnswer((_) async {}); + }); + + tearDown(() { + getIt.reset(); + }); + + test('Initial value should be equal the default values', () { + final preferences = container.read(userPreferencesProvider); final defaultPreferences = PreferencesTable.defaults(); expect(preferences, defaultPreferences); }); - test('[setSystemTitleBar] should update UI titlebar', () async { - TestWidgetsFlutterBinding.ensureInitialized(); + test('setSystemTitleBar should update UI titlebar', () async { + when(() => audioPlayer.setAudioNormalization(any())) + .thenAnswer((_) async {}); - final ref = createContainer(overrides: [ - ..._createDefaultOverrides(), - windowManagerProvider.overrideWith( - (ref) { - final mockWindowManager = MockWindowManager(); - - when(() => mockWindowManager.setTitleBarStyle(any())) - .thenAnswer((_) => Future.value()); - - return mockWindowManager; - }, - ) - ]); - - final db = ref.read(databaseProvider); - final preferences = ref.read(userPreferencesProvider); + final db = getIt.get(); + final preferences = container.read(userPreferencesProvider); await Future.delayed(const Duration(milliseconds: 300)); - final preferencesNotifier = ref.read(userPreferencesProvider.notifier); + final preferencesNotifier = + container.read(userPreferencesProvider.notifier); expect(preferences.systemTitleBar, false); - await preferencesNotifier.setSystemTitleBar(true); - final completer = Completer(); final subscription = (db.select(db.preferencesTable) ..where((tbl) => tbl.id.equals(0))) @@ -98,14 +102,11 @@ void main() { subscription.cancel(); }); - final systemTitleBar = await completer.future; + preferencesNotifier.setSystemTitleBar(true); - expect(systemTitleBar, true); - verify( - () => ref - .read(windowManagerProvider) - .setTitleBarStyle(TitleBarStyle.normal), - ).called(1); + await expectLater(completer.future, completion(equals(true))); + verify(() => mockWindowManager.setTitleBarStyle(TitleBarStyle.hidden)) + .called(1); }); }); } diff --git a/test/providers/volume_provider_test.dart b/test/providers/volume_provider_test.dart index 0254d91e..79334f11 100644 --- a/test/providers/volume_provider_test.dart +++ b/test/providers/volume_provider_test.dart @@ -6,9 +6,7 @@ import 'package:spotube/provider/volume_provider.dart'; import 'package:spotube/services/audio_player/audio_player.dart'; import 'package:spotube/services/kv_store/kv_store.dart'; -class MockSpotubeAudioPlayer extends Mock implements SpotubeAudioPlayer {} - -class MockKVStoreService extends Mock implements KVStoreService {} +import 'mocks/mocks.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized();