use discord_rich_presence::{activity, DiscordIpc, DiscordIpcClient};
use super::config;
pub struct DiscordRpcClient {
inner: DiscordIpcClient,
connected: bool,
}
pub struct LargeImage<'a> {
pub key: &'a str,
pub text: &'a str,
}
impl DiscordRpcClient {
pub fn new() -> Self {
let client_id = option_env!("DISCORD_CLIENT_ID")
.filter(|id| !id.is_empty())
.map(str::to_string)
.unwrap_or_else(|| config::load().client_id);
Self {
inner: DiscordIpcClient::new(&client_id),
connected: false,
}
}
pub fn is_connected(&self) -> bool {
self.connected
}
pub fn connect(&mut self) -> bool {
self.connected = self.inner.connect().is_ok();
self.connected
}
pub fn set_presence(
&mut self,
details: &str,
state: Option<&str>,
large_image: Option<LargeImage>,
started_at_unix_ms: i64,
) -> bool {
if !self.connected {
return false;
}
let mut activity = activity::Activity::new()
.details(details)
.timestamps(activity::Timestamps::new().start(started_at_unix_ms));
if let Some(state) = state {
activity = activity.state(state);
}
if let Some(LargeImage { key, text }) = large_image {
activity = activity.assets(
activity::Assets::new()
.large_image(key)
.large_text(text),
);
}
if self.inner.set_activity(activity).is_err() {
self.connected = false;
return false;
}
true
}
pub fn clear_presence(&mut self) {
if self.connected {
let _ = self.inner.clear_activity();
}
}
}
impl Default for DiscordRpcClient {
fn default() -> Self {
Self::new()
}
}