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 { @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 _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 setData(PreferencesTableCompanion data) async { final db = ref.read(databaseProvider); final query = db.update(db.preferencesTable)..where((t) => t.id.equals(0)); await query.write(data); } Future reset() async { final db = ref.read(databaseProvider); final query = db.update(db.preferencesTable)..where((t) => t.id.equals(0)); await query.replace(PreferencesTableCompanion.insert()); } static Future 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 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 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 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(), );