Add settings customize Discord status text

The new settings let you customize the "Listening to" status text, according to the [status display types](https://discord.com/developers/docs/events/gateway-events#activity-object).

Fixes #1796.
This commit is contained in:
7xnl
2025-08-28 01:30:25 +03:00
committed by Jonas Kvinge
parent 3c3480fb84
commit b5fd3d5717
7 changed files with 75 additions and 4 deletions

View File

@@ -32,6 +32,7 @@ extern "C" {
typedef struct DiscordRichPresence { typedef struct DiscordRichPresence {
int type; int type;
int status_display_type;
const char *name; /* max 128 bytes */ const char *name; /* max 128 bytes */
const char *state; /* max 128 bytes */ const char *state; /* max 128 bytes */
const char *details; /* max 128 bytes */ const char *details; /* max 128 bytes */

View File

@@ -128,6 +128,9 @@ size_t JsonWriteRichPresenceObj(char *dest, const size_t maxLen, const int nonce
if (presence->type >= 0 && presence->type <= 5) { if (presence->type >= 0 && presence->type <= 5) {
WriteKey(writer, "type"); WriteKey(writer, "type");
writer.Int(presence->type); writer.Int(presence->type);
WriteKey(writer, "status_display_type");
writer.Int(presence->status_display_type);
} }
WriteOptionalString(writer, "name", presence->name); WriteOptionalString(writer, "name", presence->name);

View File

@@ -71,6 +71,14 @@ constexpr char kSettingsGroup[] = "DiscordRPC";
constexpr char kEnabled[] = "enabled"; constexpr char kEnabled[] = "enabled";
constexpr char kStatusDisplayType[] = "StatusDisplayType";
enum class StatusDisplayType {
App = 0,
Artist,
Song
};
} // namespace } // namespace
#endif // NOTIFICATIONSSETTINGS_H #endif // NOTIFICATIONSSETTINGS_H

View File

@@ -46,7 +46,8 @@ RichPresence::RichPresence(const SharedPtr<Player> player,
: QObject(parent), : QObject(parent),
player_(player), player_(player),
playlist_manager_(playlist_manager), playlist_manager_(playlist_manager),
initialized_(false) { initialized_(false),
status_display_type_(0) {
QObject::connect(&*player_->engine(), &EngineBase::StateChanged, this, &RichPresence::EngineStateChanged); QObject::connect(&*player_->engine(), &EngineBase::StateChanged, this, &RichPresence::EngineStateChanged);
QObject::connect(&*playlist_manager_, &PlaylistManager::CurrentSongChanged, this, &RichPresence::CurrentSongChanged); QObject::connect(&*playlist_manager_, &PlaylistManager::CurrentSongChanged, this, &RichPresence::CurrentSongChanged);
@@ -69,6 +70,7 @@ void RichPresence::ReloadSettings() {
Settings s; Settings s;
s.beginGroup(DiscordRPCSettings::kSettingsGroup); s.beginGroup(DiscordRPCSettings::kSettingsGroup);
const bool enabled = s.value(DiscordRPCSettings::kEnabled, false).toBool(); const bool enabled = s.value(DiscordRPCSettings::kEnabled, false).toBool();
status_display_type_ = s.value(DiscordRPCSettings::kStatusDisplayType, static_cast<int>(DiscordRPCSettings::StatusDisplayType::App)).toInt();
s.endGroup(); s.endGroup();
if (enabled && !initialized_) { if (enabled && !initialized_) {
@@ -117,7 +119,11 @@ void RichPresence::SendPresenceUpdate() {
::DiscordRichPresence presence_data{}; ::DiscordRichPresence presence_data{};
memset(&presence_data, 0, sizeof(presence_data)); memset(&presence_data, 0, sizeof(presence_data));
presence_data.type = 2; // Listening
// Listening to
presence_data.type = 2;
presence_data.status_display_type = status_display_type_;
presence_data.largeImageKey = kStrawberryIconResourceName; presence_data.largeImageKey = kStrawberryIconResourceName;
presence_data.smallImageKey = kStrawberryIconResourceName; presence_data.smallImageKey = kStrawberryIconResourceName;
presence_data.smallImageText = kStrawberryIconDescription; presence_data.smallImageText = kStrawberryIconDescription;
@@ -126,7 +132,9 @@ void RichPresence::SendPresenceUpdate() {
QByteArray artist; QByteArray artist;
if (!activity_.artist.isEmpty()) { if (!activity_.artist.isEmpty()) {
artist = activity_.artist.toUtf8(); artist = activity_.artist.toUtf8();
artist.prepend(tr("by ").toUtf8()); if (artist.size() < 2) { // Discord activity 2 char min. fix
artist.append(" ");
}
presence_data.state = artist.constData(); presence_data.state = artist.constData();
} }

View File

@@ -70,6 +70,7 @@ class RichPresence : public QObject {
}; };
Activity activity_; Activity activity_;
bool initialized_; bool initialized_;
int status_display_type_;
}; };
} // namespace discord } // namespace discord

View File

@@ -209,6 +209,19 @@ void NotificationsSettingsPage::Load() {
// Discord // Discord
s.beginGroup(DiscordRPCSettings::kSettingsGroup); s.beginGroup(DiscordRPCSettings::kSettingsGroup);
ui_->richpresence_enabled->setChecked(s.value(DiscordRPCSettings::kEnabled, false).toBool()); ui_->richpresence_enabled->setChecked(s.value(DiscordRPCSettings::kEnabled, false).toBool());
const DiscordRPCSettings::StatusDisplayType discord_status_display_type = static_cast<DiscordRPCSettings::StatusDisplayType>(s.value(DiscordRPCSettings::kStatusDisplayType, static_cast<int>(DiscordRPCSettings::StatusDisplayType::App)).toInt());
switch (discord_status_display_type) {
case DiscordRPCSettings::StatusDisplayType::App:
ui_->richpresence_listening_to_app->setChecked(true);
break;
case DiscordRPCSettings::StatusDisplayType::Artist:
ui_->richpresence_listening_to_artist->setChecked(true);
break;
case DiscordRPCSettings::StatusDisplayType::Song:
ui_->richpresence_listening_to_song->setChecked(true);
break;
}
s.endGroup(); s.endGroup();
UpdatePopupVisible(); UpdatePopupVisible();
@@ -229,6 +242,11 @@ void NotificationsSettingsPage::Save() {
else if (osd_->SupportsTrayPopups() && ui_->notifications_tray->isChecked()) osd_type = OSDSettings::Type::TrayPopup; else if (osd_->SupportsTrayPopups() && ui_->notifications_tray->isChecked()) osd_type = OSDSettings::Type::TrayPopup;
else if (osd_->SupportsOSDPretty() && ui_->notifications_pretty->isChecked()) osd_type = OSDSettings::Type::Pretty; else if (osd_->SupportsOSDPretty() && ui_->notifications_pretty->isChecked()) osd_type = OSDSettings::Type::Pretty;
DiscordRPCSettings::StatusDisplayType discord_status_display_type = DiscordRPCSettings::StatusDisplayType::App;
if (ui_->richpresence_listening_to_app->isChecked()) discord_status_display_type = DiscordRPCSettings::StatusDisplayType::App;
else if (ui_->richpresence_listening_to_artist->isChecked()) discord_status_display_type = DiscordRPCSettings::StatusDisplayType::Artist;
else if (ui_->richpresence_listening_to_song->isChecked()) discord_status_display_type = DiscordRPCSettings::StatusDisplayType::Song;
s.beginGroup(OSDSettings::kSettingsGroup); s.beginGroup(OSDSettings::kSettingsGroup);
s.setValue(OSDSettings::kType, static_cast<int>(osd_type)); s.setValue(OSDSettings::kType, static_cast<int>(osd_type));
s.setValue(OSDSettings::kTimeout, ui_->notifications_duration->value() * 1000); s.setValue(OSDSettings::kTimeout, ui_->notifications_duration->value() * 1000);
@@ -255,7 +273,9 @@ void NotificationsSettingsPage::Save() {
s.beginGroup(DiscordRPCSettings::kSettingsGroup); s.beginGroup(DiscordRPCSettings::kSettingsGroup);
s.setValue(DiscordRPCSettings::kEnabled, ui_->richpresence_enabled->isChecked()); s.setValue(DiscordRPCSettings::kEnabled, ui_->richpresence_enabled->isChecked());
s.setValue(DiscordRPCSettings::kStatusDisplayType, static_cast<int>(discord_status_display_type));
s.endGroup(); s.endGroup();
} }
void NotificationsSettingsPage::PrettyOpacityChanged(int value) { void NotificationsSettingsPage::PrettyOpacityChanged(int value) {

View File

@@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>518</width> <width>518</width>
<height>778</height> <height>844</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -380,6 +380,36 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QGroupBox" name="richpresence_listening_to">
<property name="title">
<string>&quot;Listening to...&quot;</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_11">
<item>
<widget class="QRadioButton" name="richpresence_listening_to_app">
<property name="text">
<string>Strawberry</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="richpresence_listening_to_artist">
<property name="text">
<string>Artist name</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="richpresence_listening_to_song">
<property name="text">
<string>Song title</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>