Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions CollapseLauncher/Classes/DiscordPresence/DiscordPresenceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,21 @@ public enum ActivityType
public sealed partial class DiscordPresenceManager : IDisposable
{
#region Properties

public bool IsRpcEnabled
{
get => field = GetAppConfigValue("EnableDiscordRPC");
set
{
if (field == value) return;
field = value;

SetAndSaveConfigValue("EnableDiscordRPC", value);
if (value) SetupPresence();
else DisablePresence();
}
}

private const string CollapseLogoExt = "https://collapselauncher.com/img/logo@2x.webp";

private DiscordRpcClient? _client;
Expand All @@ -46,8 +61,8 @@ public sealed partial class DiscordPresenceManager : IDisposable
private DateTime? _lastPlayTime;
private bool _firstTimeConnect = true;
private readonly ActionBlock<RichPresence?> _presenceUpdateQueue;

private bool _cachedIsIdleEnabled = true;
private bool _cachedIsIdleEnabled = true;

public bool IdleEnabled
{
Expand Down Expand Up @@ -103,6 +118,7 @@ public void Dispose()

private void EnablePresence(ulong applicationId)
{
if (!IsRpcEnabled) return;
_firstTimeConnect = true;

// Flush and dispose the session
Expand Down Expand Up @@ -168,8 +184,10 @@ public void DisablePresence()

public void SetupPresence()
{
string? gameCategory = GetAppConfigValue("GameCategory").ToString();
bool isGameStatusEnabled = GetAppConfigValue("EnableDiscordGameStatus").ToBool();
if (!IsRpcEnabled) return;

var gameCategory = GetAppConfigValue("GameCategory").ToString();
var isGameStatusEnabled = GetAppConfigValue("EnableDiscordGameStatus").ToBool();

if (isGameStatusEnabled)
{
Expand Down Expand Up @@ -220,10 +238,7 @@ private bool TryEnablePresenceIfPlugin()

public void SetActivity(ActivityType activity, DateTime? activityOffset = null)
{
if (!GetAppConfigValue("EnableDiscordRPC").ToBool())
{
return;
}
if (!IsRpcEnabled) return;

//_lastAttemptedActivityType = activity;
_activityType = activity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ private async Task<bool> LoadRegionRootButton()

LogWriteLine($"Region changed to {Preset.ZoneFullname}", LogType.Scheme, true);
#if !DISABLEDISCORD
if (GetAppConfigValue("EnableDiscordRPC").ToBool())
if (AppDiscordPresence.IsRpcEnabled)
AppDiscordPresence.SetupPresence();
#endif
return true;
Expand Down
4 changes: 2 additions & 2 deletions CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -881,8 +881,8 @@ private async void ChangeToActivatedRegion()
if (await LoadRegionFromCurrentConfigV2(preset, gameName, gameRegion))
{
#if !DISABLEDISCORD
if (GetAppConfigValue("EnableDiscordRPC").ToBool() && !sameRegion)
AppDiscordPresence?.SetupPresence();
if ((AppDiscordPresence?.IsRpcEnabled ?? false) && !sameRegion)
AppDiscordPresence.SetupPresence();
#endif
InvokeLoadingRegionPopup(false);
LauncherFrame.BackStack.Clear();
Expand Down
1 change: 1 addition & 0 deletions CollapseLauncher/XAMLs/MainApp/Pages/HomePage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2219,6 +2219,7 @@
Style="{ThemeResource BodyStrongTextBlockStyle}"
Text="{x:Bind helper:Locale.Lang._HomePage.GameSettings_Panel3RegionRpc}" />
<ToggleSwitch x:Name="RegionRpcToggle"
IsEnabled="{x:Bind IsRpcEnabled_QS}"
IsOn="{x:Bind ToggleRegionPlayingRpc, Mode=TwoWay}"
OffContent="{x:Bind helper:Locale.Lang._Misc.Disabled}"
OnContent="{x:Bind helper:Locale.Lang._Misc.Enabled}" />
Expand Down
2 changes: 2 additions & 0 deletions CollapseLauncher/XAMLs/MainApp/Pages/HomePage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ public sealed partial class HomePage
private int barWidth;
private int consoleWidth;

private readonly bool IsRpcEnabled_QS = AppDiscordPresence?.IsRpcEnabled ?? false;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The readonly field IsRpcEnabled_QS is initialized with a stale false value because AppDiscordPresence is null during HomePage construction, permanently disabling the RegionRpcToggle.
Severity: HIGH | Confidence: High

🔍 Detailed Analysis

The readonly field IsRpcEnabled_QS in HomePage.xaml.cs is initialized at a point in the application startup sequence where AppDiscordPresence is still null. This causes the field to be permanently set to false due to the null-coalescing operator (?? false). The UI's RegionRpcToggle is bound to this readonly field, and as a result, it will always be disabled. This prevents users from interacting with the regional RPC toggle, even when the global RPC setting is enabled, which defeats the purpose of the new control.

💡 Suggested Fix

Instead of using a readonly field, convert IsRpcEnabled_QS into a property with a getter that dynamically reads the current state from AppDiscordPresence.IsRpcEnabled. This ensures the UI binding always reflects the up-to-date value of the global RPC setting. Also, consider implementing INotifyPropertyChanged to update the UI dynamically if the global setting can change while the page is open.

🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: CollapseLauncher/XAMLs/MainApp/Pages/HomePage.xaml.cs#L82

Potential issue: The `readonly` field `IsRpcEnabled_QS` in `HomePage.xaml.cs` is
initialized at a point in the application startup sequence where `AppDiscordPresence` is
still `null`. This causes the field to be permanently set to `false` due to the
null-coalescing operator (`?? false`). The UI's `RegionRpcToggle` is bound to this
`readonly` field, and as a result, it will always be disabled. This prevents users from
interacting with the regional RPC toggle, even when the global RPC setting is enabled,
which defeats the purpose of the new control.

Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 513280


public static int RefreshRateDefault => 500;
public static int RefreshRateSlow => 1000;

Expand Down
13 changes: 6 additions & 7 deletions CollapseLauncher/XAMLs/MainApp/Pages/SettingsPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -769,9 +769,9 @@ private bool IsDiscordRpcEnabled
{
get
{
bool isEnabled = GetAppConfigValue("EnableDiscordRPC");
ToggleDiscordGameStatus.IsEnabled = IsEnabled;
if (isEnabled)
var e = AppDiscordPresence.IsRpcEnabled;
ToggleDiscordGameStatus.IsEnabled = e;
if (e)
{
ToggleDiscordGameStatus.Visibility = Visibility.Visible;
ToggleDiscordIdleStatus.Visibility = Visibility.Visible;
Expand All @@ -781,23 +781,22 @@ private bool IsDiscordRpcEnabled
ToggleDiscordGameStatus.Visibility = Visibility.Collapsed;
ToggleDiscordIdleStatus.Visibility = Visibility.Collapsed;
}
return isEnabled;
return e;
}
set
{
if (value)
{
AppDiscordPresence.SetupPresence();
ToggleDiscordGameStatus.Visibility = Visibility.Visible;
ToggleDiscordIdleStatus.Visibility = Visibility.Visible;
}
else
{
AppDiscordPresence.DisablePresence();
ToggleDiscordGameStatus.Visibility = Visibility.Collapsed;
ToggleDiscordIdleStatus.Visibility = Visibility.Collapsed;
}
SetAndSaveConfigValue("EnableDiscordRPC", value);

AppDiscordPresence.IsRpcEnabled = value;
ToggleDiscordGameStatus.IsEnabled = value;
}
}
Expand Down
Loading