Skip to content

Commit 4291f41

Browse files
author
NellowTCS
committed
Add not working discord local rpc to desktop app
1 parent 075daa6 commit 4291f41

9 files changed

Lines changed: 215 additions & 62 deletions

File tree

Build/src-tauri/Cargo.lock

Lines changed: 29 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Build/src-tauri/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ serde_json = "1.0.149"
2525
tauri-plugin-fs = "2.4.5"
2626
tauri-plugin-notification = "2.3.3"
2727
tauri-plugin-dialog = "2.6.0"
28+
discord-rich-presence = "1.1.0"
2829

Build/src-tauri/src/lib.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,65 @@
11
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
2+
3+
use discord_rich_presence::{activity::Activity, DiscordIpc, DiscordIpcClient};
4+
5+
const DISCORD_APP_ID: &str = "1419480226970341476";
6+
const DISCORD_LARGE_IMAGE_KEY: &str = "large_image_key";
7+
28
#[tauri::command]
39
fn greet(name: &str) -> String {
410
format!("Hello, {}! You've been greeted from Rust!", name)
511
}
612

13+
#[tauri::command]
14+
fn set_discord_presence(details: String, state: String) -> Result<(), String> {
15+
let mut client = DiscordIpcClient::new(DISCORD_APP_ID);
16+
17+
client.connect().map_err(|e| format!("Discord connect failed: {}", e))?;
18+
19+
let activity = Activity::new()
20+
.details(details)
21+
.state(state)
22+
.assets(
23+
discord_rich_presence::activity::Assets::new()
24+
.large_image(DISCORD_LARGE_IMAGE_KEY)
25+
.large_text("HTMLPlayer"),
26+
);
27+
28+
client
29+
.set_activity(activity)
30+
.map_err(|e| format!("Failed to set Discord activity: {}", e))
31+
}
32+
33+
#[tauri::command]
34+
fn clear_discord_presence() -> Result<(), String> {
35+
let mut client = DiscordIpcClient::new(DISCORD_APP_ID);
36+
37+
client.connect().map_err(|e| format!("Discord connect failed: {}", e))?;
38+
client
39+
.clear_activity()
40+
.map_err(|e| format!("Failed to clear Discord activity: {}", e))
41+
}
42+
43+
#[tauri::command]
44+
fn is_discord_running() -> bool {
45+
let mut client = DiscordIpcClient::new(DISCORD_APP_ID);
46+
if client.connect().is_err() {
47+
return false;
48+
}
49+
50+
// Ignore errors when clearing activity; we only care whether the IPC is reachable.
51+
let _ = client.clear_activity();
52+
true
53+
}
54+
755
#[cfg_attr(mobile, tauri::mobile_entry_point)]
856
pub fn run() {
957
tauri::Builder::default()
1058
.plugin(tauri_plugin_dialog::init())
1159
.plugin(tauri_plugin_notification::init())
1260
.plugin(tauri_plugin_fs::init())
1361
.plugin(tauri_plugin_opener::init())
14-
.invoke_handler(tauri::generate_handler![greet])
62+
.invoke_handler(tauri::generate_handler![greet, set_discord_presence, clear_discord_presence, is_discord_running])
1563
.run(tauri::generate_context!())
1664
.expect("error while running tauri application");
1765
}

Build/src/components/Settings.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { useTranslation } from "react-i18next";
2929
import { languageNames } from "../types/supportedLanguages";
3030
import { isSafari } from "../helpers/safariHelper";
3131
import { Icon } from "./Icon";
32+
import { isTauri } from "@tauri-apps/api/core";
3233

