Skip to content
Open
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
97 changes: 50 additions & 47 deletions src/actions/channel.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::cache::{CachedGuild, guild_cache, refresh_guild_cache};
use crate::client::{current_voice_channel, discord_client};
use crate::cache::{CachedGuild, GUILD_CACHE, refresh_guild_cache};
use crate::client::{CURRENT_VOICE_CHANNEL, get_discord_client};

use std::collections::HashMap;
use std::sync::{Arc, OnceLock};
use std::sync::{Arc, LazyLock};

use discord_ipc_rust::models::send::commands::{
GetChannelsArgs, SelectTextChannelArgs, SelectVoiceChannelArgs, SentCommand,
Expand All @@ -12,7 +12,7 @@ use openaction::{
Action, ActionUuid, Instance, InstanceId, OpenActionResult, async_trait, visible_instances,
};
use serde::{Deserialize, Serialize};
use tokio::sync::RwLock;
use tokio::sync::Mutex;

#[derive(Clone, Copy)]
enum ChannelKind {
Expand Down Expand Up @@ -41,10 +41,8 @@ impl ChannelKind {
}
}

fn channel_request_map() -> &'static RwLock<HashMap<InstanceId, ChannelKind>> {
static REQUESTS: OnceLock<RwLock<HashMap<InstanceId, ChannelKind>>> = OnceLock::new();
REQUESTS.get_or_init(|| RwLock::new(HashMap::new()))
}
static CHANNEL_REQUESTS_MAP: LazyLock<Mutex<HashMap<InstanceId, ChannelKind>>> =
LazyLock::new(|| Mutex::new(HashMap::new()));

