mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00

* feat: add youtube engine abstraction and yt-dlp integration * chore: add yt-dlp as optional dependency * feat: implement custom path support for youtube engines * chore: check for custom path in setting engine select dropdown * chore: update yt_dlp_dart * chore: setting video url instead of video id in fetchSiblings * feat: implement NewPipe engine * chore: update local path to git url for flutter_new_pipe_extractor package * chore: fix android build isn't working * chore: fix routes not working when initially signing in * refactor: drop fallback support to different sources
252 lines
7.3 KiB
Dart
252 lines
7.3 KiB
Dart
import 'package:drift/drift.dart';
|
|
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
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/models/database/database.dart';
|
|
import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart';
|
|
import 'package:spotube/provider/database/database.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';
|
|
import 'package:spotube/utils/platform.dart';
|
|
import 'package:window_manager/window_manager.dart';
|
|
import 'package:open_file/open_file.dart';
|
|
|
|
typedef UserPreferences = PreferencesTableData;
|
|
|
|
class UserPreferencesNotifier extends Notifier<PreferencesTableData> {
|
|
@override
|
|
build() {
|
|
final db = ref.watch(databaseProvider);
|
|
|
|
(db.select(db.preferencesTable)..where((tbl) => tbl.id.equals(0)))
|
|
.getSingleOrNull()
|
|
.then((result) async {
|
|
if (result == null) {
|
|
await db.into(db.preferencesTable).insert(
|
|
PreferencesTableCompanion.insert(
|
|
id: const Value(0),
|
|
downloadLocation: Value(await _getDefaultDownloadDirectory()),
|
|
),
|
|
);
|
|
}
|
|
|
|
state = await (db.select(db.preferencesTable)
|
|
..where((tbl) => tbl.id.equals(0)))
|
|
.getSingle();
|
|
|
|
final subscription = (db.select(db.preferencesTable)
|
|
..where((tbl) => tbl.id.equals(0)))
|
|
.watchSingle()
|
|
.listen((event) async {
|
|
try {
|
|
state = event;
|
|
|
|
if (kIsDesktop) {
|
|
await windowManager.setTitleBarStyle(
|
|
state.systemTitleBar
|
|
? TitleBarStyle.normal
|
|
: TitleBarStyle.hidden,
|
|
);
|
|
}
|
|
|
|
await audioPlayer.setAudioNormalization(state.normalizeAudio);
|
|
} catch (e, stack) {
|
|
AppLogger.reportError(e, stack);
|
|
}
|
|
});
|
|
|
|
ref.onDispose(() {
|
|
subscription.cancel();
|
|
});
|
|
});
|
|
|
|
return PreferencesTable.defaults();
|
|
}
|
|
|
|
Future<String> _getDefaultDownloadDirectory() async {
|
|
if (kIsAndroid) return "/storage/emulated/0/Download/Spotube";
|
|
|
|
if (kIsMacOS) {
|
|
return join((await paths.getLibraryDirectory()).path, "Caches");
|
|
}
|
|
|
|
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)..where((t) => t.id.equals(0));
|
|
|
|
await query.replace(PreferencesTableCompanion.insert());
|
|
}
|
|
|
|
static Future<String> getMusicCacheDir() async {
|
|
if (kIsAndroid) {
|
|
final dir =
|
|
await paths.getExternalCacheDirectories().then((dirs) => dirs!.first);
|
|
if (!await dir.exists()) {
|
|
await dir.create(recursive: true);
|
|
}
|
|
return join(dir.path, 'Cached Tracks');
|
|
}
|
|
|
|
final dir = await paths.getApplicationCacheDirectory();
|
|
return join(dir.path, 'cached_tracks');
|
|
}
|
|
|
|
Future<void> openCacheFolder() async {
|
|
try {
|
|
final filePath = await getMusicCacheDir();
|
|
|
|
await OpenFile.open(filePath);
|
|
} catch (e, stack) {
|
|
AppLogger.reportError(e, stack);
|
|
}
|
|
}
|
|
|
|
void setStreamMusicCodec(SourceCodecs codec) {
|
|
setData(PreferencesTableCompanion(streamMusicCodec: Value(codec)));
|
|
}
|
|
|
|
void setDownloadMusicCodec(SourceCodecs codec) {
|
|
setData(PreferencesTableCompanion(downloadMusicCodec: Value(codec)));
|
|
}
|
|
|
|
void setThemeMode(ThemeMode mode) {
|
|
setData(PreferencesTableCompanion(themeMode: Value(mode)));
|
|
}
|
|
|
|
void setRecommendationMarket(Market country) {
|
|
setData(PreferencesTableCompanion(market: Value(country)));
|
|
}
|
|
|
|
void setAccentColorScheme(SpotubeColor color) {
|
|
setData(PreferencesTableCompanion(accentColorScheme: Value(color)));
|
|
}
|
|
|
|
void setAlbumColorSync(bool sync) {
|
|
setData(PreferencesTableCompanion(albumColorSync: Value(sync)));
|
|
|
|
// if (!sync) {
|
|
// ref.read(paletteProvider.notifier).state = null;
|
|
// } else {
|
|
// ref.read(audioPlayerStreamListenersProvider).updatePalette();
|
|
// }
|
|
}
|
|
|
|
void setCheckUpdate(bool check) {
|
|
setData(PreferencesTableCompanion(checkUpdate: Value(check)));
|
|
}
|
|
|
|
void setAudioQuality(SourceQualities quality) {
|
|
setData(PreferencesTableCompanion(audioQuality: Value(quality)));
|
|
}
|
|
|
|
void setDownloadLocation(String downloadDir) {
|
|
if (downloadDir.isEmpty) return;
|
|
setData(PreferencesTableCompanion(downloadLocation: Value(downloadDir)));
|
|
}
|
|
|
|
void setLocalLibraryLocation(List<String> localLibraryDirs) {
|
|
//if (localLibraryDir.isEmpty) return;
|
|
setData(
|
|
PreferencesTableCompanion(
|
|
localLibraryLocation: Value(localLibraryDirs),
|
|
),
|
|
);
|
|
}
|
|
|
|
void setLayoutMode(LayoutMode mode) {
|
|
setData(PreferencesTableCompanion(layoutMode: Value(mode)));
|
|
}
|
|
|
|
void setCloseBehavior(CloseBehavior behavior) {
|
|
setData(PreferencesTableCompanion(closeBehavior: Value(behavior)));
|
|
}
|
|
|
|
void setShowSystemTrayIcon(bool show) {
|
|
setData(PreferencesTableCompanion(showSystemTrayIcon: Value(show)));
|
|
}
|
|
|
|
void setLocale(Locale locale) {
|
|
setData(PreferencesTableCompanion(locale: Value(locale)));
|
|
}
|
|
|
|
void setPipedInstance(String instance) {
|
|
setData(PreferencesTableCompanion(pipedInstance: Value(instance)));
|
|
}
|
|
|
|
void setInvidiousInstance(String instance) {
|
|
setData(PreferencesTableCompanion(invidiousInstance: Value(instance)));
|
|
}
|
|
|
|
void setSearchMode(SearchMode mode) {
|
|
setData(PreferencesTableCompanion(searchMode: Value(mode)));
|
|
}
|
|
|
|
void setSkipNonMusic(bool skip) {
|
|
setData(PreferencesTableCompanion(skipNonMusic: Value(skip)));
|
|
}
|
|
|
|
void setAudioSource(AudioSource type) {
|
|
setData(PreferencesTableCompanion(audioSource: Value(type)));
|
|
}
|
|
|
|
void setYoutubeClientEngine(YoutubeClientEngine engine) {
|
|
setData(PreferencesTableCompanion(youtubeClientEngine: Value(engine)));
|
|
}
|
|
|
|
void setSystemTitleBar(bool isSystemTitleBar) {
|
|
setData(
|
|
PreferencesTableCompanion(
|
|
systemTitleBar: Value(isSystemTitleBar),
|
|
),
|
|
);
|
|
}
|
|
|
|
void setDiscordPresence(bool discordPresence) {
|
|
setData(PreferencesTableCompanion(discordPresence: Value(discordPresence)));
|
|
}
|
|
|
|
void setAmoledDarkTheme(bool isAmoled) {
|
|
setData(PreferencesTableCompanion(amoledDarkTheme: Value(isAmoled)));
|
|
}
|
|
|
|
void setNormalizeAudio(bool normalize) {
|
|
setData(PreferencesTableCompanion(normalizeAudio: Value(normalize)));
|
|
audioPlayer.setAudioNormalization(normalize);
|
|
}
|
|
|
|
void setEndlessPlayback(bool endless) {
|
|
setData(PreferencesTableCompanion(endlessPlayback: Value(endless)));
|
|
}
|
|
|
|
void setEnableConnect(bool enable) {
|
|
setData(PreferencesTableCompanion(enableConnect: Value(enable)));
|
|
}
|
|
|
|
void setCacheMusic(bool cache) {
|
|
setData(PreferencesTableCompanion(cacheMusic: Value(cache)));
|
|
}
|
|
}
|
|
|
|
final userPreferencesProvider =
|
|
NotifierProvider<UserPreferencesNotifier, PreferencesTableData>(
|
|
() => UserPreferencesNotifier(),
|
|
);
|