Skip to content

feat: Discord Rich Presence integration for activity display#126

Open
Meganugger wants to merge 4 commits intoOpenCloudGaming:devfrom
OpenCloudFork:feat/discord-rich-presence
Open

feat: Discord Rich Presence integration for activity display#126
Meganugger wants to merge 4 commits intoOpenCloudGaming:devfrom
OpenCloudFork:feat/discord-rich-presence

Conversation

@Meganugger
Copy link

Summary

Integrates Discord Rich Presence to display user activity and streaming details (game name, resolution, FPS, region, elapsed time) in the GFN client, with fixes for reliable game title resolution and persistent app timer.

Added

  • DiscordPresenceService in src/main/discord/ for managing Discord RPC lifecycle
  • Discord RPC IPC channels (discord:update-presence, discord:clear-presence) in preload and shared IPC
  • Discord settings section in SettingsPage (enable/disable toggle, custom client ID)
  • discordPresenceEnabled and discordClientId fields in settings and shared types
  • App-level hooks in App.tsx to push idle/queue/streaming presence updates

Updated

  • package.json / package-lock.json with @xhayper/discord-rpc dependency
  • DiscordPresencePayload interface in gfn.ts for typed presence data

Fixed

  • Game name resolution now falls back correctly when title is unavailable
  • Server details and elapsed timer accuracy improved
  • Persistent app timer no longer resets on state transitions

Validation Notes

Recommended smoke checks:

  • Launch the app with Discord running and verify presence appears in Discord profile
  • Start a streaming session and confirm game name, resolution, and elapsed time display correctly
  • Toggle Discord Rich Presence off in settings and confirm presence clears
  • Close the app and confirm Discord presence clears gracefully

Copy link

@capy-ai capy-ai bot left a comment

Choose a reason for hiding this comment

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

Added 2 comments

// Logs export IPC handler
ipcMain.handle(IPC_CHANNELS.LOGS_EXPORT, async (_event, format: "text" | "json" = "text"): Promise<string> => {
return exportLogs(format);

Copy link

Choose a reason for hiding this comment

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

[🔴 Critical]

The DISCORD_UPDATE_PRESENCE and DISCORD_CLEAR_PRESENCE IPC handlers are added inside the LOGS_EXPORT handler's async callback, after a return statement. They are unreachable dead code and will never be registered with ipcMain. Every call from the renderer (window.openNow.updateDiscordPresence(...)) will fail because no handler exists for those channels.

// opennow-stable/src/main/index.ts
ipcMain.handle(IPC_CHANNELS.LOGS_EXPORT, async (_event, format) => {
  return exportLogs(format);

  // Discord Rich Presence IPC handlers  ← unreachable!
  ipcMain.handle(IPC_CHANNELS.DISCORD_UPDATE_PRESENCE, ...);
  ipcMain.handle(IPC_CHANNELS.DISCORD_CLEAR_PRESENCE, ...);
});

Move both ipcMain.handle calls outside the LOGS_EXPORT handler, placing them at the same level as the other top-level IPC registrations in registerIpcHandlers().

Create an application at discord.com/developers and paste its Client ID here.
</span>
</div>
</div>
Copy link

Choose a reason for hiding this comment

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

[🟠 High]

The Discord <section> is inserted after the </div> that closes the scrollable content wrapper (line 1421 on the base), and an additional </div> is added after it. This results in: (1) the Discord section rendering outside the scrollable content area, and (2) an unmatched </div> that breaks the JSX tree, which will cause a React rendering error or broken layout.

// opennow-stable/src/renderer/src/components/SettingsPage.tsx
        </section>         {/* end of previous section */}
      </div>               {/* closes scrollable content area */}
        <section>...</section>  {/* Discord section — outside container! */}
      </div>               {/* extra unmatched closing div */}
      <div className="settings-footer">

Move the Discord <section> block above the </div> that closes the scrollable content container, and remove the extra </div>.

@zortos293
Copy link
Collaborator

zortos293 commented Feb 24, 2026

@Meganugger can you fix these issues?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants