mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
feat: toggle for discord rpc
This commit is contained in:
parent
b92583d0df
commit
24a2294512
@ -108,4 +108,5 @@ abstract class SpotubeIcons {
|
|||||||
static const noEye = FeatherIcons.eyeOff;
|
static const noEye = FeatherIcons.eyeOff;
|
||||||
static const normalize = FeatherIcons.barChart2;
|
static const normalize = FeatherIcons.barChart2;
|
||||||
static const wikipedia = SimpleIcons.wikipedia;
|
static const wikipedia = SimpleIcons.wikipedia;
|
||||||
|
static const discord = SimpleIcons.discord;
|
||||||
}
|
}
|
||||||
|
@ -280,5 +280,6 @@
|
|||||||
"login": "Login",
|
"login": "Login",
|
||||||
"login_with_your_lastfm": "Login with your Last.fm account",
|
"login_with_your_lastfm": "Login with your Last.fm account",
|
||||||
"scrobble_to_lastfm": "Scrobble to Last.fm",
|
"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"
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_desktop_tools/flutter_desktop_tools.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:spotube/collections/spotube_icons.dart';
|
import 'package:spotube/collections/spotube_icons.dart';
|
||||||
import 'package:spotube/components/settings/section_card_with_heading.dart';
|
import 'package:spotube/components/settings/section_card_with_heading.dart';
|
||||||
@ -50,6 +51,13 @@ class SettingsDesktopSection extends HookConsumerWidget {
|
|||||||
value: preferences.systemTitleBar,
|
value: preferences.systemTitleBar,
|
||||||
onChanged: preferencesNotifier.setSystemTitleBar,
|
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,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
70
lib/provider/discord_provider.dart
Normal file
70
lib/provider/discord_provider.dart
Normal file
@ -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 ?? <Artist>[]);
|
||||||
|
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;
|
||||||
|
},
|
||||||
|
);
|
@ -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/provider/user_preferences/user_preferences_state.dart';
|
||||||
import 'package:spotube/services/audio_player/audio_player.dart';
|
import 'package:spotube/services/audio_player/audio_player.dart';
|
||||||
import 'package:spotube/services/audio_services/audio_services.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/exceptions.dart';
|
||||||
import 'package:spotube/services/sourced_track/models/source_info.dart';
|
import 'package:spotube/services/sourced_track/models/source_info.dart';
|
||||||
import 'package:spotube/services/sourced_track/sourced_track.dart';
|
import 'package:spotube/services/sourced_track/sourced_track.dart';
|
||||||
@ -64,6 +64,7 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
|
|||||||
ProxyPlaylist get playlist => state;
|
ProxyPlaylist get playlist => state;
|
||||||
BlackListNotifier get blacklist =>
|
BlackListNotifier get blacklist =>
|
||||||
ref.read(BlackListNotifier.provider.notifier);
|
ref.read(BlackListNotifier.provider.notifier);
|
||||||
|
Discord get discord => ref.read(discordProvider);
|
||||||
|
|
||||||
static final provider =
|
static final provider =
|
||||||
StateNotifierProvider<ProxyPlaylistNotifier, ProxyPlaylist>(
|
StateNotifierProvider<ProxyPlaylistNotifier, ProxyPlaylist>(
|
||||||
|
@ -110,6 +110,10 @@ class UserPreferencesNotifier extends PersistedStateNotifier<UserPreferences> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setDiscordPresence(bool discordPresence) {
|
||||||
|
state = state.copyWith(discordPresence: discordPresence);
|
||||||
|
}
|
||||||
|
|
||||||
void setAmoledDarkTheme(bool isAmoled) {
|
void setAmoledDarkTheme(bool isAmoled) {
|
||||||
state = state.copyWith(amoledDarkTheme: isAmoled);
|
state = state.copyWith(amoledDarkTheme: isAmoled);
|
||||||
}
|
}
|
||||||
|
@ -198,6 +198,9 @@ final class UserPreferences {
|
|||||||
)
|
)
|
||||||
final SourceCodecs downloadMusicCodec;
|
final SourceCodecs downloadMusicCodec;
|
||||||
|
|
||||||
|
@JsonKey(defaultValue: true)
|
||||||
|
final bool discordPresence;
|
||||||
|
|
||||||
UserPreferences({
|
UserPreferences({
|
||||||
required this.audioQuality,
|
required this.audioQuality,
|
||||||
required this.albumColorSync,
|
required this.albumColorSync,
|
||||||
@ -219,6 +222,7 @@ final class UserPreferences {
|
|||||||
required this.audioSource,
|
required this.audioSource,
|
||||||
required this.streamMusicCodec,
|
required this.streamMusicCodec,
|
||||||
required this.downloadMusicCodec,
|
required this.downloadMusicCodec,
|
||||||
|
required this.discordPresence,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory UserPreferences.withDefaults() {
|
factory UserPreferences.withDefaults() {
|
||||||
@ -255,6 +259,7 @@ final class UserPreferences {
|
|||||||
SourceCodecs? downloadMusicCodec,
|
SourceCodecs? downloadMusicCodec,
|
||||||
SourceCodecs? streamMusicCodec,
|
SourceCodecs? streamMusicCodec,
|
||||||
bool? systemTitleBar,
|
bool? systemTitleBar,
|
||||||
|
bool? discordPresence,
|
||||||
}) {
|
}) {
|
||||||
return UserPreferences(
|
return UserPreferences(
|
||||||
themeMode: themeMode ?? this.themeMode,
|
themeMode: themeMode ?? this.themeMode,
|
||||||
@ -277,6 +282,7 @@ final class UserPreferences {
|
|||||||
normalizeAudio: normalizeAudio ?? this.normalizeAudio,
|
normalizeAudio: normalizeAudio ?? this.normalizeAudio,
|
||||||
streamMusicCodec: streamMusicCodec ?? this.streamMusicCodec,
|
streamMusicCodec: streamMusicCodec ?? this.streamMusicCodec,
|
||||||
systemTitleBar: systemTitleBar ?? this.systemTitleBar,
|
systemTitleBar: systemTitleBar ?? this.systemTitleBar,
|
||||||
|
discordPresence: discordPresence ?? this.discordPresence,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,7 @@ UserPreferences _$UserPreferencesFromJson(Map<String, dynamic> json) =>
|
|||||||
_$SourceCodecsEnumMap, json['downloadMusicCodec'],
|
_$SourceCodecsEnumMap, json['downloadMusicCodec'],
|
||||||
unknownValue: SourceCodecs.m4a) ??
|
unknownValue: SourceCodecs.m4a) ??
|
||||||
SourceCodecs.m4a,
|
SourceCodecs.m4a,
|
||||||
|
discordPresence: json['discordPresence'] as bool? ?? true,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$UserPreferencesToJson(UserPreferences instance) =>
|
Map<String, dynamic> _$UserPreferencesToJson(UserPreferences instance) =>
|
||||||
@ -88,6 +89,7 @@ Map<String, dynamic> _$UserPreferencesToJson(UserPreferences instance) =>
|
|||||||
'audioSource': _$AudioSourceEnumMap[instance.audioSource]!,
|
'audioSource': _$AudioSourceEnumMap[instance.audioSource]!,
|
||||||
'streamMusicCodec': _$SourceCodecsEnumMap[instance.streamMusicCodec]!,
|
'streamMusicCodec': _$SourceCodecsEnumMap[instance.streamMusicCodec]!,
|
||||||
'downloadMusicCodec': _$SourceCodecsEnumMap[instance.downloadMusicCodec]!,
|
'downloadMusicCodec': _$SourceCodecsEnumMap[instance.downloadMusicCodec]!,
|
||||||
|
'discordPresence': instance.discordPresence,
|
||||||
};
|
};
|
||||||
|
|
||||||
const _$SourceQualitiesEnumMap = {
|
const _$SourceQualitiesEnumMap = {
|
||||||
|
@ -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 ?? <Artist>[]);
|
|
||||||
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();
|
|
@ -1,61 +1,76 @@
|
|||||||
{
|
{
|
||||||
"ar": [
|
"ar": [
|
||||||
"go_to_album"
|
"go_to_album",
|
||||||
|
"discord_rich_presence"
|
||||||
],
|
],
|
||||||
|
|
||||||
"bn": [
|
"bn": [
|
||||||
"go_to_album"
|
"go_to_album",
|
||||||
|
"discord_rich_presence"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ca": [
|
"ca": [
|
||||||
"go_to_album"
|
"go_to_album",
|
||||||
|
"discord_rich_presence"
|
||||||
],
|
],
|
||||||
|
|
||||||
"de": [
|
"de": [
|
||||||
"go_to_album"
|
"go_to_album",
|
||||||
|
"discord_rich_presence"
|
||||||
],
|
],
|
||||||
|
|
||||||
"es": [
|
"es": [
|
||||||
"go_to_album"
|
"go_to_album",
|
||||||
|
"discord_rich_presence"
|
||||||
],
|
],
|
||||||
|
|
||||||
"fa": [
|
"fa": [
|
||||||
"go_to_album"
|
"go_to_album",
|
||||||
|
"discord_rich_presence"
|
||||||
],
|
],
|
||||||
|
|
||||||
"fr": [
|
"fr": [
|
||||||
"go_to_album"
|
"go_to_album",
|
||||||
|
"discord_rich_presence"
|
||||||
],
|
],
|
||||||
|
|
||||||
"hi": [
|
"hi": [
|
||||||
"go_to_album"
|
"go_to_album",
|
||||||
|
"discord_rich_presence"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ja": [
|
"ja": [
|
||||||
"go_to_album"
|
"go_to_album",
|
||||||
|
"discord_rich_presence"
|
||||||
],
|
],
|
||||||
|
|
||||||
"pl": [
|
"pl": [
|
||||||
"go_to_album"
|
"go_to_album",
|
||||||
|
"discord_rich_presence"
|
||||||
],
|
],
|
||||||
|
|
||||||
"pt": [
|
"pt": [
|
||||||
"go_to_album"
|
"go_to_album",
|
||||||
|
"discord_rich_presence"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ru": [
|
"ru": [
|
||||||
"go_to_album"
|
"go_to_album",
|
||||||
|
"discord_rich_presence"
|
||||||
],
|
],
|
||||||
|
|
||||||
"tr": [
|
"tr": [
|
||||||
"go_to_album"
|
"go_to_album",
|
||||||
|
"discord_rich_presence"
|
||||||
],
|
],
|
||||||
|
|
||||||
"uk": [
|
"uk": [
|
||||||
"go_to_album"
|
"go_to_album",
|
||||||
|
"discord_rich_presence"
|
||||||
],
|
],
|
||||||
|
|
||||||
"zh": [
|
"zh": [
|
||||||
"go_to_album"
|
"go_to_album",
|
||||||
|
"discord_rich_presence"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user