spotube/lib/provider/user_preferences/user_preferences_provider.dart

260 lines
7.4 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);
await query.replace(PreferencesTableCompanion.insert(id: const Value(0)));
}
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 setConnectPort(int port) {
assert(
port >= -1 && port <= 65535,
"Port must be between -1 and 65535, got $port",
);
setData(PreferencesTableCompanion(connectPort: Value(port)));
}
void setCacheMusic(bool cache) {
setData(PreferencesTableCompanion(cacheMusic: Value(cache)));
}
}
final userPreferencesProvider =
NotifierProvider<UserPreferencesNotifier, PreferencesTableData>(
() => UserPreferencesNotifier(),
);