diff --git a/src/Lurker.UI/Assets/TradeAlert.mp3 b/src/Lurker.UI/Assets/TradeAlert.mp3
new file mode 100644
index 00000000..21e55bde
Binary files /dev/null and b/src/Lurker.UI/Assets/TradeAlert.mp3 differ
diff --git a/src/Lurker.UI/Lurker.UI.csproj b/src/Lurker.UI/Lurker.UI.csproj
index 65edfd50..b6d76153 100644
--- a/src/Lurker.UI/Lurker.UI.csproj
+++ b/src/Lurker.UI/Lurker.UI.csproj
@@ -83,6 +83,9 @@
..\..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Rocks.dll
+
+ ..\..\packages\NAudio.1.9.0\lib\net35\NAudio.dll
+
..\..\packages\NLog.4.6.8\lib\net45\NLog.dll
@@ -265,6 +268,7 @@
+
TextTemplatingFileGenerator
Svg.cs
diff --git a/src/Lurker.UI/ViewModels/SettingsViewModel.cs b/src/Lurker.UI/ViewModels/SettingsViewModel.cs
index 6f3ce048..e1358aa1 100644
--- a/src/Lurker.UI/ViewModels/SettingsViewModel.cs
+++ b/src/Lurker.UI/ViewModels/SettingsViewModel.cs
@@ -19,6 +19,7 @@ public class SettingsViewModel: ScreenBase
private SettingsService _settingService;
private UpdateManager _updateManager;
private bool _needsUpdate;
+ private int _alertVolume;
#endregion
@@ -34,6 +35,8 @@ public SettingsViewModel(IWindowManager windowManager, KeyboardHelper keyboardHe
this._settingService = settingsService;
this._updateManager = updateManager;
this.DisplayName = "Settings";
+
+ this.PropertyChanged += this.SettingsViewModel_PropertyChanged;
}
#endregion
@@ -125,6 +128,40 @@ public string StillInterestedMessage
}
}
+ ///
+ /// Gets or sets a value indicating whether [alert enabled].
+ ///
+ public bool AlertEnabled
+ {
+ get
+ {
+ return this._settingService.AlertEnabled;
+ }
+
+ set
+ {
+ this._settingService.AlertEnabled = value;
+ this.NotifyOfPropertyChange();
+ }
+ }
+
+ ///
+ /// Gets or sets the alert volume.
+ ///
+ public int AlertVolume
+ {
+ get
+ {
+ return this._alertVolume;
+ }
+
+ set
+ {
+ this._alertVolume = value;
+ this.NotifyOfPropertyChange();
+ }
+ }
+
#endregion
#region Methods
@@ -180,6 +217,7 @@ protected override void OnDeactivate(bool close)
///
protected override void OnActivate()
{
+ this.AlertVolume = (int)(this._settingService.AlertVolume * 100);
this.CheckForUpdate();
base.OnActivate();
}
@@ -192,6 +230,19 @@ private async void CheckForUpdate()
this.NeedsUpdate = await this._updateManager.CheckForUpdate();
}
+ ///
+ /// Handles the PropertyChanged event of the SettingsViewModel control.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ private void SettingsViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == nameof(this.AlertVolume))
+ {
+ this._settingService.AlertVolume = (float)this.AlertVolume / 100;
+ }
+ }
+
#endregion
}
}
diff --git a/src/Lurker.UI/ViewModels/ShellViewModel.cs b/src/Lurker.UI/ViewModels/ShellViewModel.cs
index 5f878e41..cc7d7dcc 100644
--- a/src/Lurker.UI/ViewModels/ShellViewModel.cs
+++ b/src/Lurker.UI/ViewModels/ShellViewModel.cs
@@ -279,9 +279,12 @@ private void CurrentLurker_PoeClosed(object sender, System.EventArgs e)
this._container.UnregisterHandler();
this._container.UnregisterHandler();
- this._clipboardLurker.Newitem -= this.ClipboardLurker_Newitem;
- this._clipboardLurker.Dispose();
- this._clipboardLurker = null;
+ if (this._clipboardLurker != null)
+ {
+ this._clipboardLurker.Newitem -= this.ClipboardLurker_Newitem;
+ this._clipboardLurker.Dispose();
+ this._clipboardLurker = null;
+ }
this._currentLurker.PoeClosed -= this.CurrentLurker_PoeClosed;
this._currentLurker.Dispose();
diff --git a/src/Lurker.UI/ViewModels/TradebarViewModel.cs b/src/Lurker.UI/ViewModels/TradebarViewModel.cs
index 15a75f53..986cf307 100644
--- a/src/Lurker.UI/ViewModels/TradebarViewModel.cs
+++ b/src/Lurker.UI/ViewModels/TradebarViewModel.cs
@@ -11,6 +11,7 @@ namespace Lurker.UI.ViewModels
using Lurker.Services;
using Lurker.UI.Helpers;
using Lurker.UI.Models;
+ using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -236,12 +237,41 @@ private void Lurker_PoeClosed(object sender, EventArgs e)
/// The trade event.
private void Lurker_NewOffer(object sender, Events.TradeEvent e)
{
+ if (this._settingsService.AlertEnabled)
+ {
+ this.PlayAlert();
+ }
+
Execute.OnUIThread(() =>
{
this.TradeOffers.Add(new OfferViewModel(e, this._keyboardHelper, this._context, this._settingsService));
});
}
+ ///
+ /// Plays the alert.
+ ///
+ private void PlayAlert()
+ {
+ var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("Lurker.UI.Assets.TradeAlert.mp3");
+ var waveOut = new WaveOutEvent();
+ var mp3Reader = new Mp3FileReader(stream);
+ waveOut.Init(mp3Reader);
+ waveOut.Volume = this._settingsService.AlertVolume;
+ waveOut.Play();
+
+ EventHandler handler = default;
+ handler = (object s, StoppedEventArgs e) =>
+ {
+ stream.Dispose();
+ mp3Reader.Dispose();
+ waveOut.Dispose();
+ waveOut.PlaybackStopped -= handler;
+ };
+
+ waveOut.PlaybackStopped += handler;
+ }
+
///
/// Lurkers the trade accepted.
///
diff --git a/src/Lurker.UI/Views/SettingsView.xaml b/src/Lurker.UI/Views/SettingsView.xaml
index eddcb470..f7d909d2 100644
--- a/src/Lurker.UI/Views/SettingsView.xaml
+++ b/src/Lurker.UI/Views/SettingsView.xaml
@@ -14,18 +14,8 @@
-
+
-
-
-
-
-
-
-
-
-
-
@@ -109,6 +99,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -122,7 +151,7 @@
+
diff --git a/src/Lurker/Models/Settings.cs b/src/Lurker/Models/Settings.cs
index a065b33a..537d5789 100644
--- a/src/Lurker/Models/Settings.cs
+++ b/src/Lurker/Models/Settings.cs
@@ -42,6 +42,16 @@ public sealed class Settings: SettingsBase
///
public bool SearchEnabled { get; set; }
+ ///
+ /// Gets or sets a value indicating whether [alert enabled].
+ ///
+ public bool AlertEnabled { get; set; }
+
+ ///
+ /// Gets or sets the alert volume.
+ ///
+ public float AlertVolume { get; set; }
+
#endregion
}
}
diff --git a/src/Lurker/Services/SettingsService.cs b/src/Lurker/Services/SettingsService.cs
index d8415d26..754c70fa 100644
--- a/src/Lurker/Services/SettingsService.cs
+++ b/src/Lurker/Services/SettingsService.cs
@@ -20,6 +20,7 @@ public class SettingsService
private static readonly string DefaultSoldMessage = $"I'm sorry, my {TokenHelper.ItemName} has already been sold.";
private static readonly string DefaultBusyMessage = "I'm busy right now I'll send you a party invite.";
private static readonly string DefaultThankYouMessage = string.Empty;
+ private static readonly float DefaultAlertVolume = 1;
private Settings _settings;
@@ -49,6 +50,7 @@ public SettingsService()
this.SoldMessage = DefaultSoldMessage;
this.StillInterestedMessage = DefaultStillInterestedMessage;
this.ThankYouMessage = DefaultThankYouMessage;
+ this.AlertVolume = DefaultAlertVolume;
this.Save();
}
else
@@ -182,6 +184,38 @@ public bool SearchEnabled
}
}
+ ///
+ /// Gets or sets a value indicating whether [alert enabled].
+ ///
+ public bool AlertEnabled
+ {
+ get
+ {
+ return this._settings.AlertEnabled;
+ }
+
+ set
+ {
+ this._settings.AlertEnabled = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the alert volume.
+ ///
+ public float AlertVolume
+ {
+ get
+ {
+ return this._settings.AlertVolume;
+ }
+
+ set
+ {
+ this._settings.AlertVolume = value;
+ }
+ }
+
#endregion
#region Methods