3334
import { resetAllDialogPreferences } from "../helpers/musicIndexedDbHelper";
3435
import {
@@ -180,6 +181,36 @@ export const Settings = ({
180181
}
181182
};
182183

184+
const [discordRpcStatus, setDiscordRpcStatus] = useState<
185+
"unknown" | "available" | "unavailable" | "unsupported"
186+
>("unknown");
187+
188+
const isTauriEnv = isTauri();
189+
190+
const checkDiscordRpcStatus = async () => {
191+
if (!isTauriEnv) {
192+
setDiscordRpcStatus("unsupported");
193+
return;
194+
}
195+
196+
try {
197+
const { invoke } = await import("@tauri-apps/api/core");
198+
const available = await invoke("is_discord_running");
199+
setDiscordRpcStatus(available ? "available" : "unavailable");
200+
} catch (error) {
201+
console.error("Failed to check Discord RPC status:", error);
202+
setDiscordRpcStatus("unavailable");
203+
}
204+
};
205+
206+
useEffect(() => {
207+
if (settings.discordEnabled) {
208+
checkDiscordRpcStatus();
209+
} else {
210+
setDiscordRpcStatus("unknown");
211+
}
212+
}, [settings.discordEnabled]);
213+
183214
// Dynamic Eruda loading/unloading functions
184215
const loadEruda = () => {
185216
return new Promise<void>((resolve, reject) => {
@@ -910,6 +941,28 @@ export const Settings = ({
910941
</div>
911942
</div>
912943
)}
944+
945+
<div className={styles.settingItem}>
946+
<div className={styles.settingInfo}>
947+
<label>{t("discord.status")}</label>
948+
<p className={styles.settingDescription}>
949+
{discordRpcStatus === "unknown" && t("discord.statusUnknown")}
950+
{discordRpcStatus === "unsupported" &&
951+
t("discord.statusUnsupported")}
952+
{discordRpcStatus === "available" &&
953+
t("discord.statusAvailable")}
954+
{discordRpcStatus === "unavailable" &&
955+
t("discord.statusUnavailable")}
956+
</p>
957+
</div>
958+
<Button
959+
variant="outline"
960+
onClick={checkDiscordRpcStatus}
961+
disabled={!isTauriEnv}
962+
>
963+
{t("discord.refreshStatus")}
964+
</Button>
965+
</div>
913966
</>
914967
)}
915968

Build/src/helpers/discordService.ts

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -24,49 +24,22 @@ export class DiscordService {
2424
}
2525

2626
/**
27-
* Send track update to Discord backend
27+
* Log track update instead of sending to Discord backend
2828
*/
2929
public async updatePresence(data: DiscordPresenceData): Promise<boolean> {
30-
try {
31-
const response = await fetch(`${DiscordService.API_BASE_URL}/presence`, {
32-
method: "POST",
33-
headers: {
34-
"Content-Type": "application/json",
35-
},
36-
body: JSON.stringify(data),
37-
});
38-
39-
if (!response.ok) {
40-
console.error(
41-
"Failed to update Discord presence:",
42-
response.status,
43-
response.statusText,
44-
);
45-
return false;
46-
}
47-
48-
return true;
49-
} catch (error) {
50-
console.error("Error updating Discord presence:", error);
51-
return false;
52-
}
30+
console.log(
31+
`[DiscordService] Would POST to ${DiscordService.API_BASE_URL}/presence with:`,
32+
data,
33+
);
34+
return true;
5335
}
5436

5537
/**
56-
* Clear Discord presence (when music stops)
38+
* Log clear presence instead of sending to Discord backend
5739
*/
5840
public async clearPresence(userId: string): Promise<boolean> {
59-
try {
60-
// Send empty details and state to clear presence
61-
return await this.updatePresence({
62-
userId,
63-
details: "",
64-
state: "",
65-
});
66-
} catch (error) {
67-
console.error("Error clearing Discord presence:", error);
68-
return false;
69-
}
41+
console.log(`[DiscordService] Would clear presence for userId: ${userId}`);
42+
return true;
7043
}
7144

7245
/**

Build/src/helpers/discordService_backup.ts

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,49 @@ export class DiscordService {
2424
}
2525

2626
/**
27-
* Log track update instead of sending to Discord backend
27+
* Send track update to Discord backend
2828
*/
2929
public async updatePresence(data: DiscordPresenceData): Promise<boolean> {
30-
console.log(
31-
`[DiscordService] Would POST to ${DiscordService.API_BASE_URL}/presence with:`,
32-
data,
33-
);
34-
return true;
30+
try {
31+
const response = await fetch(`${DiscordService.API_BASE_URL}/presence`, {
32+
method: "POST",
33+
headers: {
34+
"Content-Type": "application/json",
35+
},
36+
body: JSON.stringify(data),
37+
});
38+
39+
if (!response.ok) {
40+
console.error(
41+
"Failed to update Discord presence:",
42+
response.status,
43+
response.statusText,
44+
);
45+
return false;
46+
}
47+
48+
return true;
49+
} catch (error) {
50+
console.error("Error updating Discord presence:", error);
51+
return false;
52+
}
3553
}
3654

3755
/**
38-
* Log clear presence instead of sending to Discord backend
56+
* Clear Discord presence (when music stops)
3957
*/
4058
public async clearPresence(userId: string): Promise<boolean> {
41-
console.log(`[DiscordService] Would clear presence for userId: ${userId}`);
42-
return true;
59+
try {
60+
// Send empty details and state to clear presence
61+
return await this.updatePresence({
62+
userId,
63+
details: "",
64+
state: "",
65+
});
66+
} catch (error) {
67+
console.error("Error clearing Discord presence:", error);
68+
return false;
69+
}
4370
}
4471

4572
/**

Build/src/hooks/musicPlayerHook.tsx

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -693,21 +693,35 @@ export const useMusicPlayer = () => {
693693
// Discord presence update function
694694
const updateDiscordPresence = useCallback(
695695
async (song: Song | null, isPlaying: boolean) => {
696-
const discordService = DiscordService.getInstance();
696+
if (!settings.discordEnabled) return;
697697

698-
if (!settings.discordEnabled || !settings.discordUserId) {
699-
return;
700-
}
698+
// Prefer Tauri RPC (desktop) if available
699+
const isTauri = (await import("@tauri-apps/api/core")).isTauri();
701700

702701
try {
703702
if (song && isPlaying) {
704-
await discordService.updatePresence({
705-
userId: settings.discordUserId,
706-
details: song.title,
707-
state: song.artist,
708-
});
703+
if (isTauri) {
704+
const { invoke } = await import("@tauri-apps/api/core");
705+
await invoke("set_discord_presence", {
706+
details: song.title,
707+
state: song.artist,
708+
});
709+
} else if (settings.discordUserId) {
710+
const discordService = DiscordService.getInstance();
711+
await discordService.updatePresence({
712+
userId: settings.discordUserId,
713+
details: song.title,
714+
state: song.artist,
715+
});
716+
}
709717
} else {
710-
await discordService.clearPresence(settings.discordUserId);
718+
if (isTauri) {
719+
const { invoke } = await import("@tauri-apps/api/core");
720+
await invoke("clear_discord_presence");
721+
} else if (settings.discordUserId) {
722+
const discordService = DiscordService.getInstance();
723+
await discordService.clearPresence(settings.discordUserId);
724+
}
711725
}
712726
} catch (error) {
713727
console.error("Failed to update Discord presence:", error);

0 commit comments

Comments
 (0)