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
3 changes: 3 additions & 0 deletions assets/encoders/headphonesBig.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions assets/encoders/headphonesBigMuted.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions assets/encoders/microphoneBig.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions assets/encoders/microphoneBigMuted.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions assets/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@
"Icon": "actions/volumeControl",
"Tooltip": "Control the volume levels of audio input and output devices",
"Controllers": ["Keypad", "Encoder"],
"Encoder": {
"layout": "$B1"
},
"PropertyInspectorPath": "pi/volumecontrol.html",
"DisableAutomaticStates": true,
"States": [{ "Image": "actions/volumeControl" }]
Expand Down
1 change: 1 addition & 0 deletions src/actions/voice_settings/audio_device_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub struct AudioDeviceWrapper {
pub device_id: String,
pub volume: f32,
pub available_devices: Vec<VoiceAvailableDevice>,
pub enable: bool,
}

impl From<AudioDeviceWrapper> for SetVoiceSettingsArgs {
Expand Down
110 changes: 109 additions & 1 deletion src/actions/voice_settings/volume_control.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::audio_device_utils::{AudioDeviceType, AudioDeviceWrapper, get_audio_device_settings};
use super::update_voice_setting;

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

Expand Down Expand Up @@ -32,6 +33,55 @@ impl Default for VolumeControlSettings {
}
}

const MUTED_ICON: &str = include_str!("../../../assets/encoders/microphoneBigMuted.svg");
const UNMUTED_ICON: &str = include_str!("../../../assets/encoders/microphoneBig.svg");
const DEAFEN_ICON: &str = include_str!("../../../assets/encoders/headphonesBigMuted.svg");
const UNDEAFEN_ICON: &str = include_str!("../../../assets/encoders/headphonesBig.svg");

async fn update_feedback(
instance: &Instance,
settings: &VolumeControlSettings,
) -> OpenActionResult<()> {
let device_type = &settings.device_type;
let Some(device_settings) = get_audio_device_settings(device_type).await else {
log::error!(
"Failed to obtain voice settings for {:?} device",
device_type
);
instance.show_alert().await?;
return Ok(());
};

let icon = match (device_type, device_settings.enable) {
(AudioDeviceType::Input, true) => UNMUTED_ICON,
(AudioDeviceType::Input, false) => MUTED_ICON,
(AudioDeviceType::Output, true) => UNDEAFEN_ICON,
(AudioDeviceType::Output, false) => DEAFEN_ICON,
};

let value = device_type.to_linear(device_settings.volume) as i32;
let indicator_value = match device_type {
AudioDeviceType::Input => value,
AudioDeviceType::Output => value / 2,
};

let title = match device_type {
AudioDeviceType::Input => "Microphone",
AudioDeviceType::Output => "Headphones",
};

instance
.set_feedback(&serde_json::json!({
"title": title,
"icon": icon,
"value": format!("{}%", value),
"indicator": {
"value": indicator_value
}
}))
.await
}

async fn adjust_volume(
instance: &Instance,
device_type: &AudioDeviceType,
Expand Down Expand Up @@ -69,6 +119,22 @@ impl Action for VolumeControlAction {
const UUID: ActionUuid = "me.amankhanna.oadiscord.volumecontrol";
type Settings = VolumeControlSettings;

async fn will_appear(
&self,
instance: &Instance,
settings: &Self::Settings,
) -> OpenActionResult<()> {
update_feedback(instance, settings).await
}

async fn did_receive_settings(
&self,
instance: &Instance,
settings: &Self::Settings,
) -> OpenActionResult<()> {
update_feedback(instance, settings).await
}

async fn key_up(&self, instance: &Instance, settings: &Self::Settings) -> OpenActionResult<()> {
let value = match settings.action_type {
VolumeControlActionType::Increase => settings.step_size as f32,
Expand All @@ -85,6 +151,49 @@ impl Action for VolumeControlAction {
.await
}

async fn dial_up(
&self,
instance: &Instance,
settings: &Self::Settings,
) -> OpenActionResult<()> {
let device_type = &settings.device_type;
let Some(device_settings) = get_audio_device_settings(device_type).await else {
log::error!(
"Failed to obtain voice settings for {:?} device",
device_type
);
instance.show_alert().await?;
return Ok(());
};

match device_type {
AudioDeviceType::Input => {
let new_mute = device_settings.enable;
update_voice_setting(
instance,
SetVoiceSettingsArgs {
mute: Some(new_mute),
..Default::default()
},
0,
)
.await
}
AudioDeviceType::Output => {
let new_deaf = device_settings.enable;
update_voice_setting(
instance,
SetVoiceSettingsArgs {
deaf: Some(new_deaf),
..Default::default()
},
0,
)
.await
}
}
}

async fn dial_rotate(
&self,
instance: &Instance,
Expand All @@ -93,7 +202,6 @@ impl Action for VolumeControlAction {
_pressed: bool,
) -> OpenActionResult<()> {
let delta = (settings.step_size as f32) * ticks as f32;

adjust_volume(instance, &settings.device_type, delta, false).await
}
}
6 changes: 6 additions & 0 deletions src/rpc_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ async fn apply_voice_state(settings: discord_ipc_rust::models::shared::voice::Vo
device_id: input.device_id,
volume: input.volume,
available_devices: input.available_devices,
enable: !mute && !deaf,
});
}

Expand All @@ -171,9 +172,14 @@ async fn apply_voice_state(settings: discord_ipc_rust::models::shared::voice::Vo
device_id: output.device_id,
volume: output.volume,
available_devices: output.available_devices,
enable: !deaf,
});
}

for instance in visible_instances(crate::actions::VolumeControlAction::UUID).await {
let _ = instance.get_settings().await;
}

for instance in visible_instances(crate::actions::SetAudioDeviceAction::UUID).await {
let _ = crate::actions::voice_settings::set_audio_device::send_available_devices_to_pi(
&instance,
Expand Down