Initial Commit
@@ -0,0 +1,7 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
|
||||
# Generated by Tauri
|
||||
# will have schema files for capabilities auto-completion
|
||||
/gen/schemas
|
||||
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "discord-presence"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
tauri = { version = "2", features = [] }
|
||||
tauri-build = { version = "2", features = [] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
discord-rich-presence = "0.2"
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2", features = [] }
|
||||
|
||||
[profile.release]
|
||||
strip = true
|
||||
lto = true
|
||||
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"identifier": "default",
|
||||
"description": "Default capabilities for the app",
|
||||
"windows": ["main"],
|
||||
"permissions": [
|
||||
"core:default"
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 974 B |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 903 B |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,74 @@
|
||||
use discord_rich_presence::{activity, DiscordIpc, DiscordIpcClient};
|
||||
use std::sync::Mutex;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use tauri::State;
|
||||
|
||||
struct Discord(Mutex<Option<DiscordIpcClient>>);
|
||||
unsafe impl Send for Discord {}
|
||||
unsafe impl Sync for Discord {}
|
||||
|
||||
struct StartTime(Mutex<i64>);
|
||||
|
||||
#[tauri::command]
|
||||
fn connect(app_id: String, discord: State<Discord>, start: State<StartTime>) -> Result<String, String> {
|
||||
let mut guard = discord.0.lock().map_err(|e| e.to_string())?;
|
||||
if let Some(ref mut old) = *guard {
|
||||
old.close().ok();
|
||||
}
|
||||
let mut client = DiscordIpcClient::new(&app_id).map_err(|e| e.to_string())?;
|
||||
client.connect().map_err(|_| "Could not connect — is Discord running?".to_string())?;
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i64;
|
||||
*start.0.lock().unwrap() = now;
|
||||
*guard = Some(client);
|
||||
Ok("Connected".into())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn disconnect(discord: State<Discord>) -> Result<String, String> {
|
||||
let mut guard = discord.0.lock().map_err(|e| e.to_string())?;
|
||||
if let Some(ref mut client) = *guard {
|
||||
client.close().map_err(|e| e.to_string())?;
|
||||
}
|
||||
*guard = None;
|
||||
Ok("Disconnected".into())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn set_activity(
|
||||
status: String,
|
||||
details: String,
|
||||
show_time: bool,
|
||||
elapsed_seconds: Option<i64>,
|
||||
discord: State<Discord>,
|
||||
start: State<StartTime>,
|
||||
) -> Result<String, String> {
|
||||
let mut guard = discord.0.lock().map_err(|e| e.to_string())?;
|
||||
let client = guard.as_mut().ok_or_else(|| "Not connected to Discord".to_string())?;
|
||||
let mut act = activity::Activity::new();
|
||||
if show_time {
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i64;
|
||||
let start_at = now - elapsed_seconds.unwrap_or(0);
|
||||
act = act.timestamps(activity::Timestamps::new().start(start_at));
|
||||
}
|
||||
if !status.is_empty() { act = act.state(&status); }
|
||||
if !details.is_empty() { act = act.details(&details); }
|
||||
client.set_activity(act).map_err(|e| e.to_string())?;
|
||||
Ok("Activity set".into())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn clear_activity(discord: State<Discord>) -> Result<String, String> {
|
||||
let mut guard = discord.0.lock().map_err(|e| e.to_string())?;
|
||||
let client = guard.as_mut().ok_or_else(|| "Not connected to Discord".to_string())?;
|
||||
client.clear_activity().map_err(|e| e.to_string())?;
|
||||
Ok("Cleared".into())
|
||||
}
|
||||
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.manage(Discord(Mutex::new(None)))
|
||||
.manage(StartTime(Mutex::new(0)))
|
||||
.invoke_handler(tauri::generate_handler![connect, disconnect, set_activity, clear_activity])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
fn main() {
|
||||
discord_presence::run();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/tauri-apps/tauri/dev/crates/tauri-utils/schema.json",
|
||||
"productName": "Discord Presence",
|
||||
"version": "0.1.0",
|
||||
"identifier": "org.racooncity.discord-presence",
|
||||
"build": {
|
||||
"frontendDist": "../ui"
|
||||
},
|
||||
"app": {
|
||||
"withGlobalTauri": true,
|
||||
"windows": [
|
||||
{
|
||||
"title": "Discord Presence",
|
||||
"width": 460,
|
||||
"height": 620,
|
||||
"resizable": true,
|
||||
"decorations": true,
|
||||
"center": true
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": "null"
|
||||
}
|
||||
}
|
||||
}
|
||||