Skip to content

Commit a59fa76

Browse files
author
Aytackydln
committed
added Voice Activity layer and added it to the default profile of Discord
1 parent 91bd2e1 commit a59fa76

8 files changed

Lines changed: 271 additions & 21 deletions

File tree

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
1-
namespace AuroraRgb.Profiles.Discord;
1+
using AuroraRgb.Profiles.Discord.Layers;
22

3-
public class Discord() : Application(new LightEventConfig
3+
namespace AuroraRgb.Profiles.Discord;
4+
5+
public class Discord : Application
46
{
5-
Name = "Discord",
6-
ID = "discord",
7-
ProcessNames = ["Discord.exe", "DiscordPTB.exe", "DiscordCanary.exe"],
8-
ProfileType = typeof(DiscordProfile),
9-
OverviewControlType = typeof(Control_Discord),
10-
GameStateType = typeof(GSI.GameStateDiscord),
11-
IconURI = "Resources/betterdiscord.png",
12-
EnableByDefault = false
13-
});
7+
public Discord() : base(new LightEventConfig
8+
{
9+
Name = "Discord",
10+
ID = "discord",
11+
ProcessNames = ["Discord.exe", "DiscordPTB.exe", "DiscordCanary.exe"],
12+
ProfileType = typeof(DiscordProfile),
13+
OverviewControlType = typeof(Control_Discord),
14+
GameStateType = typeof(GSI.GameStateDiscord),
15+
IconURI = "Resources/betterdiscord.png",
16+
EnableByDefault = false
17+
})
18+
{
19+
AllowLayer<DiscordVoiceActivityLayerHandler>();
20+
}
21+
}

Project-Aurora/Project-Aurora/Profiles/Discord/DiscordProfile.cs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Drawing;
22
using AuroraRgb.EffectsEngine;
3+
using AuroraRgb.Profiles.Discord.Layers;
34
using AuroraRgb.Settings;
45
using AuroraRgb.Settings.Layers;
56
using AuroraRgb.Settings.Overrides.Logic;
@@ -17,14 +18,14 @@ public override void Reset()
1718
var overrideLookupTableBuilder = new OverrideLookupTableBuilder<Color>();
1819
overrideLookupTableBuilder.AddEntry(Color.Red, new BooleanGSIBoolean("User/SelfMute"));
1920

20-
OverlayLayers = new System.Collections.ObjectModel.ObservableCollection<Layer>
21-
{
21+
OverlayLayers =
22+
[
2223
new("Mic Status", new SolidColorLayerHandler
2324
{
2425
Properties = new LayerHandlerProperties
2526
{
2627
_PrimaryColor = Color.Lime,
27-
_Sequence = new KeySequence(new[] { DeviceKeys.PAUSE_BREAK })
28+
_Sequence = new KeySequence([DeviceKeys.PAUSE_BREAK])
2829
}
2930
}, new OverrideLogicBuilder()
3031
.SetDynamicBoolean("_Enabled", new StringComparison(
@@ -39,7 +40,7 @@ public override void Reset()
3940
Properties = new LayerHandlerProperties
4041
{
4142
_PrimaryColor = Color.Yellow,
42-
_Sequence = new KeySequence(new[] { DeviceKeys.PRINT_SCREEN })
43+
_Sequence = new KeySequence([DeviceKeys.PRINT_SCREEN])
4344
}
4445
}, new OverrideLogicBuilder().SetDynamicBoolean("_Enabled", new BooleanGSIBoolean("User/Mentions"))),
4546

@@ -48,9 +49,19 @@ public override void Reset()
4849
Properties = new LayerHandlerProperties
4950
{
5051
_PrimaryColor = Color.LightBlue,
51-
_Sequence = new KeySequence(new[] { DeviceKeys.PRINT_SCREEN, DeviceKeys.SCROLL_LOCK, DeviceKeys.PAUSE_BREAK })
52+
_Sequence = new KeySequence([DeviceKeys.PRINT_SCREEN, DeviceKeys.SCROLL_LOCK, DeviceKeys.PAUSE_BREAK])
5253
}
5354
}, new OverrideLogicBuilder().SetDynamicBoolean("_Enabled", new BooleanGSIBoolean("User/UnreadMessages"))),
54-
};
55+
56+
new ("Voice Activity", new DiscordVoiceActivityLayerHandler
57+
{
58+
Properties = new DiscordVoiceActivityLayerHandlerProperties
59+
{
60+
_Sequence = new KeySequence([
61+
DeviceKeys.INSERT, DeviceKeys.HOME, DeviceKeys.PAGE_UP, DeviceKeys.DELETE, DeviceKeys.END, DeviceKeys.PAGE_DOWN
62+
])
63+
}
64+
}),
65+
];
5566
}
5667
}

