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
50 changes: 28 additions & 22 deletions Aerochat/Aerochat.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup Label="Globals">
<WebView2LoaderPreference>Static</WebView2LoaderPreference>
Expand Down Expand Up @@ -613,27 +613,33 @@
<Resource Include="Resources\ScrollBar\UpGlyphActive.png" />
<Resource Include="Resources\ScrollBar\UpGlyphHover.png" />
<Resource Include="Resources\ScrollBar\UpGlyphInactive.png" />
<Resource Include="Resources\Sounds\newalert.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Sounds\newemail.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Sounds\nudge.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Sounds\online.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Sounds\outgoing.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Sounds\phone.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Sounds\type.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Content Include="Resources\Sounds\newalert.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Resources\Sounds\newemail.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Resources\Sounds\nudge.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Resources\Sounds\online.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Resources\Sounds\outgoing.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Resources\Sounds\phone.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Resources\Sounds\type.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Resources\Sounds\joincall.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Resources\Sounds\leavecall.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Resource Include="Resources\Titlebar\Vista\Close.png" />
<Resource Include="Resources\Titlebar\Vista\CloseActive.png" />
<Resource Include="Resources\Titlebar\Vista\CloseHover.png" />
Expand Down
10 changes: 5 additions & 5 deletions Aerochat/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Aerochat.Hoarder;
using Aerochat.Hoarder;
using Aerochat.ViewModels;
using Aerochat.Windows;
using Aerochat.Settings;
Expand Down Expand Up @@ -550,7 +550,7 @@ await Current.Dispatcher.InvokeAsync(() =>
});
noti.Show();

mediaPlayer.Open(new Uri("Resources/Sounds/online.wav", UriKind.Relative));
mediaPlayer.Open(Helpers.SoundHelper.GetSoundUri("online.wav"));
});

};
Expand Down Expand Up @@ -627,13 +627,13 @@ await Current.Dispatcher.InvokeAsync(() =>

if (isNudge)
{
if (SettingsManager.Instance.PlayNotificationSounds) //toggle sound
mediaPlayer.Open(new Uri("Resources/Sounds/nudge.wav", UriKind.Relative));
if (SettingsManager.Instance.PlayNotificationSounds)
mediaPlayer.Open(Helpers.SoundHelper.GetSoundUri("nudge.wav"));
}
else
{
if (SettingsManager.Instance.PlayNotificationSounds)
mediaPlayer.Open(new Uri("Resources/Sounds/type.wav", UriKind.Relative));
mediaPlayer.Open(Helpers.SoundHelper.GetSoundUri("type.wav"));
}
});
};
Expand Down
29 changes: 29 additions & 0 deletions Aerochat/Helpers/SoundHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.IO;
using System.Windows.Media;

namespace Aerochat.Helpers
{
public static class SoundHelper
{
private static readonly string SoundBase = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory, "Resources", "Sounds");

private static MediaPlayer _sfxPlayer;

public static Uri GetSoundUri(string fileName)
{
return new Uri(Path.Combine(SoundBase, fileName), UriKind.Absolute);
}

public static void PlaySound(string fileName)
{
if (_sfxPlayer == null)
{
_sfxPlayer = new MediaPlayer();
_sfxPlayer.MediaOpened += (s, e) => _sfxPlayer.Play();
}
_sfxPlayer.Open(GetSoundUri(fileName));
}
}
}
Binary file added Aerochat/Resources/Sounds/joincall.wav
Binary file not shown.
Binary file added Aerochat/Resources/Sounds/leavecall.wav
Binary file not shown.
9 changes: 8 additions & 1 deletion Aerochat/ViewModels/User.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using DSharpPlus.Entities;
using DSharpPlus.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -20,6 +20,13 @@ public class UserViewModel : ViewModelBase
private SceneViewModel? _scene;
private string? _color = "#525252";
private string? _image;
private bool _isSpeaking;

public bool IsSpeaking
{
get => _isSpeaking;
set => SetProperty(ref _isSpeaking, value);
}

