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_discord_rpc/flutter_discord_rpc.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
|
||||||
|
|
||||||
import 'package:home_widget/home_widget.dart';
|
import 'package:home_widget/home_widget.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.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/models/database/database.dart';
|
||||||
import 'package:spotube/modules/settings/color_scheme_picker_dialog.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/audio_player/audio_player_streams.dart';
|
||||||
import 'package:spotube/provider/database/database.dart';
|
|
||||||
import 'package:spotube/provider/glance/glance.dart';
|
import 'package:spotube/provider/glance/glance.dart';
|
||||||
import 'package:spotube/provider/server/bonsoir.dart';
|
import 'package:spotube/provider/server/bonsoir.dart';
|
||||||
import 'package:spotube/provider/server/server.dart';
|
import 'package:spotube/provider/server/server.dart';
|
||||||
@ -73,7 +71,9 @@ Future<void> main(List<String> rawArgs) async {
|
|||||||
() => KVStoreService.init(),
|
() => KVStoreService.init(),
|
||||||
dependsOn: [SharedPreferences],
|
dependsOn: [SharedPreferences],
|
||||||
);
|
);
|
||||||
|
getIt.registerLazySingleton<AppDatabase>(() => AppDatabase());
|
||||||
getIt.registerSingleton(SpotubeAudioPlayer());
|
getIt.registerSingleton(SpotubeAudioPlayer());
|
||||||
|
getIt.registerSingleton<WindowManager>(windowManager);
|
||||||
|
|
||||||
await registerWindowsScheme("spotify");
|
await registerWindowsScheme("spotify");
|
||||||
|
|
||||||
@ -112,8 +112,6 @@ Future<void> main(List<String> rawArgs) async {
|
|||||||
|
|
||||||
await EncryptedKvStoreService.initialize();
|
await EncryptedKvStoreService.initialize();
|
||||||
|
|
||||||
final database = AppDatabase();
|
|
||||||
|
|
||||||
if (kIsDesktop) {
|
if (kIsDesktop) {
|
||||||
await localNotifier.setup(appName: "Spotube");
|
await localNotifier.setup(appName: "Spotube");
|
||||||
await WindowManagerTools.initialize();
|
await WindowManagerTools.initialize();
|
||||||
@ -124,14 +122,11 @@ Future<void> main(List<String> rawArgs) async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runApp(
|
runApp(
|
||||||
ProviderScope(
|
const ProviderScope(
|
||||||
overrides: [
|
observers: [
|
||||||
databaseProvider.overrideWith((ref) => database),
|
|
||||||
],
|
|
||||||
observers: const [
|
|
||||||
AppLoggerProviderObserver(),
|
AppLoggerProviderObserver(),
|
||||||
],
|
],
|
||||||
child: const Spotube(),
|
child: Spotube(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -4,13 +4,13 @@ import 'package:drift/drift.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:media_kit/media_kit.dart' hide Track;
|
import 'package:media_kit/media_kit.dart' hide Track;
|
||||||
import 'package:spotify/spotify.dart' hide Playlist;
|
import 'package:spotify/spotify.dart' hide Playlist;
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/extensions/list.dart';
|
import 'package:spotube/extensions/list.dart';
|
||||||
import 'package:spotube/extensions/track.dart';
|
import 'package:spotube/extensions/track.dart';
|
||||||
import 'package:spotube/models/database/database.dart';
|
import 'package:spotube/models/database/database.dart';
|
||||||
import 'package:spotube/models/local_track.dart';
|
import 'package:spotube/models/local_track.dart';
|
||||||
import 'package:spotube/provider/audio_player/state.dart';
|
import 'package:spotube/provider/audio_player/state.dart';
|
||||||
import 'package:spotube/provider/blacklist_provider.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/discord_provider.dart';
|
||||||
import 'package:spotube/provider/server/sourced_track.dart';
|
import 'package:spotube/provider/server/sourced_track.dart';
|
||||||
import 'package:spotube/services/audio_player/audio_player.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);
|
BlackListNotifier get _blacklist => ref.read(blacklistProvider.notifier);
|
||||||
|
|
||||||
Future<void> _syncSavedState() async {
|
Future<void> _syncSavedState() async {
|
||||||
final database = ref.read(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
|
|
||||||
var playerState =
|
var playerState =
|
||||||
await database.select(database.audioPlayerStateTable).getSingleOrNull();
|
await database.select(database.audioPlayerStateTable).getSingleOrNull();
|
||||||
@ -102,7 +102,7 @@ class AudioPlayerNotifier extends Notifier<AudioPlayerState> {
|
|||||||
Future<void> _updatePlayerState(
|
Future<void> _updatePlayerState(
|
||||||
AudioPlayerStateTableCompanion companion,
|
AudioPlayerStateTableCompanion companion,
|
||||||
) async {
|
) async {
|
||||||
final database = ref.read(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
|
|
||||||
await (database.update(database.audioPlayerStateTable)
|
await (database.update(database.audioPlayerStateTable)
|
||||||
..where((tb) => tb.id.equals(0)))
|
..where((tb) => tb.id.equals(0)))
|
||||||
@ -112,7 +112,7 @@ class AudioPlayerNotifier extends Notifier<AudioPlayerState> {
|
|||||||
Future<void> _updatePlaylist(
|
Future<void> _updatePlaylist(
|
||||||
Playlist playlist,
|
Playlist playlist,
|
||||||
) async {
|
) async {
|
||||||
final database = ref.read(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
|
|
||||||
await database.batch((batch) {
|
await database.batch((batch) {
|
||||||
batch.update(
|
batch.update(
|
||||||
|
@ -11,10 +11,10 @@ import 'package:flutter_inappwebview/flutter_inappwebview.dart'
|
|||||||
hide X509Certificate;
|
hide X509Certificate;
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:spotube/collections/routes.dart';
|
import 'package:spotube/collections/routes.dart';
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/components/dialogs/prompt_dialog.dart';
|
import 'package:spotube/components/dialogs/prompt_dialog.dart';
|
||||||
import 'package:spotube/extensions/context.dart';
|
import 'package:spotube/extensions/context.dart';
|
||||||
import 'package:spotube/models/database/database.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/services/logger/logger.dart';
|
||||||
import 'package:spotube/utils/platform.dart';
|
import 'package:spotube/utils/platform.dart';
|
||||||
import 'package:otp_util/otp_util.dart';
|
import 'package:otp_util/otp_util.dart';
|
||||||
@ -51,10 +51,10 @@ class AuthenticationNotifier extends AsyncNotifier<AuthenticationTableData?> {
|
|||||||
return dio;
|
return dio;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
AppDatabase get database => getIt.get<AppDatabase>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
build() async {
|
build() async {
|
||||||
final database = ref.watch(databaseProvider);
|
|
||||||
|
|
||||||
final data = await (database.select(database.authenticationTable)
|
final data = await (database.select(database.authenticationTable)
|
||||||
..where((s) => s.id.equals(0)))
|
..where((s) => s.id.equals(0)))
|
||||||
.getSingleOrNull();
|
.getSingleOrNull();
|
||||||
@ -92,7 +92,6 @@ class AuthenticationNotifier extends AsyncNotifier<AuthenticationTableData?> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> refreshCredentials() async {
|
Future<void> refreshCredentials() async {
|
||||||
final database = ref.read(databaseProvider);
|
|
||||||
final refreshedCredentials =
|
final refreshedCredentials =
|
||||||
await credentialsFromCookie(state.asData!.value!.cookie.value);
|
await credentialsFromCookie(state.asData!.value!.cookie.value);
|
||||||
|
|
||||||
@ -102,7 +101,6 @@ class AuthenticationNotifier extends AsyncNotifier<AuthenticationTableData?> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> login(String cookie) async {
|
Future<void> login(String cookie) async {
|
||||||
final database = ref.read(databaseProvider);
|
|
||||||
final refreshedCredentials = await credentialsFromCookie(cookie);
|
final refreshedCredentials = await credentialsFromCookie(cookie);
|
||||||
|
|
||||||
await database
|
await database
|
||||||
@ -289,7 +287,6 @@ class AuthenticationNotifier extends AsyncNotifier<AuthenticationTableData?> {
|
|||||||
|
|
||||||
Future<void> logout() async {
|
Future<void> logout() async {
|
||||||
state = const AsyncData(null);
|
state = const AsyncData(null);
|
||||||
final database = ref.read(databaseProvider);
|
|
||||||
await (database.delete(database.authenticationTable)
|
await (database.delete(database.authenticationTable)
|
||||||
..where((s) => s.id.equals(0)))
|
..where((s) => s.id.equals(0)))
|
||||||
.go();
|
.go();
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/models/current_playlist.dart';
|
import 'package:spotube/models/current_playlist.dart';
|
||||||
import 'package:spotube/models/database/database.dart';
|
import 'package:spotube/models/database/database.dart';
|
||||||
import 'package:spotube/provider/database/database.dart';
|
|
||||||
|
|
||||||
class BlackListNotifier extends AsyncNotifier<List<BlacklistTableData>> {
|
class BlackListNotifier extends AsyncNotifier<List<BlacklistTableData>> {
|
||||||
|
AppDatabase get db => getIt.get<AppDatabase>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
build() async {
|
build() async {
|
||||||
final database = ref.watch(databaseProvider);
|
final subscription = db
|
||||||
|
.select(db.blacklistTable)
|
||||||
final subscription = database
|
|
||||||
.select(database.blacklistTable)
|
|
||||||
.watch()
|
.watch()
|
||||||
.listen((event) => state = AsyncData(event));
|
.listen((event) => state = AsyncData(event));
|
||||||
|
|
||||||
@ -19,17 +19,15 @@ class BlackListNotifier extends AsyncNotifier<List<BlacklistTableData>> {
|
|||||||
subscription.cancel();
|
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 {
|
Future<void> add(BlacklistTableCompanion element) async {
|
||||||
_database.into(_database.blacklistTable).insert(element);
|
db.into(db.blacklistTable).insert(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> remove(String elementId) async {
|
Future<void> remove(String elementId) async {
|
||||||
await (_database.delete(_database.blacklistTable)
|
await (db.delete(db.blacklistTable)
|
||||||
..where((tbl) => tbl.elementId.equals(elementId)))
|
..where((tbl) => tbl.elementId.equals(elementId)))
|
||||||
.go();
|
.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:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/models/database/database.dart';
|
import 'package:spotube/models/database/database.dart';
|
||||||
import 'package:spotube/provider/database/database.dart';
|
|
||||||
|
|
||||||
class PlaybackHistoryActions {
|
class PlaybackHistoryActions {
|
||||||
final Ref ref;
|
final Ref ref;
|
||||||
AppDatabase get _db => ref.read(databaseProvider);
|
AppDatabase get _db => getIt.get<AppDatabase>();
|
||||||
|
|
||||||
PlaybackHistoryActions(this.ref);
|
PlaybackHistoryActions(this.ref);
|
||||||
|
|
||||||
|
@ -2,13 +2,13 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/models/database/database.dart';
|
import 'package:spotube/models/database/database.dart';
|
||||||
import 'package:spotube/provider/database/database.dart';
|
|
||||||
|
|
||||||
class RecentlyPlayedItemNotifier extends AsyncNotifier<List<HistoryTableData>> {
|
class RecentlyPlayedItemNotifier extends AsyncNotifier<List<HistoryTableData>> {
|
||||||
@override
|
@override
|
||||||
build() async {
|
build() async {
|
||||||
final database = ref.watch(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
|
|
||||||
final query = database.customSelect(
|
final query = database.customSelect(
|
||||||
"""
|
"""
|
||||||
|
@ -4,8 +4,8 @@ import 'dart:convert';
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:drift/extensions/json1.dart';
|
import 'package:drift/extensions/json1.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/models/database/database.dart';
|
import 'package:spotube/models/database/database.dart';
|
||||||
import 'package:spotube/provider/database/database.dart';
|
|
||||||
|
|
||||||
class PlaybackHistorySummary {
|
class PlaybackHistorySummary {
|
||||||
final Duration duration;
|
final Duration duration;
|
||||||
@ -47,7 +47,7 @@ class PlaybackHistorySummaryNotifier
|
|||||||
extends AsyncNotifier<PlaybackHistorySummary> {
|
extends AsyncNotifier<PlaybackHistorySummary> {
|
||||||
@override
|
@override
|
||||||
build() async {
|
build() async {
|
||||||
final database = ref.watch(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
|
|
||||||
final uniqItemIdCountingCol =
|
final uniqItemIdCountingCol =
|
||||||
database.historyTable.itemId.count(distinct: true);
|
database.historyTable.itemId.count(distinct: true);
|
||||||
|
@ -4,7 +4,8 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:spotify/spotify.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/history/top.dart';
|
||||||
import 'package:spotube/provider/spotify/spotify.dart';
|
import 'package:spotube/provider/spotify/spotify.dart';
|
||||||
|
|
||||||
@ -39,7 +40,7 @@ class HistoryTopAlbumsNotifier extends FamilyPaginatedAsyncNotifier<
|
|||||||
HistoryTopAlbumsNotifier() : super();
|
HistoryTopAlbumsNotifier() : super();
|
||||||
|
|
||||||
Selectable<AlbumSimple> createAlbumsQuery({int? limit, int? offset}) {
|
Selectable<AlbumSimple> createAlbumsQuery({int? limit, int? offset}) {
|
||||||
final database = ref.read(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
|
|
||||||
final duration = switch (arg) {
|
final duration = switch (arg) {
|
||||||
HistoryDuration.allTime => '0',
|
HistoryDuration.allTime => '0',
|
||||||
|
@ -2,8 +2,8 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/models/database/database.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/history/top.dart';
|
||||||
import 'package:spotube/provider/spotify/spotify.dart';
|
import 'package:spotube/provider/spotify/spotify.dart';
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ class HistoryTopPlaylistsNotifier extends FamilyPaginatedAsyncNotifier<
|
|||||||
|
|
||||||
SimpleSelectStatement<$HistoryTableTable, HistoryTableData>
|
SimpleSelectStatement<$HistoryTableTable, HistoryTableData>
|
||||||
createPlaylistsQuery() {
|
createPlaylistsQuery() {
|
||||||
final database = ref.read(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
|
|
||||||
return database.select(database.historyTable)
|
return database.select(database.historyTable)
|
||||||
..where(
|
..where(
|
||||||
|
@ -2,8 +2,8 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/models/database/database.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/history/top.dart';
|
||||||
import 'package:spotube/provider/spotify/spotify.dart';
|
import 'package:spotube/provider/spotify/spotify.dart';
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ class HistoryTopTracksNotifier extends FamilyPaginatedAsyncNotifier<
|
|||||||
|
|
||||||
SimpleSelectStatement<$HistoryTableTable, HistoryTableData>
|
SimpleSelectStatement<$HistoryTableTable, HistoryTableData>
|
||||||
createTracksQuery() {
|
createTracksQuery() {
|
||||||
final database = ref.read(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
|
|
||||||
return database.select(database.historyTable)
|
return database.select(database.historyTable)
|
||||||
..where(
|
..where(
|
||||||
|
@ -5,24 +5,24 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||||||
import 'package:scrobblenaut/scrobblenaut.dart';
|
import 'package:scrobblenaut/scrobblenaut.dart';
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
import 'package:spotube/collections/env.dart';
|
import 'package:spotube/collections/env.dart';
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/extensions/artist_simple.dart';
|
import 'package:spotube/extensions/artist_simple.dart';
|
||||||
import 'package:spotube/models/database/database.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/services/logger/logger.dart';
|
||||||
|
|
||||||
class ScrobblerNotifier extends AsyncNotifier<Scrobblenaut?> {
|
class ScrobblerNotifier extends AsyncNotifier<Scrobblenaut?> {
|
||||||
final StreamController<Track> _scrobbleController =
|
final StreamController<Track> _scrobbleController =
|
||||||
StreamController<Track>.broadcast();
|
StreamController<Track>.broadcast();
|
||||||
|
AppDatabase get db => getIt.get<AppDatabase>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
build() async {
|
build() async {
|
||||||
final database = ref.watch(databaseProvider);
|
final loginInfo = await (db.select(db.scrobblerTable)
|
||||||
|
|
||||||
final loginInfo = await (database.select(database.scrobblerTable)
|
|
||||||
..where((t) => t.id.equals(0)))
|
..where((t) => t.id.equals(0)))
|
||||||
.getSingleOrNull();
|
.getSingleOrNull();
|
||||||
|
|
||||||
final subscription =
|
final subscription =
|
||||||
database.select(database.scrobblerTable).watch().listen((event) async {
|
db.select(db.scrobblerTable).watch().listen((event) async {
|
||||||
try {
|
try {
|
||||||
if (event.isNotEmpty) {
|
if (event.isNotEmpty) {
|
||||||
state = await AsyncValue.guard(
|
state = await AsyncValue.guard(
|
||||||
@ -83,8 +83,6 @@ class ScrobblerNotifier extends AsyncNotifier<Scrobblenaut?> {
|
|||||||
String username,
|
String username,
|
||||||
String password,
|
String password,
|
||||||
) async {
|
) async {
|
||||||
final database = ref.read(databaseProvider);
|
|
||||||
|
|
||||||
final lastFm = await LastFM.authenticate(
|
final lastFm = await LastFM.authenticate(
|
||||||
apiKey: Env.lastFmApiKey,
|
apiKey: Env.lastFmApiKey,
|
||||||
apiSecret: Env.lastFmApiSecret,
|
apiSecret: Env.lastFmApiSecret,
|
||||||
@ -94,7 +92,7 @@ class ScrobblerNotifier extends AsyncNotifier<Scrobblenaut?> {
|
|||||||
|
|
||||||
if (!lastFm.isAuth) throw Exception("Invalid credentials");
|
if (!lastFm.isAuth) throw Exception("Invalid credentials");
|
||||||
|
|
||||||
await database.into(database.scrobblerTable).insert(
|
await db.into(db.scrobblerTable).insert(
|
||||||
ScrobblerTableCompanion.insert(
|
ScrobblerTableCompanion.insert(
|
||||||
id: const Value(0),
|
id: const Value(0),
|
||||||
username: username,
|
username: username,
|
||||||
@ -105,8 +103,8 @@ class ScrobblerNotifier extends AsyncNotifier<Scrobblenaut?> {
|
|||||||
|
|
||||||
Future<void> logout() async {
|
Future<void> logout() async {
|
||||||
state = const AsyncValue.data(null);
|
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) {
|
void scrobble(Track track) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/models/database/database.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/services/logger/logger.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
@ -17,7 +17,7 @@ class SourcedSegments {
|
|||||||
|
|
||||||
Future<List<SkipSegmentTableData>> getAndCacheSkipSegments(
|
Future<List<SkipSegmentTableData>> getAndCacheSkipSegments(
|
||||||
String id, Ref ref) async {
|
String id, Ref ref) async {
|
||||||
final database = ref.read(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
try {
|
try {
|
||||||
final cached = await (database.select(database.skipSegmentTable)
|
final cached = await (database.select(database.skipSegmentTable)
|
||||||
..where((s) => s.trackId.equals(id)))
|
..where((s) => s.trackId.equals(id)))
|
||||||
|
@ -123,7 +123,7 @@ class SyncedLyricsNotifier extends FamilyAsyncNotifier<SubtitleSimple, Track?> {
|
|||||||
@override
|
@override
|
||||||
FutureOr<SubtitleSimple> build(track) async {
|
FutureOr<SubtitleSimple> build(track) async {
|
||||||
try {
|
try {
|
||||||
final database = ref.watch(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
final spotify = ref.watch(spotifyProvider);
|
final spotify = ref.watch(spotifyProvider);
|
||||||
final auth = await ref.watch(authenticationProvider.future);
|
final auth = await ref.watch(authenticationProvider.future);
|
||||||
|
|
||||||
|
@ -6,9 +6,9 @@ import 'dart:math';
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:spotube/collections/assets.gen.dart';
|
import 'package:spotube/collections/assets.gen.dart';
|
||||||
import 'package:spotube/collections/env.dart';
|
import 'package:spotube/collections/env.dart';
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/models/database/database.dart';
|
import 'package:spotube/models/database/database.dart';
|
||||||
import 'package:spotube/provider/authentication/authentication.dart';
|
import 'package:spotube/provider/authentication/authentication.dart';
|
||||||
import 'package:spotube/provider/database/database.dart';
|
|
||||||
import 'package:spotube/services/logger/logger.dart';
|
import 'package:spotube/services/logger/logger.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
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/tray_manager/tray_menu.dart';
|
||||||
import 'package:spotube/provider/user_preferences/user_preferences_provider.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:spotube/utils/platform.dart';
|
||||||
import 'package:tray_manager/tray_manager.dart';
|
import 'package:tray_manager/tray_manager.dart';
|
||||||
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
class SystemTrayManager with TrayListener {
|
class SystemTrayManager with TrayListener {
|
||||||
final Ref ref;
|
final Ref ref;
|
||||||
@ -40,7 +41,7 @@ class SystemTrayManager with TrayListener {
|
|||||||
@override
|
@override
|
||||||
onTrayIconMouseDown() {
|
onTrayIconMouseDown() {
|
||||||
if (kIsWindows) {
|
if (kIsWindows) {
|
||||||
ref.read(windowManagerProvider).show();
|
getIt.get<WindowManager>().show();
|
||||||
} else {
|
} else {
|
||||||
trayManager.popUpContextMenu();
|
trayManager.popUpContextMenu();
|
||||||
}
|
}
|
||||||
@ -49,7 +50,7 @@ class SystemTrayManager with TrayListener {
|
|||||||
@override
|
@override
|
||||||
onTrayIconRightMouseDown() {
|
onTrayIconRightMouseDown() {
|
||||||
if (!kIsWindows) {
|
if (!kIsWindows) {
|
||||||
ref.read(windowManagerProvider).show();
|
getIt.get<WindowManager>().show();
|
||||||
} else {
|
} else {
|
||||||
trayManager.popUpContextMenu();
|
trayManager.popUpContextMenu();
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
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/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:spotube/services/audio_player/audio_player.dart';
|
||||||
import 'package:media_kit/media_kit.dart' hide Track;
|
import 'package:media_kit/media_kit.dart' hide Track;
|
||||||
import 'package:tray_manager/tray_manager.dart';
|
import 'package:tray_manager/tray_manager.dart';
|
||||||
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
final audioPlayerLoopMode = StreamProvider<PlaylistMode>((ref) {
|
final audioPlayerLoopMode = StreamProvider<PlaylistMode>((ref) {
|
||||||
return audioPlayer.loopModeStream;
|
return audioPlayer.loopModeStream;
|
||||||
@ -19,7 +20,7 @@ final audioPlayerPlaying = StreamProvider<bool>((ref) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
final trayMenuProvider = Provider((ref) {
|
final trayMenuProvider = Provider((ref) {
|
||||||
final windowManager = ref.watch(windowManagerProvider);
|
final windowManager = getIt.get<WindowManager>();
|
||||||
|
|
||||||
final playlistNotifier = ref.watch(audioPlayerProvider.notifier);
|
final playlistNotifier = ref.watch(audioPlayerProvider.notifier);
|
||||||
final isPlaybackPlaying =
|
final isPlaybackPlaying =
|
||||||
|
@ -5,11 +5,10 @@ import 'package:path/path.dart';
|
|||||||
import 'package:path_provider/path_provider.dart' as paths;
|
import 'package:path_provider/path_provider.dart' as paths;
|
||||||
import 'package:shadcn_flutter/shadcn_flutter.dart' hide join;
|
import 'package:shadcn_flutter/shadcn_flutter.dart' hide join;
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/models/database/database.dart';
|
import 'package:spotube/models/database/database.dart';
|
||||||
import 'package:spotube/modules/settings/color_scheme_picker_dialog.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/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/audio_player/audio_player.dart';
|
||||||
import 'package:spotube/services/logger/logger.dart';
|
import 'package:spotube/services/logger/logger.dart';
|
||||||
import 'package:spotube/services/sourced_track/enums.dart';
|
import 'package:spotube/services/sourced_track/enums.dart';
|
||||||
@ -20,10 +19,10 @@ import 'package:open_file/open_file.dart';
|
|||||||
typedef UserPreferences = PreferencesTableData;
|
typedef UserPreferences = PreferencesTableData;
|
||||||
|
|
||||||
class UserPreferencesNotifier extends Notifier<PreferencesTableData> {
|
class UserPreferencesNotifier extends Notifier<PreferencesTableData> {
|
||||||
|
AppDatabase get db => getIt.get<AppDatabase>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
build() {
|
build() {
|
||||||
final db = ref.watch(databaseProvider);
|
|
||||||
|
|
||||||
(db.select(db.preferencesTable)..where((tbl) => tbl.id.equals(0)))
|
(db.select(db.preferencesTable)..where((tbl) => tbl.id.equals(0)))
|
||||||
.getSingleOrNull()
|
.getSingleOrNull()
|
||||||
.then((result) async {
|
.then((result) async {
|
||||||
@ -50,7 +49,7 @@ class UserPreferencesNotifier extends Notifier<PreferencesTableData> {
|
|||||||
state = event;
|
state = event;
|
||||||
|
|
||||||
if (kIsDesktop) {
|
if (kIsDesktop) {
|
||||||
await ref.read(windowManagerProvider).setTitleBarStyle(
|
await getIt.get<WindowManager>().setTitleBarStyle(
|
||||||
state.systemTitleBar
|
state.systemTitleBar
|
||||||
? TitleBarStyle.normal
|
? TitleBarStyle.normal
|
||||||
: TitleBarStyle.hidden,
|
: TitleBarStyle.hidden,
|
||||||
@ -71,29 +70,25 @@ class UserPreferencesNotifier extends Notifier<PreferencesTableData> {
|
|||||||
return PreferencesTable.defaults();
|
return PreferencesTable.defaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> _getDefaultDownloadDirectory() async {
|
// Future<String> _getDefaultDownloadDirectory() async {
|
||||||
if (kIsAndroid) return "/storage/emulated/0/Download/Spotube";
|
// if (kIsAndroid) return "/storage/emulated/0/Download/Spotube";
|
||||||
|
|
||||||
if (kIsMacOS) {
|
// if (kIsMacOS) {
|
||||||
return join((await paths.getLibraryDirectory()).path, "Caches");
|
// return join((await paths.getLibraryDirectory()).path, "Caches");
|
||||||
}
|
// }
|
||||||
|
|
||||||
return paths.getDownloadsDirectory().then((dir) {
|
// return paths.getDownloadsDirectory().then((dir) {
|
||||||
return join(dir!.path, "Spotube");
|
// return join(dir!.path, "Spotube");
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
Future<void> setData(PreferencesTableCompanion data) async {
|
Future<void> setData(PreferencesTableCompanion data) async {
|
||||||
final db = ref.read(databaseProvider);
|
|
||||||
|
|
||||||
final query = db.update(db.preferencesTable)..where((t) => t.id.equals(0));
|
final query = db.update(db.preferencesTable)..where((t) => t.id.equals(0));
|
||||||
|
|
||||||
await query.write(data);
|
await query.write(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> reset() async {
|
Future<void> reset() async {
|
||||||
final db = ref.read(databaseProvider);
|
|
||||||
|
|
||||||
final query = db.update(db.preferencesTable);
|
final query = db.update(db.preferencesTable);
|
||||||
|
|
||||||
await query.replace(PreferencesTableCompanion.insert(id: const Value(0)));
|
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:drift/drift.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/models/database/database.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/provider/user_preferences/user_preferences_provider.dart';
|
||||||
import 'package:spotube/services/sourced_track/enums.dart';
|
import 'package:spotube/services/sourced_track/enums.dart';
|
||||||
import 'package:spotube/services/sourced_track/exceptions.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)
|
final cachedSource = await (database.select(database.sourceMatchTable)
|
||||||
..where((s) => s.trackId.equals(track.id!))
|
..where((s) => s.trackId.equals(track.id!))
|
||||||
..limit(1)
|
..limit(1)
|
||||||
@ -258,7 +259,7 @@ class InvidiousSourcedTrack extends SourcedTrack {
|
|||||||
final manifest =
|
final manifest =
|
||||||
await pipedClient.videos.get(newSourceInfo.id, local: true);
|
await pipedClient.videos.get(newSourceInfo.id, local: true);
|
||||||
|
|
||||||
final database = ref.read(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
await database.into(database.sourceMatchTable).insert(
|
await database.into(database.sourceMatchTable).insert(
|
||||||
SourceMatchTableCompanion.insert(
|
SourceMatchTableCompanion.insert(
|
||||||
trackId: id!,
|
trackId: id!,
|
||||||
|
@ -2,8 +2,8 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/models/database/database.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/enums.dart';
|
||||||
import 'package:spotube/services/sourced_track/exceptions.dart';
|
import 'package:spotube/services/sourced_track/exceptions.dart';
|
||||||
import 'package:spotube/services/sourced_track/models/source_info.dart';
|
import 'package:spotube/services/sourced_track/models/source_info.dart';
|
||||||
@ -41,7 +41,7 @@ class JioSaavnSourcedTrack extends SourcedTrack {
|
|||||||
required Ref ref,
|
required Ref ref,
|
||||||
bool weakMatch = false,
|
bool weakMatch = false,
|
||||||
}) async {
|
}) async {
|
||||||
final database = ref.read(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
final cachedSource = await (database.select(database.sourceMatchTable)
|
final cachedSource = await (database.select(database.sourceMatchTable)
|
||||||
..where((s) => s.trackId.equals(track.id!))
|
..where((s) => s.trackId.equals(track.id!))
|
||||||
..limit(1)
|
..limit(1)
|
||||||
@ -214,7 +214,7 @@ class JioSaavnSourcedTrack extends SourcedTrack {
|
|||||||
|
|
||||||
final (:info, :source) = toSiblingType(item);
|
final (:info, :source) = toSiblingType(item);
|
||||||
|
|
||||||
final database = ref.read(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
await database.into(database.sourceMatchTable).insert(
|
await database.into(database.sourceMatchTable).insert(
|
||||||
SourceMatchTableCompanion.insert(
|
SourceMatchTableCompanion.insert(
|
||||||
trackId: id!,
|
trackId: id!,
|
||||||
|
@ -3,8 +3,8 @@ import 'package:drift/drift.dart';
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:piped_client/piped_client.dart';
|
import 'package:piped_client/piped_client.dart';
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/models/database/database.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/provider/user_preferences/user_preferences_provider.dart';
|
||||||
|
|
||||||
import 'package:spotube/services/sourced_track/enums.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)
|
final cachedSource = await (database.select(database.sourceMatchTable)
|
||||||
..where((s) => s.trackId.equals(track.id!))
|
..where((s) => s.trackId.equals(track.id!))
|
||||||
..limit(1)
|
..limit(1)
|
||||||
@ -287,7 +287,7 @@ class PipedSourcedTrack extends SourcedTrack {
|
|||||||
|
|
||||||
final manifest = await pipedClient.streams(newSourceInfo.id);
|
final manifest = await pipedClient.streams(newSourceInfo.id);
|
||||||
|
|
||||||
final database = ref.read(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
await database.into(database.sourceMatchTable).insert(
|
await database.into(database.sourceMatchTable).insert(
|
||||||
SourceMatchTableCompanion.insert(
|
SourceMatchTableCompanion.insert(
|
||||||
trackId: id!,
|
trackId: id!,
|
||||||
|
@ -2,8 +2,8 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/models/database/database.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/provider/youtube_engine/youtube_engine.dart';
|
||||||
import 'package:spotube/services/logger/logger.dart';
|
import 'package:spotube/services/logger/logger.dart';
|
||||||
import 'package:spotube/services/song_link/song_link.dart';
|
import 'package:spotube/services/song_link/song_link.dart';
|
||||||
@ -66,7 +66,7 @@ class YoutubeSourcedTrack extends SourcedTrack {
|
|||||||
return sourcedTrack;
|
return sourcedTrack;
|
||||||
}
|
}
|
||||||
|
|
||||||
final database = ref.read(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
final cachedSource = await (database.select(database.sourceMatchTable)
|
final cachedSource = await (database.select(database.sourceMatchTable)
|
||||||
..where((s) => s.trackId.equals(track.id!))
|
..where((s) => s.trackId.equals(track.id!))
|
||||||
..limit(1)
|
..limit(1)
|
||||||
@ -261,8 +261,8 @@ class YoutubeSourcedTrack extends SourcedTrack {
|
|||||||
.where((item) => item.isNotEmpty);
|
.where((item) => item.isNotEmpty);
|
||||||
// Single word and duration match with 3 second tolerance
|
// Single word and duration match with 3 second tolerance
|
||||||
if (ytWords.any((word) => spWords.contains(word)) &&
|
if (ytWords.any((word) => spWords.contains(word)) &&
|
||||||
(videoInfo.duration - track.duration!)
|
(videoInfo.duration - track.duration!).abs().inMilliseconds <=
|
||||||
.abs().inMilliseconds <= 3000) {
|
3000) {
|
||||||
return videoInfo;
|
return videoInfo;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -356,7 +356,7 @@ class YoutubeSourcedTrack extends SourcedTrack {
|
|||||||
.read(youtubeEngineProvider)
|
.read(youtubeEngineProvider)
|
||||||
.getStreamManifest(newSourceInfo.id);
|
.getStreamManifest(newSourceInfo.id);
|
||||||
|
|
||||||
final database = ref.read(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
|
|
||||||
await database.into(database.sourceMatchTable).insert(
|
await database.into(database.sourceMatchTable).insert(
|
||||||
SourceMatchTableCompanion.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:html/dom.dart' hide Text;
|
||||||
import 'package:shadcn_flutter/shadcn_flutter.dart' hide Element;
|
import 'package:shadcn_flutter/shadcn_flutter.dart' hide Element;
|
||||||
import 'package:spotify/spotify.dart';
|
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/pages/library/user_local_tracks/user_local_tracks.dart';
|
||||||
import 'package:spotube/modules/root/update_dialog.dart';
|
import 'package:spotube/modules/root/update_dialog.dart';
|
||||||
|
|
||||||
import 'package:spotube/models/lyrics.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/dio/dio.dart';
|
||||||
import 'package:spotube/services/logger/logger.dart';
|
import 'package:spotube/services/logger/logger.dart';
|
||||||
import 'package:spotube/services/sourced_track/sourced_track.dart';
|
import 'package:spotube/services/sourced_track/sourced_track.dart';
|
||||||
@ -333,7 +334,7 @@ abstract class ServiceUtils {
|
|||||||
WidgetRef ref,
|
WidgetRef ref,
|
||||||
) async {
|
) async {
|
||||||
if (!Env.enableUpdateChecker) return;
|
if (!Env.enableUpdateChecker) return;
|
||||||
final database = ref.read(databaseProvider);
|
final database = getIt.get<AppDatabase>();
|
||||||
final checkUpdate = await (database.selectOnly(database.preferencesTable)
|
final checkUpdate = await (database.selectOnly(database.preferencesTable)
|
||||||
..addColumns([database.preferencesTable.checkUpdate])
|
..addColumns([database.preferencesTable.checkUpdate])
|
||||||
..where(database.preferencesTable.id.equals(0)))
|
..where(database.preferencesTable.id.equals(0)))
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
// GENERATED CODE, DO NOT EDIT BY HAND.
|
// GENERATED CODE, DO NOT EDIT BY HAND.
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
import 'package:drift/drift.dart';
|
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
|
class AuthenticationTable extends Table
|
||||||
with TableInfo<AuthenticationTable, AuthenticationTableData> {
|
with TableInfo<AuthenticationTable, AuthenticationTableData> {
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
// GENERATED CODE, DO NOT EDIT BY HAND.
|
// GENERATED CODE, DO NOT EDIT BY HAND.
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
import 'package:drift/drift.dart';
|
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
|
class AuthenticationTable extends Table
|
||||||
with TableInfo<AuthenticationTable, AuthenticationTableData> {
|
with TableInfo<AuthenticationTable, AuthenticationTableData> {
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
// GENERATED CODE, DO NOT EDIT BY HAND.
|
// GENERATED CODE, DO NOT EDIT BY HAND.
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
import 'package:drift/drift.dart';
|
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
|
class AuthenticationTable extends Table
|
||||||
with TableInfo<AuthenticationTable, AuthenticationTableData> {
|
with TableInfo<AuthenticationTable, AuthenticationTableData> {
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
// GENERATED CODE, DO NOT EDIT BY HAND.
|
// GENERATED CODE, DO NOT EDIT BY HAND.
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
import 'package:drift/drift.dart';
|
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
|
class AuthenticationTable extends Table
|
||||||
with TableInfo<AuthenticationTable, AuthenticationTableData> {
|
with TableInfo<AuthenticationTable, AuthenticationTableData> {
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
// GENERATED CODE, DO NOT EDIT BY HAND.
|
// GENERATED CODE, DO NOT EDIT BY HAND.
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
import 'package:drift/drift.dart';
|
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
|
class AuthenticationTable extends Table
|
||||||
with TableInfo<AuthenticationTable, AuthenticationTableData> {
|
with TableInfo<AuthenticationTable, AuthenticationTableData> {
|
||||||
|
@ -20,13 +20,13 @@ void main() {
|
|||||||
// These simple tests verify all possible schema updates with a simple (no
|
// These simple tests verify all possible schema updates with a simple (no
|
||||||
// data) migration. This is a quick way to ensure that written database
|
// data) migration. This is a quick way to ensure that written database
|
||||||
// migrations properly alter the schema.
|
// migrations properly alter the schema.
|
||||||
final versions = GeneratedHelper.versions;
|
const versions = GeneratedHelper.versions;
|
||||||
for (final (i, fromVersion) in versions.indexed) {
|
for (final (i, fromVersion) in versions.indexed) {
|
||||||
group('from $fromVersion', () {
|
group('from $fromVersion', () {
|
||||||
for (final toVersion in versions.skip(i + 1)) {
|
for (final toVersion in versions.skip(i + 1)) {
|
||||||
test('to $toVersion', () async {
|
test('to $toVersion', () async {
|
||||||
final schema = await verifier.schemaAt(fromVersion);
|
final schema = await verifier.schemaAt(fromVersion);
|
||||||
final db = Database(schema.newConnection());
|
final db = AppDatabase(schema.newConnection());
|
||||||
await verifier.migrateAndValidate(db, toVersion);
|
await verifier.migrateAndValidate(db, toVersion);
|
||||||
await db.close();
|
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';
|
part of 'mocks.dart';
|
||||||
import 'package:window_manager/window_manager.dart';
|
|
||||||
|
|
||||||
class MockWindowManager extends Mock implements WindowManager {}
|
class MockWindowManager extends Mock implements WindowManager {}
|
||||||
|
@ -4,36 +4,54 @@ import 'package:drift/native.dart';
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:mocktail/mocktail.dart';
|
import 'package:mocktail/mocktail.dart';
|
||||||
|
import 'package:spotube/collections/vars.dart';
|
||||||
import 'package:spotube/models/database/database.dart';
|
import 'package:spotube/models/database/database.dart';
|
||||||
import 'package:spotube/provider/audio_player/audio_player_streams.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/default_download_dir_provider.dart';
|
||||||
import 'package:spotube/provider/user_preferences/user_preferences_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:spotube/services/logger/logger.dart';
|
||||||
import 'package:window_manager/window_manager.dart';
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
import '../create_container.dart';
|
import '../create_container.dart';
|
||||||
import '../mocks/audio_player_listeners_mock.dart';
|
import '../mocks/mocks.dart';
|
||||||
import '../mocks/window_manager_mock.dart';
|
|
||||||
|
|
||||||
List<Override> _createDefaultOverrides() => [
|
void main() {
|
||||||
databaseProvider.overrideWith(
|
group('UserPreferences', () {
|
||||||
(ref) {
|
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());
|
final database = AppDatabase(NativeDatabase.memory());
|
||||||
|
|
||||||
ref.onDispose(database.close);
|
addTearDown(() {
|
||||||
|
database.close();
|
||||||
|
});
|
||||||
|
|
||||||
return database;
|
return database;
|
||||||
},
|
},
|
||||||
),
|
);
|
||||||
|
|
||||||
|
container = createContainer(
|
||||||
|
overrides: [
|
||||||
audioPlayerStreamListenersProvider.overrideWith(
|
audioPlayerStreamListenersProvider.overrideWith(
|
||||||
(ref) {
|
(ref) {
|
||||||
final streamListeners = MockAudioPlayerStreamListeners();
|
final streamListeners = MockAudioPlayerStreamListeners();
|
||||||
|
|
||||||
when(() => streamListeners.updatePalette()).thenReturn(
|
|
||||||
Future.value(),
|
|
||||||
);
|
|
||||||
|
|
||||||
return streamListeners;
|
return streamListeners;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -41,51 +59,37 @@ List<Override> _createDefaultOverrides() => [
|
|||||||
(ref) {
|
(ref) {
|
||||||
return Future.value("/storage/emulated/0/Download/Spotube");
|
return Future.value("/storage/emulated/0/Download/Spotube");
|
||||||
},
|
},
|
||||||
)
|
),
|
||||||
];
|
],
|
||||||
|
);
|
||||||
|
|
||||||
void main() {
|
when(() => mockWindowManager.setTitleBarStyle(any()))
|
||||||
group('UserPreferences', () {
|
.thenAnswer((_) async {});
|
||||||
setUpAll(() {
|
});
|
||||||
registerFallbackValue(TitleBarStyle.normal);
|
|
||||||
AppLogger.initialize(false);
|
tearDown(() {
|
||||||
|
getIt.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Initial value should be equal the default values', () {
|
test('Initial value should be equal the default values', () {
|
||||||
final ref = createContainer(overrides: _createDefaultOverrides());
|
final preferences = container.read(userPreferencesProvider);
|
||||||
|
|
||||||
final preferences = ref.read(userPreferencesProvider);
|
|
||||||
final defaultPreferences = PreferencesTable.defaults();
|
final defaultPreferences = PreferencesTable.defaults();
|
||||||
|
|
||||||
expect(preferences, defaultPreferences);
|
expect(preferences, defaultPreferences);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[setSystemTitleBar] should update UI titlebar', () async {
|
test('setSystemTitleBar should update UI titlebar', () async {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
when(() => audioPlayer.setAudioNormalization(any()))
|
||||||
|
.thenAnswer((_) async {});
|
||||||
|
|
||||||
final ref = createContainer(overrides: [
|
final db = getIt.get<AppDatabase>();
|
||||||
..._createDefaultOverrides(),
|
final preferences = container.read(userPreferencesProvider);
|
||||||
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);
|
|
||||||
await Future.delayed(const Duration(milliseconds: 300));
|
await Future.delayed(const Duration(milliseconds: 300));
|
||||||
final preferencesNotifier = ref.read(userPreferencesProvider.notifier);
|
final preferencesNotifier =
|
||||||
|
container.read(userPreferencesProvider.notifier);
|
||||||
|
|
||||||
expect(preferences.systemTitleBar, false);
|
expect(preferences.systemTitleBar, false);
|
||||||
|
|
||||||
await preferencesNotifier.setSystemTitleBar(true);
|
|
||||||
|
|
||||||
final completer = Completer<bool>();
|
final completer = Completer<bool>();
|
||||||
final subscription = (db.select(db.preferencesTable)
|
final subscription = (db.select(db.preferencesTable)
|
||||||
..where((tbl) => tbl.id.equals(0)))
|
..where((tbl) => tbl.id.equals(0)))
|
||||||
@ -98,14 +102,11 @@ void main() {
|
|||||||
subscription.cancel();
|
subscription.cancel();
|
||||||
});
|
});
|
||||||
|
|
||||||
final systemTitleBar = await completer.future;
|
preferencesNotifier.setSystemTitleBar(true);
|
||||||
|
|
||||||
expect(systemTitleBar, true);
|
await expectLater(completer.future, completion(equals(true)));
|
||||||
verify(
|
verify(() => mockWindowManager.setTitleBarStyle(TitleBarStyle.hidden))
|
||||||
() => ref
|
.called(1);
|
||||||
.read(windowManagerProvider)
|
|
||||||
.setTitleBarStyle(TitleBarStyle.normal),
|
|
||||||
).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/audio_player/audio_player.dart';
|
||||||
import 'package:spotube/services/kv_store/kv_store.dart';
|
import 'package:spotube/services/kv_store/kv_store.dart';
|
||||||
|
|
||||||
class MockSpotubeAudioPlayer extends Mock implements SpotubeAudioPlayer {}
|
import 'mocks/mocks.dart';
|
||||||
|
|
||||||
class MockKVStoreService extends Mock implements KVStoreService {}
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
Loading…
Reference in New Issue
Block a user