Project-Aurora/Project-Aurora/Profiles/Discord/GSI/GameState_Discord.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1-
using System.Text.Json.Serialization;
1+
using System.Collections.Generic;
2+
using System.Text.Json.Serialization;
23
using AuroraRgb.Profiles.Discord.GSI.Nodes;
34
using AuroraRgb.Profiles.Generic;
45

56
namespace AuroraRgb.Profiles.Discord.GSI;
67

7-
public partial class GameStateDiscord : GameState
8+
[method: JsonConstructor]
9+
public partial class GameStateDiscord(Dictionary<string, VoiceParticipantNode> participants) : GameState
810
{
9-
public static readonly GameStateDiscord Default = new();
10-
11+
public GameStateDiscord() : this([])
12+
{
13+
}
14+
15+
public static readonly GameStateDiscord Default = new([]);
16+
1117
[JsonPropertyName("provider")]
1218
public ProviderNode Provider { get; set; } = ProviderNode.Default;
1319

@@ -22,4 +28,7 @@ public partial class GameStateDiscord : GameState
2228

2329
[JsonPropertyName("voice")]
2430
public VoiceNode Voice { get; set; } = VoiceNode.Default;
31+
32+
[JsonPropertyName("voice_participants")]
33+
public Dictionary<string, VoiceParticipantNode> Participants { get; set; } = participants;
2534
}

Project-Aurora/Project-Aurora/Profiles/Discord/GSI/Nodes/UserNode.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,15 @@ public string StatusJson
2727
set => Status = GetStatus(value);
2828
}
2929

30+
[JsonPropertyName("mute")]
31+
public bool Mute { get; set; }
32+
3033
[JsonPropertyName("self_mute")]
3134
public bool SelfMute { get; set; }
3235