public required string Name
{
Expand Down
107 changes: 104 additions & 3 deletions Aerochat/Voice/VoiceManager.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
using Aerochat.Hoarder;
using Aerochat.Hoarder;
using Aerochat.ViewModels;
using Aerochat.Windows;
using Aerovoice.Clients;
using DSharpPlus.Entities;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace Aerochat.Voice
{
Expand All @@ -25,10 +24,81 @@ public ChannelViewModel? ChannelVM
set => SetProperty(ref _channelVM, value);
}

public event EventHandler<(ulong UserId, bool IsSpeaking)> UserSpeakingChanged;
public event EventHandler<bool> ClientSpeakingChanged;

private readonly ConcurrentDictionary<ulong, float> _userVolumes = new();
private readonly ConcurrentDictionary<ulong, bool> _userMuted = new();

public bool SelfMuted
{
get => voiceSocket?.SelfMuted ?? false;
set { if (voiceSocket != null) voiceSocket.SelfMuted = value; }
}

public bool SelfDeafened
{
get => voiceSocket?.SelfDeafened ?? false;
set { if (voiceSocket != null) voiceSocket.SelfDeafened = value; }
}

public float ClientTransmitVolume
{
get => voiceSocket?.Player.ClientTransmitVolume ?? 1.0f;
set { if (voiceSocket != null) voiceSocket.Player.ClientTransmitVolume = value; }
}

public void SetUserVolume(ulong userId, float volume)
{
_userVolumes[userId] = volume;
ApplyVolumeForUser(userId);
}

public float GetUserVolume(ulong userId)
{
return _userVolumes.TryGetValue(userId, out var vol) ? vol : 1.0f;
}

public void SetUserMuted(ulong userId, bool muted)
{
_userMuted[userId] = muted;
ApplyMuteForUser(userId);
}

public bool IsUserMuted(ulong userId)
{
return _userMuted.TryGetValue(userId, out var m) && m;
}

private IEnumerable<uint> GetSsrcsForUser(ulong userId)
{
if (voiceSocket == null) return Array.Empty<uint>();
return voiceSocket.SsrcToUserId
.Where(kvp => kvp.Value == userId)
.Select(kvp => kvp.Key);
}

private void ApplyVolumeForUser(ulong userId)
{
if (voiceSocket == null) return;
float vol = _userVolumes.TryGetValue(userId, out var v) ? v : 1.0f;
foreach (var ssrc in GetSsrcsForUser(userId))
voiceSocket.Player.SetSsrcVolume(ssrc, vol);
}

private void ApplyMuteForUser(ulong userId)
{
if (voiceSocket == null) return;
bool muted = _userMuted.TryGetValue(userId, out var m) && m;
foreach (var ssrc in GetSsrcsForUser(userId))
voiceSocket.Player.SetSsrcMuted(ssrc, muted);
}

public async Task LeaveVoiceChannel()
{
if (voiceSocket is null)
return;
UnsubscribeEvents();
await voiceSocket.DisconnectAndDispose();
voiceSocket = null;
ChannelVM = null;
Expand All @@ -38,9 +108,40 @@ public async Task JoinVoiceChannel(DiscordChannel channel)
{
await LeaveVoiceChannel();
voiceSocket = new(Discord.Client);
SubscribeEvents();
await voiceSocket.ConnectAsync(channel);
voiceSocket.Recorder.SetInputDevice(Settings.SettingsManager.Instance.InputDeviceIndex);
ChannelVM = ChannelViewModel.FromChannel(channel);
}

private void SubscribeEvents()
{
if (voiceSocket == null) return;
voiceSocket.UserSpeakingChanged += OnUserSpeakingChanged;
voiceSocket.ClientSpeakingChanged += OnClientSpeakingChanged;
}

private void UnsubscribeEvents()
{
if (voiceSocket == null) return;
voiceSocket.UserSpeakingChanged -= OnUserSpeakingChanged;
voiceSocket.ClientSpeakingChanged -= OnClientSpeakingChanged;
}

private void OnUserSpeakingChanged(object? sender, (ulong UserId, bool IsSpeaking) e)
{
if (voiceSocket == null) return;
if (e.IsSpeaking)
{
ApplyMuteForUser(e.UserId);
ApplyVolumeForUser(e.UserId);
}
UserSpeakingChanged?.Invoke(this, e);
}

private void OnClientSpeakingChanged(object? sender, bool isSpeaking)
{
ClientSpeakingChanged?.Invoke(this, isSpeaking);
}
}
}
35 changes: 30 additions & 5 deletions Aerochat/Windows/Chat.xaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Window x:Class="Aerochat.Windows.Chat"
<Window x:Class="Aerochat.Windows.Chat"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
Expand Down Expand Up @@ -477,10 +477,35 @@
<ItemsControl ItemsSource="{Binding ConnectedUsers}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="4,2,0,2">
<controls:ProfilePictureFrame FrameSize="ExtraSmall" UserStatus="{Binding Presence.Status}" />
<TextBlock Margin="4,0,0,0" Opacity="0.5" Text="{Binding Name}" />
</StackPanel>
<Border CornerRadius="3" Padding="0" Margin="0,1,0,1" x:Name="VoiceUserBorder" MouseRightButtonUp="VoiceUserContextMenu_Open">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="Transparent" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSpeaking}" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Color="#3300C853" Offset="0" />
<GradientStop Color="#2200E676" Offset="0.5" />
<GradientStop Color="#1100C853" Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect Color="#00C853" BlurRadius="8" ShadowDepth="0" Opacity="0.4" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<StackPanel Orientation="Horizontal" Margin="4,2,4,2">
<controls:ProfilePictureFrame FrameSize="ExtraSmall" UserStatus="{Binding Presence.Status}" />
<TextBlock Margin="4,0,0,0" Opacity="0.5" Text="{Binding Name}" />
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Expand Down
Loading