From 24a2294512bb0c4aff77bc8dcad9b4de3e8b45c6 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 8 Dec 2023 13:27:31 +0600 Subject: [PATCH] feat: toggle for discord rpc --- lib/collections/spotube_icons.dart | 1 + lib/l10n/app_en.arb | 3 +- lib/pages/settings/sections/desktop.dart | 8 +++ lib/provider/discord_provider.dart | 70 +++++++++++++++++++ .../proxy_playlist_provider.dart | 3 +- .../user_preferences_provider.dart | 4 ++ .../user_preferences_state.dart | 6 ++ .../user_preferences_state.g.dart | 2 + lib/services/discord/discord.dart | 44 ------------ untranslated_messages.json | 45 ++++++++---- 10 files changed, 125 insertions(+), 61 deletions(-) create mode 100644 lib/provider/discord_provider.dart delete mode 100644 lib/services/discord/discord.dart diff --git a/lib/collections/spotube_icons.dart b/lib/collections/spotube_icons.dart index d00775c75..00010aae6 100644 --- a/lib/collections/spotube_icons.dart +++ b/lib/collections/spotube_icons.dart @@ -108,4 +108,5 @@ abstract class SpotubeIcons { static const noEye = FeatherIcons.eyeOff; static const normalize = FeatherIcons.barChart2; static const wikipedia = SimpleIcons.wikipedia; + static const discord = SimpleIcons.discord; } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 5aded7d54..859000120 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -280,5 +280,6 @@ "login": "Login", "login_with_your_lastfm": "Login with your Last.fm account", "scrobble_to_lastfm": "Scrobble to Last.fm", - "go_to_album": "Go to Album" + "go_to_album": "Go to Album", + "discord_rich_presence": "Discord Rich Presence" } \ No newline at end of file diff --git a/lib/pages/settings/sections/desktop.dart b/lib/pages/settings/sections/desktop.dart index 41d6d61ef..ae721fc48 100644 --- a/lib/pages/settings/sections/desktop.dart +++ b/lib/pages/settings/sections/desktop.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_desktop_tools/flutter_desktop_tools.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/settings/section_card_with_heading.dart'; @@ -50,6 +51,13 @@ class SettingsDesktopSection extends HookConsumerWidget { value: preferences.systemTitleBar, onChanged: preferencesNotifier.setSystemTitleBar, ), + if (!DesktopTools.platform.isMacOS) + SwitchListTile( + secondary: const Icon(SpotubeIcons.discord), + title: Text(context.l10n.discord_rich_presence), + value: preferences.discordPresence, + onChanged: preferencesNotifier.setDiscordPresence, + ), ], ); } diff --git a/lib/provider/discord_provider.dart b/lib/provider/discord_provider.dart new file mode 100644 index 000000000..3aa547a94 --- /dev/null +++ b/lib/provider/discord_provider.dart @@ -0,0 +1,70 @@ +import 'package:dart_discord_rpc/dart_discord_rpc.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_desktop_tools/flutter_desktop_tools.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:spotify/spotify.dart'; +import 'package:spotube/collections/env.dart'; +import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; +import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; +import 'package:spotube/utils/type_conversion_utils.dart'; + +class Discord extends ChangeNotifier { + final DiscordRPC? discordRPC; + final bool isEnabled; + + Discord(this.isEnabled) + : discordRPC = (DesktopTools.platform.isWindows || + DesktopTools.platform.isLinux) && + isEnabled + ? DiscordRPC(applicationId: Env.discordAppId) + : null { + discordRPC?.start(autoRegister: true); + } + + void updatePresence(Track track) { + clear(); + final artistNames = + TypeConversionUtils.artists_X_String(track.artists ?? []); + discordRPC?.updatePresence( + DiscordPresence( + details: "Song: ${track.name} by $artistNames", + state: "Vibing in Music", + startTimeStamp: DateTime.now().millisecondsSinceEpoch, + largeImageKey: "spotube-logo-foreground", + largeImageText: "Spotube", + smallImageKey: "spotube-logo-foreground", + smallImageText: "Spotube", + ), + ); + } + + void clear() { + discordRPC?.clearPresence(); + } + + void shutdown() { + discordRPC?.shutDown(); + } + + @override + void dispose() { + clear(); + shutdown(); + super.dispose(); + } +} + +final discordProvider = ChangeNotifierProvider( + (ref) { + final isEnabled = + ref.watch(userPreferencesProvider.select((s) => s.discordPresence)); + final playback = ref.read(ProxyPlaylistNotifier.provider); + final discord = Discord(isEnabled); + + if (playback.activeTrack != null) { + discord.updatePresence(playback.activeTrack!); + } + + return discord; + }, +); diff --git a/lib/provider/proxy_playlist/proxy_playlist_provider.dart b/lib/provider/proxy_playlist/proxy_playlist_provider.dart index 849439932..ca0fb3081 100644 --- a/lib/provider/proxy_playlist/proxy_playlist_provider.dart +++ b/lib/provider/proxy_playlist/proxy_playlist_provider.dart @@ -24,7 +24,7 @@ import 'package:spotube/provider/user_preferences/user_preferences_provider.dart import 'package:spotube/provider/user_preferences/user_preferences_state.dart'; import 'package:spotube/services/audio_player/audio_player.dart'; import 'package:spotube/services/audio_services/audio_services.dart'; -import 'package:spotube/services/discord/discord.dart'; +import 'package:spotube/provider/discord_provider.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/sourced_track.dart'; @@ -64,6 +64,7 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier ProxyPlaylist get playlist => state; BlackListNotifier get blacklist => ref.read(BlackListNotifier.provider.notifier); + Discord get discord => ref.read(discordProvider); static final provider = StateNotifierProvider( diff --git a/lib/provider/user_preferences/user_preferences_provider.dart b/lib/provider/user_preferences/user_preferences_provider.dart index 88a0df2ee..46569269a 100644 --- a/lib/provider/user_preferences/user_preferences_provider.dart +++ b/lib/provider/user_preferences/user_preferences_provider.dart @@ -110,6 +110,10 @@ class UserPreferencesNotifier extends PersistedStateNotifier { } } + void setDiscordPresence(bool discordPresence) { + state = state.copyWith(discordPresence: discordPresence); + } + void setAmoledDarkTheme(bool isAmoled) { state = state.copyWith(amoledDarkTheme: isAmoled); } diff --git a/lib/provider/user_preferences/user_preferences_state.dart b/lib/provider/user_preferences/user_preferences_state.dart index b3d7fe8a9..4244ca67d 100644 --- a/lib/provider/user_preferences/user_preferences_state.dart +++ b/lib/provider/user_preferences/user_preferences_state.dart @@ -198,6 +198,9 @@ final class UserPreferences { ) final SourceCodecs downloadMusicCodec; + @JsonKey(defaultValue: true) + final bool discordPresence; + UserPreferences({ required this.audioQuality, required this.albumColorSync, @@ -219,6 +222,7 @@ final class UserPreferences { required this.audioSource, required this.streamMusicCodec, required this.downloadMusicCodec, + required this.discordPresence, }); factory UserPreferences.withDefaults() { @@ -255,6 +259,7 @@ final class UserPreferences { SourceCodecs? downloadMusicCodec, SourceCodecs? streamMusicCodec, bool? systemTitleBar, + bool? discordPresence, }) { return UserPreferences( themeMode: themeMode ?? this.themeMode, @@ -277,6 +282,7 @@ final class UserPreferences { normalizeAudio: normalizeAudio ?? this.normalizeAudio, streamMusicCodec: streamMusicCodec ?? this.streamMusicCodec, systemTitleBar: systemTitleBar ?? this.systemTitleBar, + discordPresence: discordPresence ?? this.discordPresence, ); } } diff --git a/lib/provider/user_preferences/user_preferences_state.g.dart b/lib/provider/user_preferences/user_preferences_state.g.dart index 54cd3aa2d..59043601b 100644 --- a/lib/provider/user_preferences/user_preferences_state.g.dart +++ b/lib/provider/user_preferences/user_preferences_state.g.dart @@ -63,6 +63,7 @@ UserPreferences _$UserPreferencesFromJson(Map json) => _$SourceCodecsEnumMap, json['downloadMusicCodec'], unknownValue: SourceCodecs.m4a) ?? SourceCodecs.m4a, + discordPresence: json['discordPresence'] as bool? ?? true, ); Map _$UserPreferencesToJson(UserPreferences instance) => @@ -88,6 +89,7 @@ Map _$UserPreferencesToJson(UserPreferences instance) => 'audioSource': _$AudioSourceEnumMap[instance.audioSource]!, 'streamMusicCodec': _$SourceCodecsEnumMap[instance.streamMusicCodec]!, 'downloadMusicCodec': _$SourceCodecsEnumMap[instance.downloadMusicCodec]!, + 'discordPresence': instance.discordPresence, }; const _$SourceQualitiesEnumMap = { diff --git a/lib/services/discord/discord.dart b/lib/services/discord/discord.dart deleted file mode 100644 index 2a40e388d..000000000 --- a/lib/services/discord/discord.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:dart_discord_rpc/dart_discord_rpc.dart'; -import 'package:flutter_desktop_tools/flutter_desktop_tools.dart'; -import 'package:spotify/spotify.dart'; -import 'package:spotube/collections/env.dart'; -import 'package:spotube/utils/type_conversion_utils.dart'; - -class Discord { - final DiscordRPC? discordRPC; - - Discord() - : discordRPC = - DesktopTools.platform.isWindows || DesktopTools.platform.isLinux - ? DiscordRPC(applicationId: Env.discordAppId) - : null { - discordRPC?.start(autoRegister: true); - } - - void updatePresence(Track track) { - clear(); - final artistNames = - TypeConversionUtils.artists_X_String(track.artists ?? []); - discordRPC?.updatePresence( - DiscordPresence( - details: "Song: ${track.name} by $artistNames", - state: "Vibing in Music", - startTimeStamp: DateTime.now().millisecondsSinceEpoch, - largeImageKey: "spotube-logo-foreground", - largeImageText: "Spotube", - smallImageKey: "spotube-logo-foreground", - smallImageText: "Spotube", - ), - ); - } - - void clear() { - discordRPC?.clearPresence(); - } - - void shutdown() { - discordRPC?.shutDown(); - } -} - -final discord = Discord(); diff --git a/untranslated_messages.json b/untranslated_messages.json index 0130c162c..e3bdc0478 100644 --- a/untranslated_messages.json +++ b/untranslated_messages.json @@ -1,61 +1,76 @@ { "ar": [ - "go_to_album" + "go_to_album", + "discord_rich_presence" ], "bn": [ - "go_to_album" + "go_to_album", + "discord_rich_presence" ], "ca": [ - "go_to_album" + "go_to_album", + "discord_rich_presence" ], "de": [ - "go_to_album" + "go_to_album", + "discord_rich_presence" ], "es": [ - "go_to_album" + "go_to_album", + "discord_rich_presence" ], "fa": [ - "go_to_album" + "go_to_album", + "discord_rich_presence" ], "fr": [ - "go_to_album" + "go_to_album", + "discord_rich_presence" ], "hi": [ - "go_to_album" + "go_to_album", + "discord_rich_presence" ], "ja": [ - "go_to_album" + "go_to_album", + "discord_rich_presence" ], "pl": [ - "go_to_album" + "go_to_album", + "discord_rich_presence" ], "pt": [ - "go_to_album" + "go_to_album", + "discord_rich_presence" ], "ru": [ - "go_to_album" + "go_to_album", + "discord_rich_presence" ], "tr": [ - "go_to_album" + "go_to_album", + "discord_rich_presence" ], "uk": [ - "go_to_album" + "go_to_album", + "discord_rich_presence" ], "zh": [ - "go_to_album" + "go_to_album", + "discord_rich_presence" ] }