mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
refactor: AppDatabase from provider to singleton
This commit is contained in:
parent
dcf0c62e5d
commit
937906139b
@ -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<void> main(List<String> rawArgs) async {
|
||||
() => KVStoreService.init(),
|
||||
dependsOn: [SharedPreferences],
|
||||
);
|
||||
getIt.registerLazySingleton<AppDatabase>(() => AppDatabase());
|
||||
getIt.registerSingleton(SpotubeAudioPlayer());
|
||||
getIt.registerSingleton<WindowManager>(windowManager);
|
||||
|
||||
await registerWindowsScheme("spotify");
|
||||
|
||||
@ -112,8 +112,6 @@ Future<void> main(List<String> rawArgs) async {
|
||||
|
||||
await EncryptedKvStoreService.initialize();
|
||||
|
||||
final database = AppDatabase();
|
||||
|
||||
if (kIsDesktop) {
|
||||
await localNotifier.setup(appName: "Spotube");
|
||||
await WindowManagerTools.initialize();
|
||||
@ -124,14 +122,11 @@ Future<void> main(List<String> rawArgs) async {
|
||||
}
|
||||
|
||||
runApp(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
databaseProvider.overrideWith((ref) => database),
|
||||
],
|
||||
observers: const [
|
||||
const ProviderScope(
|
||||
observers: [
|
||||
AppLoggerProviderObserver(),
|
||||
],
|
||||
child: const Spotube(),
|
||||
child: Spotube(),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
@ -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<AudioPlayerState> {
|
||||
BlackListNotifier get _blacklist => ref.read(blacklistProvider.notifier);
|
||||
|
||||
Future<void> _syncSavedState() async {
|
||||
final database = ref.read(databaseProvider);
|
||||
final database = getIt.get<AppDatabase>();
|
||||
|
||||
var playerState =
|
||||
await database.select(database.audioPlayerStateTable).getSingleOrNull();
|
||||
@ -102,7 +102,7 @@ class AudioPlayerNotifier extends Notifier<AudioPlayerState> {
|
||||
Future<void> _updatePlayerState(
|
||||
AudioPlayerStateTableCompanion companion,
|
||||
) async {
|
||||
final database = ref.read(databaseProvider);
|
||||
final database = getIt.get<AppDatabase>();
|
||||
|
||||
await (database.update(database.audioPlayerStateTable)
|
||||
..where((tb) => tb.id.equals(0)))
|
||||
@ -112,7 +112,7 @@ class AudioPlayerNotifier extends Notifier<AudioPlayerState> {
|
||||
Future<void> _updatePlaylist(
|
||||
Playlist playlist,
|
||||
) async {
|
||||
final database = ref.read(databaseProvider);
|
||||
final database = getIt.get<AppDatabase>();
|
||||
|
||||
await database.batch((batch) {
|
||||
batch.update(
|
||||
|
@ -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<AuthenticationTableData?> {
|
||||
return dio;
|
||||
}();
|
||||
|
||||
AppDatabase get database => getIt.get<AppDatabase>();
|
||||
|
||||
@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<AuthenticationTableData?> {
|
||||
}
|
||||
|
||||
Future<void> refreshCredentials() async {
|
||||
final database = ref.read(databaseProvider);
|
||||
final refreshedCredentials =
|
||||
await credentialsFromCookie(state.asData!.value!.cookie.value);
|
||||
|
||||
@ -102,7 +101,6 @@ class AuthenticationNotifier extends AsyncNotifier<AuthenticationTableData?> {
|
||||
}
|
||||
|
||||
Future<void> login(String cookie) async {
|
||||
final database = ref.read(databaseProvider);
|
||||
final refreshedCredentials = await credentialsFromCookie(cookie);
|
||||
|
||||
await database
|
||||
@ -289,7 +287,6 @@ class AuthenticationNotifier extends AsyncNotifier<AuthenticationTableData?> {
|
||||
|
||||
Future<void> logout() async {
|
||||
state = const AsyncData(null);
|
||||
final database = ref.read(databaseProvider);
|
||||
await (database.delete(database.authenticationTable)
|
||||
..where((s) => s.id.equals(0)))
|
||||
.go();
|
||||
|
@ -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<List<BlacklistTableData>> {
|
||||
AppDatabase get db => getIt.get<AppDatabase>();
|
||||
|
||||
@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<List<BlacklistTableData>> {
|
||||
subscription.cancel();
|
||||
});
|
||||
|
||||
return await database.select(database.blacklistTable).get();
|
||||
return await db.select(db.blacklistTable).get();
|
||||
}
|
||||
|
||||
AppDatabase get _database => ref.read(databaseProvider);
|
||||
|
||||
Future<void> add(BlacklistTableCompanion element) async {
|
||||
_database.into(_database.blacklistTable).insert(element);
|
||||
db.into(db.blacklistTable).insert(element);
|
||||
}
|
||||
|
||||
Future<void> remove(String elementId) async {
|
||||
await (_database.delete(_database.blacklistTable)
|
||||
await (db.delete(db.blacklistTable)
|
||||
..where((tbl) => tbl.elementId.equals(elementId)))
|
||||
.go();
|
||||
}
|
||||
|
@ -1,4 +0,0 @@
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:spotube/models/database/database.dart';
|
||||
|
||||
final databaseProvider = Provider((ref) => AppDatabase());
|
@ -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<AppDatabase>();
|
||||
|
||||
PlaybackHistoryActions(this.ref);
|
||||
|
||||
|
@ -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<List<HistoryTableData>> {
|
||||
@override
|
||||
build() async {
|
||||
final database = ref.watch(databaseProvider);
|
||||
final database = getIt.get<AppDatabase>();
|
||||
|
||||
final query = database.customSelect(
|
||||
"""
|
||||
|
@ -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<PlaybackHistorySummary> {
|
||||
@override
|
||||
build() async {
|
||||
final database = ref.watch(databaseProvider);
|
||||
final database = getIt.get<AppDatabase>();
|
||||
|
||||
final uniqItemIdCountingCol =
|
||||
database.historyTable.itemId.count(distinct: true);
|
||||
|
@ -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<AlbumSimple> createAlbumsQuery({int? limit, int? offset}) {
|
||||
final database = ref.read(databaseProvider);
|
||||
final database = getIt.get<AppDatabase>();
|
||||
|
||||
final duration = switch (arg) {
|
||||
HistoryDuration.allTime => '0',
|
||||
|
@ -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<AppDatabase>();
|
||||
|
||||
return database.select(database.historyTable)
|
||||
..where(
|
||||
|
@ -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<AppDatabase>();
|
||||
|
||||
return database.select(database.historyTable)
|
||||
..where(
|
||||
|
@ -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<Scrobblenaut?> {
|
||||
final StreamController<Track> _scrobbleController =
|
||||
StreamController<Track>.broadcast();
|
||||
AppDatabase get db => getIt.get<AppDatabase>();
|
||||
|
||||
@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<Scrobblenaut?> {
|
||||
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<Scrobblenaut?> {
|
||||
|
||||
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<Scrobblenaut?> {
|
||||
|
||||
Future<void> 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) {
|
||||
|
@ -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<List<SkipSegmentTableData>> getAndCacheSkipSegments(
|
||||
String id, Ref ref) async {
|
||||
final database = ref.read(databaseProvider);
|
||||
final database = getIt.get<AppDatabase>();
|
||||
try {
|
||||
final cached = await (database.select(database.skipSegmentTable)
|
||||
..where((s) => s.trackId.equals(id)))
|
||||
|
@ -123,7 +123,7 @@ class SyncedLyricsNotifier extends FamilyAsyncNotifier<SubtitleSimple, Track?> {
|
||||
@override
|
||||
FutureOr<SubtitleSimple> build(track) async {
|
||||
try {
|
||||
final database = ref.watch(databaseProvider);
|
||||
final database = getIt.get<AppDatabase>();
|
||||
final spotify = ref.watch(spotifyProvider);
|
||||
final auth = await ref.watch(authenticationProvider.future);
|
||||
|
||||
|
@ -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';
|
||||
|
@ -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<WindowManager>().show();
|
||||
} else {
|
||||
trayManager.popUpContextMenu();
|
||||
}
|
||||
@ -49,7 +50,7 @@ class SystemTrayManager with TrayListener {
|
||||
@override
|
||||
onTrayIconRightMouseDown() {
|
||||
if (!kIsWindows) {
|
||||
ref.read(windowManagerProvider).show();
|
||||
getIt.get<WindowManager>().show();
|
||||
} else {
|
||||
trayManager.popUpContextMenu();
|
||||
}
|
||||
|
@ -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<PlaylistMode>((ref) {
|
||||
return audioPlayer.loopModeStream;
|
||||
@ -19,7 +20,7 @@ final audioPlayerPlaying = StreamProvider<bool>((ref) {
|
||||
});
|
||||
|
||||
final trayMenuProvider = Provider((ref) {
|
||||
final windowManager = ref.watch(windowManagerProvider);
|
||||
final windowManager = getIt.get<WindowManager>();
|
||||
|
||||
final playlistNotifier = ref.watch(audioPlayerProvider.notifier);
|
||||
final isPlaybackPlaying =
|
||||
|
@ -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<PreferencesTableData> {
|
||||
AppDatabase get db => getIt.get<AppDatabase>();
|
||||
|
||||
@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<PreferencesTableData> {
|
||||
state = event;
|
||||
|
||||
if (kIsDesktop) {
|
||||
await ref.read(windowManagerProvider).setTitleBarStyle(
|
||||
await getIt.get<WindowManager>().setTitleBarStyle(
|
||||
state.systemTitleBar
|
||||
? TitleBarStyle.normal
|
||||
: TitleBarStyle.hidden,
|
||||
@ -71,29 +70,25 @@ class UserPreferencesNotifier extends Notifier<PreferencesTableData> {
|
||||
return PreferencesTable.defaults();
|
||||
}
|
||||
|
||||
Future<String> _getDefaultDownloadDirectory() async {
|
||||
if (kIsAndroid) return "/storage/emulated/0/Download/Spotube";
|
||||
// Future<String> _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<void> 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<void> reset() async {
|
||||
final db = ref.read(databaseProvider);
|
||||
|
||||
final query = db.update(db.preferencesTable);
|
||||
|
||||
await query.replace(PreferencesTableCompanion.insert(id: const Value(0)));
|
||||
|
@ -1,4 +0,0 @@
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
final windowManagerProvider = Provider((ref) => windowManager);
|
@ -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<AppDatabase>();
|
||||
|
||||
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<AppDatabase>();
|
||||
await database.into(database.sourceMatchTable).insert(
|
||||
SourceMatchTableCompanion.insert(
|
||||
trackId: id!,
|
||||
|
@ -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<AppDatabase>();
|
||||
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<AppDatabase>();
|
||||
await database.into(database.sourceMatchTable).insert(
|
||||
SourceMatchTableCompanion.insert(
|
||||
trackId: id!,
|
||||
|
@ -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<AppDatabase>();
|
||||
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<AppDatabase>();
|
||||
await database.into(database.sourceMatchTable).insert(
|
||||
SourceMatchTableCompanion.insert(
|
||||
trackId: id!,
|
||||
|
@ -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<AppDatabase>();
|
||||
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<AppDatabase>();
|
||||
|
||||
await database.into(database.sourceMatchTable).insert(
|
||||
SourceMatchTableCompanion.insert(
|
||||
|
@ -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<AppDatabase>();
|
||||
final checkUpdate = await (database.selectOnly(database.preferencesTable)
|
||||
..addColumns([database.preferencesTable.checkUpdate])
|
||||
..where(database.preferencesTable.id.equals(0)))
|
||||
|
@ -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<AuthenticationTable, AuthenticationTableData> {
|
||||
|
@ -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<AuthenticationTable, AuthenticationTableData> {
|
||||
|
@ -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<AuthenticationTable, AuthenticationTableData> {
|
||||
|
@ -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<AuthenticationTable, AuthenticationTableData> {
|
||||
|
@ -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<AuthenticationTable, AuthenticationTableData> {
|
||||
|
@ -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();
|
||||
});
|
||||
|
@ -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 {}
|
6
test/providers/mocks/audio_player_mock.dart
Normal file
6
test/providers/mocks/audio_player_mock.dart
Normal file
@ -0,0 +1,6 @@
|
||||
part of 'mocks.dart';
|
||||
|
||||
class MockAudioPlayerStreamListeners extends Mock
|
||||
implements AudioPlayerStreamListeners {}
|
||||
|
||||
class MockSpotubeAudioPlayer extends Mock implements SpotubeAudioPlayer {}
|
3
test/providers/mocks/kv_store_mock.dart
Normal file
3
test/providers/mocks/kv_store_mock.dart
Normal file
@ -0,0 +1,3 @@
|
||||
part of 'mocks.dart';
|
||||
|
||||
class MockKVStoreService extends Mock implements KVStoreService {}
|
12
test/providers/mocks/mocks.dart
Normal file
12
test/providers/mocks/mocks.dart
Normal file
@ -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';
|
@ -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 {}
|
||||
|
@ -4,36 +4,54 @@ 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';
|
||||
import '../mocks/mocks.dart';
|
||||
|
||||
List<Override> _createDefaultOverrides() => [
|
||||
databaseProvider.overrideWith(
|
||||
(ref) {
|
||||
void main() {
|
||||
group('UserPreferences', () {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
late ProviderContainer container;
|
||||
late MockWindowManager mockWindowManager;
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(TitleBarStyle.normal);
|
||||
AppLogger.initialize(false);
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
mockWindowManager = MockWindowManager();
|
||||
|
||||
getIt.registerSingleton<SpotubeAudioPlayer>(MockSpotubeAudioPlayer());
|
||||
getIt.registerSingleton<KVStoreService>(MockKVStoreService());
|
||||
getIt.registerSingleton<WindowManager>(mockWindowManager);
|
||||
getIt.registerLazySingleton(
|
||||
() {
|
||||
final database = AppDatabase(NativeDatabase.memory());
|
||||
|
||||
ref.onDispose(database.close);
|
||||
addTearDown(() {
|
||||
database.close();
|
||||
});
|
||||
|
||||
return database;
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
container = createContainer(
|
||||
overrides: [
|
||||
audioPlayerStreamListenersProvider.overrideWith(
|
||||
(ref) {
|
||||
final streamListeners = MockAudioPlayerStreamListeners();
|
||||
|
||||
when(() => streamListeners.updatePalette()).thenReturn(
|
||||
Future.value(),
|
||||
);
|
||||
|
||||
return streamListeners;
|
||||
},
|
||||
),
|
||||
@ -41,51 +59,37 @@ List<Override> _createDefaultOverrides() => [
|
||||
(ref) {
|
||||
return Future.value("/storage/emulated/0/Download/Spotube");
|
||||
},
|
||||
)
|
||||
];
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
void main() {
|
||||
group('UserPreferences', () {
|
||||
setUpAll(() {
|
||||
registerFallbackValue(TitleBarStyle.normal);
|
||||
AppLogger.initialize(false);
|
||||
when(() => mockWindowManager.setTitleBarStyle(any()))
|
||||
.thenAnswer((_) async {});
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
getIt.reset();
|
||||
});
|
||||
|
||||
test('Initial value should be equal the default values', () {
|
||||
final ref = createContainer(overrides: _createDefaultOverrides());
|
||||
|
||||
final preferences = ref.read(userPreferencesProvider);
|
||||
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<AppDatabase>();
|
||||
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<bool>();
|
||||
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);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user