async fn get_all_instances() -> impl Iterator<Item = Arc<Instance>> {
visible_instances(TextChannelAction::UUID)
Expand All @@ -60,7 +58,7 @@ pub async fn send_guilds_to_pi(instance: Option<&Instance>) {
guilds: Vec<CachedGuild>,
}

let cache = guild_cache().read().await;
let cache = GUILD_CACHE.read().await;
let payload = Payload {
guilds: cache.clone(),
};
Expand All @@ -78,7 +76,7 @@ pub async fn send_guilds_to_pi(instance: Option<&Instance>) {
}

pub async fn send_cached_guilds_to_pi(instance: &Instance) -> OpenActionResult<()> {
if !guild_cache().read().await.is_empty() {
if !GUILD_CACHE.read().await.is_empty() {
send_guilds_to_pi(Some(instance)).await;
Ok(())
} else {
Expand All @@ -97,7 +95,7 @@ pub async fn send_channels_to_pi(channels: &[Channel]) {
channels: Vec<ChannelInfo>,
}

let mut requests = channel_request_map().write().await;
let mut requests = CHANNEL_REQUESTS_MAP.lock().await;

for instance in get_all_instances().await {
if let Some(kind) = requests.remove(&instance.instance_id) {
Expand Down Expand Up @@ -136,17 +134,22 @@ impl PiRequest {

match request {
PiRequest::RequestChannels { guild_id } => {
channel_request_map()
.write()
CHANNEL_REQUESTS_MAP
.lock()
.await
.insert(instance.instance_id.clone(), kind);

let mut client_lock = discord_client().write().await;
if let Some(client) = client_lock.as_mut()
&& let Err(e) = client
let result = {
let Some(mut client) = get_discord_client(instance).await? else {
return Ok(());
};

client
.emit_command(&SentCommand::GetChannels(GetChannelsArgs { guild_id }))
.await
{
};

if let Err(e) = result {
log::error!("Failed to request channels: {}", e);
}
}
Expand Down Expand Up @@ -191,20 +194,20 @@ impl Action for TextChannelAction {
return Ok(());
}

let mut client_lock = discord_client().write().await;
let Some(client) = client_lock.as_mut() else {
log::error!("Discord client not initialized");
instance.show_alert().await?;
return Ok(());
let result = {
let Some(mut client) = get_discord_client(instance).await? else {
return Ok(());
};

client
.emit_command(&SentCommand::SelectTextChannel(SelectTextChannelArgs {
channel_id: Some(settings.channel_id.clone()),
timeout: None,
}))
.await
};

if let Err(e) = client
.emit_command(&SentCommand::SelectTextChannel(SelectTextChannelArgs {
channel_id: Some(settings.channel_id.clone()),
timeout: None,
}))
.await
{
if let Err(e) = result {
log::error!("Failed to select text channel: {}", e);
instance.show_alert().await?;
}
Expand All @@ -217,7 +220,7 @@ async fn sync_voice_channel_state(
instance: &Instance,
settings: &ChannelActionSettings,
) -> OpenActionResult<()> {
let is_active = current_voice_channel()
let is_active = CURRENT_VOICE_CHANNEL
.read()
.await
.as_deref()
Expand Down Expand Up @@ -271,30 +274,30 @@ impl Action for VoiceChannelAction {
return Ok(());
}

let mut client_lock = discord_client().write().await;
let Some(client) = client_lock.as_mut() else {
log::error!("Discord client not initialized");
instance.show_alert().await?;
return Ok(());
};

let current = current_voice_channel().read().await;
let current = CURRENT_VOICE_CHANNEL.read().await;
let target = if current.as_deref() != Some(settings.channel_id.as_str()) {
Some(settings.channel_id.clone())
} else {
None
};
drop(current);

if let Err(e) = client
.emit_command(&SentCommand::SelectVoiceChannel(SelectVoiceChannelArgs {
channel_id: target,
force: Some(true),
navigate: Some(false),
timeout: None,
}))
.await
{
let result = {
let Some(mut client) = get_discord_client(instance).await? else {
return Ok(());
};

client
.emit_command(&SentCommand::SelectVoiceChannel(SelectVoiceChannelArgs {
channel_id: target,
force: Some(true),
navigate: Some(false),
timeout: None,
}))
.await
};

if let Err(e) = result {
log::error!("Failed to select or deselect voice channel: {}", e);
instance.show_alert().await?;
}
Expand Down
38 changes: 19 additions & 19 deletions src/actions/notifications.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::cache::notification_cache;
use crate::client::discord_client;
use crate::cache::NOTIFICATION_CACHE;
use crate::client::get_discord_client;

use discord_ipc_rust::models::send::commands::{SelectTextChannelArgs, SentCommand};
use openaction::{Action, ActionUuid, Instance, OpenActionResult, async_trait};
use serde::{Deserialize, Serialize};

pub async fn update_title(instance: &Instance) -> OpenActionResult<()> {
let cache = notification_cache().read().await;
let cache = NOTIFICATION_CACHE.read().await;
let title = format!("{}", cache.len());

if let Err(e) = instance.set_title(Some(title), None).await {
Expand Down Expand Up @@ -55,21 +55,21 @@ impl Action for NotificationsAction {
let notification = match settings.action_type {
NotificationsActionType::DoNothing => return Ok(()),
NotificationsActionType::Clear => {
notification_cache().write().await.clear();
NOTIFICATION_CACHE.write().await.clear();
update_title(instance).await?;
return Ok(());
}
NotificationsActionType::OpenAndClear => {
let mut cache = notification_cache().write().await;
let mut cache = NOTIFICATION_CACHE.write().await;
let notification = cache.pop_back();
cache.clear();
notification
}
NotificationsActionType::CycleRecentFirst => {
notification_cache().write().await.pop_back()
NOTIFICATION_CACHE.write().await.pop_back()
}
NotificationsActionType::CycleOldestFirst => {
notification_cache().write().await.pop_front()
NOTIFICATION_CACHE.write().await.pop_front()
}
};

Expand All @@ -80,20 +80,20 @@ impl Action for NotificationsAction {

update_title(instance).await?;

let mut client_lock = discord_client().write().await;
let Some(client) = client_lock.as_mut() else {
log::error!("Discord client not initialized");
instance.show_alert().await?;
return Ok(());
let result = {
let Some(mut client) = get_discord_client(instance).await? else {
return Ok(());
};

client
.emit_command(&SentCommand::SelectTextChannel(SelectTextChannelArgs {
channel_id: Some(notification.channel_id),
timeout: None,
}))
.await
};

if let Err(e) = client
.emit_command(&SentCommand::SelectTextChannel(SelectTextChannelArgs {
channel_id: Some(notification.channel_id),
timeout: None,
}))
.await
{
if let Err(e) = result {
log::error!("Failed to select text channel: {}", e);
instance.show_alert().await?;
}
Expand Down
24 changes: 12 additions & 12 deletions src/actions/screen_share.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::client::discord_client;
use crate::client::get_discord_client;

use std::collections::HashMap;

Expand All @@ -17,19 +17,19 @@ impl Action for ToggleScreenshareAction {
instance: &Instance,
_settings: &Self::Settings,
) -> OpenActionResult<()> {
let mut client_lock = discord_client().write().await;
let Some(client) = client_lock.as_mut() else {
log::error!("Discord client not initialized");
instance.show_alert().await?;
return Ok(());
let result = {
let Some(mut client) = get_discord_client(instance).await? else {
return Ok(());
};

client
.emit_command(&SentCommand::ToggleScreenshare(ToggleScreenshareArgs {
pid: None,
}))
.await
};

if let Err(e) = client
.emit_command(&SentCommand::ToggleScreenshare(ToggleScreenshareArgs {
pid: None,
}))
.await
{
if let Err(e) = result {
log::error!("Failed to toggle screen share: {}", e);
instance.show_alert().await?;
}
Expand Down
26 changes: 13 additions & 13 deletions src/actions/soundboard.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::cache::{CachedSoundboardSound, refresh_soundboard_cache, soundboard_sounds_cache};
use crate::client::discord_client;
use crate::cache::{CachedSoundboardSound, SOUNDBOARD_SOUNDS_CACHE, refresh_soundboard_cache};
use crate::client::get_discord_client;

use discord_ipc_rust::models::send::commands::SentCommand;
use openaction::{Action, ActionUuid, Instance, OpenActionResult, async_trait, visible_instances};
Expand All @@ -12,7 +12,7 @@ pub async fn send_sounds_to_pi(instance: Option<&Instance>) {
}

let payload = Payload {
sounds: soundboard_sounds_cache().read().await.clone(),
sounds: SOUNDBOARD_SOUNDS_CACHE.read().await.clone(),
};

match instance {
Expand All @@ -33,7 +33,7 @@ async fn set_button_title(instance: &Instance, sound: Option<&CachedSoundboardSo
}

async fn send_cached_sounds_to_pi(instance: &Instance) -> OpenActionResult<()> {
if !soundboard_sounds_cache().read().await.is_empty() {
if !SOUNDBOARD_SOUNDS_CACHE.read().await.is_empty() {
send_sounds_to_pi(Some(instance)).await;
crate::actions::channel::send_cached_guilds_to_pi(instance).await?;
Ok(())
Expand Down Expand Up @@ -86,17 +86,17 @@ impl Action for SoundboardAction {
return Ok(());
};

let mut client_lock = discord_client().write().await;
let Some(client) = client_lock.as_mut() else {
log::error!("Discord client not initialized");
instance.show_alert().await?;
return Ok(());
let result = {
let Some(mut client) = get_discord_client(instance).await? else {
return Ok(());
};

client
.emit_command(&SentCommand::PlaySoundboardSound(sound.clone().into()))
.await
};

if let Err(e) = client
.emit_command(&SentCommand::PlaySoundboardSound(sound.clone().into()))
.await
{
if let Err(e) = result {
log::error!("Failed to play soundboard sound: {}", e);
instance.show_alert().await?;
}
Expand Down
15 changes: 8 additions & 7 deletions src/actions/video.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::client::discord_client;
use crate::client::get_discord_client;

use std::collections::HashMap;

Expand All @@ -17,14 +17,15 @@ impl Action for ToggleVideoAction {
instance: &Instance,
_settings: &Self::Settings,
) -> OpenActionResult<()> {
let mut client_lock = discord_client().write().await;
let Some(client) = client_lock.as_mut() else {
log::error!("Discord client not initialized");
instance.show_alert().await?;
return Ok(());
let result = {
let Some(mut client) = get_discord_client(instance).await? else {
return Ok(());
};

client.emit_command(&SentCommand::ToggleVideo).await
};

if let Err(e) = client.emit_command(&SentCommand::ToggleVideo).await {
if let Err(e) = result {
log::error!("Failed to toggle video: {}", e);
instance.show_alert().await?;
}
Expand Down
Loading