36+
[JsonPropertyName("deafen")]
37+
public bool Deaf { get; set; }
38+
3339
[JsonPropertyName("self_deafen")]
3440
public bool SelfDeafen { get; set; }
3541

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace AuroraRgb.Profiles.Discord.GSI.Nodes;
4+
5+
public class VoiceParticipantNode
6+
{
7+
[JsonPropertyName("userId")]
8+
public string UserId { get; set; } = string.Empty;
9+
10+
[JsonPropertyName("is_speaking")]
11+
public bool IsSpeaking { get; set; }
12+
13+
[JsonPropertyName("mute")]
14+
public bool IsMuted { get; set; }
15+
16+
[JsonPropertyName("deaf")]
17+
public bool IsDeafened { get; set; }
18+
19+
[JsonPropertyName("selfMute")]
20+
public bool IsSelfMuted { get; set; }
21+
22+
[JsonPropertyName("selfDeaf")]
23+
public bool IsSelfDeafened { get; set; }
24+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<UserControl x:Class="AuroraRgb.Profiles.Discord.Layers.ControlDiscordVoiceActivityLayer"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6+
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
7+
xmlns:controls="clr-namespace:AuroraRgb.Controls"
8+
mc:Ignorable="d" Loaded="UserControl_Loaded">
9+
<Grid>
10+
<Grid.ColumnDefinitions>
11+
<ColumnDefinition Width="Auto"/>
12+
<ColumnDefinition/>
13+
</Grid.ColumnDefinitions>
14+
<Grid.RowDefinitions>
15+
<RowDefinition Height="Auto"/>
16+
<RowDefinition Height="Auto"/>
17+
<RowDefinition/>
18+
</Grid.RowDefinitions>
19+
<Label HorizontalAlignment="Left" Padding="0" Content="Muted Color:" VerticalAlignment="Top" Margin="0,2,0,0"/>
20+
<xctk:ColorPicker Grid.Row="0" Grid.Column="1" x:Name="MutedColorPicker" Margin="6,0,0,0" Height="20" VerticalAlignment="Top" HorizontalAlignment="Left" Width="160"
21+
UsingAlphaChannel="True" ColorMode="ColorCanvas" SelectedColorChanged="ColorPicker_Muted_SelectedColorChanged" />
22+
<Label Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" Margin="0,0,0,0" Padding="0" Content="Speaking Color:" VerticalAlignment="Top"/>
23+
<xctk:ColorPicker Grid.Row="1" Grid.Column="1" x:Name="SpeakingColorPicker" Margin="6,0,0,0" Height="20" VerticalAlignment="Top" HorizontalAlignment="Left" Width="160"
24+
ColorMode="ColorCanvas" SelectedColorChanged="ColorPicker_Speaking_SelectedColorChanged" UsingAlphaChannel="True" />
25+
<Label Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" Margin="0,0,0,0" Padding="0" Content="Default Color:" VerticalAlignment="Top"/>
26+
<xctk:ColorPicker Grid.Row="2" Grid.Column="1" x:Name="DefaultColorPicker" Margin="6,0,0,0" Height="20" VerticalAlignment="Top" HorizontalAlignment="Left" Width="160"
27+
ColorMode="ColorCanvas" SelectedColorChanged="ColorPicker_Default_SelectedColorChanged" UsingAlphaChannel="True" />
28+
<controls:KeySequence x:Name="KeySequenceControl" Grid.Row="0" Grid.Column="1" Grid.RowSpan="3" Margin="254,0,0,0" RecordingTag="Discord - Voice Activity" Title="Affected Keys"
29+
SequenceUpdated="KeySequence_keys_SequenceUpdated" HorizontalAlignment="Left" Width="230"/>
30+
</Grid>
31+
</UserControl>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using System.Windows;
2+
using System.Windows.Media;
3+
using AuroraRgb.Settings;
4+
using AuroraRgb.Utils;
5+
using Xceed.Wpf.Toolkit;
6+
7+
namespace AuroraRgb.Profiles.Discord.Layers;
8+
9+
/// <summary>
10+
/// Interaction logic for Control_CSGOBackgroundLayer.xaml
11+
/// </summary>
12+
public partial class ControlDiscordVoiceActivityLayer
13+
{
14+
private bool _settingsSet;
15+
16+
public ControlDiscordVoiceActivityLayer()
17+
{
18+
InitializeComponent();
19+
}
20+
21+
public ControlDiscordVoiceActivityLayer(DiscordVoiceActivityLayerHandler dataContext)
22+
{
23+
InitializeComponent();
24+
25+
DataContext = dataContext;
26+
}
27+
28+
public void SetSettings()
29+
{
30+
if (DataContext is not DiscordVoiceActivityLayerHandler layerHandler || _settingsSet) return;
31+
MutedColorPicker.SelectedColor = ColorUtils.DrawingColorToMediaColor(layerHandler.Properties.MutedColor);
32+
SpeakingColorPicker.SelectedColor = ColorUtils.DrawingColorToMediaColor(layerHandler.Properties.SpeakingColor);
33+
DefaultColorPicker.SelectedColor = ColorUtils.DrawingColorToMediaColor(layerHandler.Properties.DefaultColor);
34+
KeySequenceControl.Sequence = layerHandler.Properties.Sequence;
35+
36+
_settingsSet = true;
37+
}
38+
39+
private void UserControl_Loaded(object? sender, RoutedEventArgs e)
40+
{
41+
SetSettings();
42+
43+
Loaded -= UserControl_Loaded;
44+
}
45+
46+
private void ColorPicker_Muted_SelectedColorChanged(object? sender, RoutedPropertyChangedEventArgs<Color?> e)
47+
{
48+
if (IsLoaded && _settingsSet && DataContext is DiscordVoiceActivityLayerHandler layerHandler && sender is ColorPicker { SelectedColor: not null } picker)
49+
layerHandler.Properties.MutedColor = ColorUtils.MediaColorToDrawingColor(picker.SelectedColor.Value);
50+
}
51+
52+
private void ColorPicker_Speaking_SelectedColorChanged(object? sender, RoutedPropertyChangedEventArgs<Color?> e)
53+
{
54+
if (IsLoaded && _settingsSet && DataContext is DiscordVoiceActivityLayerHandler layerHandler && sender is ColorPicker { SelectedColor: not null } picker)
55+
layerHandler.Properties.SpeakingColor = ColorUtils.MediaColorToDrawingColor(picker.SelectedColor.Value);
56+
}
57+
58+
private void ColorPicker_Default_SelectedColorChanged(object? sender, RoutedPropertyChangedEventArgs<Color?> e)
59+
{
60+
if (IsLoaded && _settingsSet && DataContext is DiscordVoiceActivityLayerHandler layerHandler && sender is ColorPicker { SelectedColor: not null } picker)
61+
layerHandler.Properties.DefaultColor = ColorUtils.MediaColorToDrawingColor(picker.SelectedColor.Value);
62+
}
63+
64+
private void KeySequence_keys_SequenceUpdated(object? sender, RoutedPropertyChangedEventArgs<KeySequence> e)
65+
{
66+
if (IsLoaded && _settingsSet && DataContext is DiscordVoiceActivityLayerHandler layerHandler)
67+
{
68+
layerHandler.Properties.Sequence = e.NewValue;
69+
}
70+
}
71+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using System.Drawing;
2+
using System.Linq;
3+
using System.Windows.Controls;
4+
using AuroraRgb.EffectsEngine;
5+
using AuroraRgb.Profiles.Discord.GSI;
6+
using AuroraRgb.Settings.Layers;
7+
using Newtonsoft.Json;
8+
9+
namespace AuroraRgb.Profiles.Discord.Layers;
10+
11+
public partial class DiscordVoiceActivityLayerHandlerProperties : LayerHandlerProperties2Color
12+
{
13+
private Color? _defaultColor;
14+
public Color DefaultColor
15+
{
16+
get => Logic?._DefaultColor ?? _defaultColor ?? Color.Empty;
17+
set => _defaultColor = value;
18+
}
19+
20+
private Color? _speakingColor;
21+
public Color SpeakingColor
22+
{
23+
get => Logic?.SpeakingColor ?? _speakingColor ?? Color.Empty;
24+
set => _speakingColor = value;
25+
}
26+
27+
private Color? _mutedColor;
28+
public Color MutedColor
29+
{
30+
get => Logic?.MutedColor ?? _mutedColor ?? Color.Empty;
31+
set => _mutedColor = value;
32+
}
33+
34+
public override void Default()
35+
{
36+
base.Default();
37+
38+
_defaultColor = Color.FromArgb(0, 124, 255);
39+
_speakingColor = Color.FromArgb(33, 255, 40);
40+
_mutedColor = Color.Red;
41+
}
42+
}
43+
44+
public class DiscordVoiceActivityLayerHandler() : LayerHandler<DiscordVoiceActivityLayerHandlerProperties>("Discord Layer Activity")
45+
{
46+
private readonly Color _transparent = Color.Transparent;
47+
private int _lastParticipantCount;
48+
49+
protected override UserControl CreateControl()
50+
{
51+
return new ControlDiscordVoiceActivityLayer(this);
52+
}
53+
54+
public override EffectLayer Render(IGameState gameState)
55+
{
56+
if (gameState is not GameStateDiscord discordState) return EmptyLayer.Instance;
57+
58+
if (Invalidated || discordState.Participants.Count != _lastParticipantCount)
59+
{
60+
EffectLayer.Clear();
61+
Invalidated = false;
62+
}
63+
64+
_lastParticipantCount = discordState.Participants.Count;
65+
var participantIds = discordState.Participants.Keys;
66+
var keySequence = Properties.Sequence.Keys;
67+
68+
var index = 0;
69+
foreach (var key in keySequence)
70+
{
71+
var participantId = participantIds.ElementAtOrDefault(index++);
72+
if (participantId == null)
73+
{
74+
EffectLayer.Set(key, in _transparent);
75+
continue;
76+
}
77+
78+
var participant = discordState.Participants[participantId];
79+
80+
if (participant.IsMuted || participant.IsSelfMuted)
81+
EffectLayer.Set(key, Properties.MutedColor);
82+
else if (participant.IsSpeaking)
83+
EffectLayer.Set(key, Properties.SpeakingColor);
84+
else
85+
EffectLayer.Set(key, Properties.DefaultColor);
86+
}
87+
88+
return EffectLayer;
89+
}
90+
}

0 commit comments

Comments
 (0)