221 lines
6.9 KiB
C#
221 lines
6.9 KiB
C#
using System;
|
|
using System.ComponentModel;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Markup;
|
|
using System.Windows.Media.Imaging;
|
|
using System.Windows.Threading;
|
|
using Windows.Data.Xml.Dom;
|
|
using Windows.UI.Notifications;
|
|
using Hardcodet.Wpf.TaskbarNotification;
|
|
using Microsoft.Toolkit.Uwp.Notifications;
|
|
using ModernWpf;
|
|
using Sentry;
|
|
using XIVChatCommon.Message;
|
|
using XIVChatCommon.Message.Server;
|
|
|
|
namespace XIVChat_Desktop {
|
|
/// <summary>
|
|
/// Interaction logic for App.xaml
|
|
/// </summary>
|
|
public partial class App : INotifyPropertyChanged, IDisposable {
|
|
public MainWindow Window { get; private set; } = null!;
|
|
public Configuration Config { get; private set; } = null!;
|
|
|
|
private Lazy<TaskbarIcon> TaskbarIcon { get; } = new(() => new TaskbarIcon {
|
|
IconSource = new BitmapImage(new Uri("pack://application:,,,/Resources/logo.ico")),
|
|
});
|
|
|
|
public string? LastHost { get; set; }
|
|
|
|
public Connection? Connection { get; set; }
|
|
|
|
public bool Connected => this.Connection != null;
|
|
|
|
public event PropertyChangedEventHandler? PropertyChanged;
|
|
|
|
private IDisposable? Sentry { get; }
|
|
|
|
public App() {
|
|
#if RELEASE
|
|
this.Sentry = SentrySdk.Init("https://cc5b1feb6e5945d7bcacc577e5d13f88@o513776.ingest.sentry.io/5616282");
|
|
this.DispatcherUnhandledException += UploadException;
|
|
#endif
|
|
}
|
|
|
|
private static void UploadException(object sender, DispatcherUnhandledExceptionEventArgs e) {
|
|
SentrySdk.CaptureException(e.Exception);
|
|
}
|
|
|
|
private async void Application_Startup(object sender, StartupEventArgs e) {
|
|
try {
|
|
this.Config = Configuration.Load() ?? new Configuration();
|
|
} catch (Exception ex) {
|
|
var result = MessageBox.Show(
|
|
$"Could not load the configuration file: {ex.Message}. Do you want to create a new configuration file and overwrite the old one?",
|
|
"Error loading config",
|
|
MessageBoxButton.YesNo
|
|
);
|
|
|
|
if (result == MessageBoxResult.Yes) {
|
|
this.Config = new Configuration();
|
|
} else {
|
|
this.Shutdown(1);
|
|
return;
|
|
}
|
|
}
|
|
|
|
try {
|
|
this.Config.Save();
|
|
} catch (Exception ex) {
|
|
MessageBox.Show($"Could not save configuration file. {ex.Message}");
|
|
}
|
|
|
|
this.Config.PropertyChanged += (_, args) => {
|
|
if (args.PropertyName != nameof(Configuration.Theme)) {
|
|
return;
|
|
}
|
|
|
|
this.UpdateTheme();
|
|
};
|
|
|
|
this.UpdateTheme();
|
|
|
|
LocaliseAllElements();
|
|
|
|
// I guess this gets initialised where you call it the first time, so initialise it on the UI thread
|
|
this.Dispatcher.Invoke(() => {
|
|
});
|
|
|
|
#if RELEASE
|
|
if (string.IsNullOrWhiteSpace(this.Config.LicenceKey) || !(await LicenceWindow.LicenceInfo(this.Config.LicenceKey)).Valid()) {
|
|
var lic = new LicenceWindow(null, true);
|
|
lic.Show();
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
this.InitialiseWindow();
|
|
}
|
|
|
|
private static void LocaliseAllElements() {
|
|
FrameworkElement.LanguageProperty.OverrideMetadata(
|
|
typeof(FrameworkElement),
|
|
new FrameworkPropertyMetadata(
|
|
XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)
|
|
)
|
|
);
|
|
}
|
|
|
|
public void InitialiseWindow() {
|
|
var wnd = new MainWindow();
|
|
this.Window = wnd;
|
|
|
|
wnd.Show();
|
|
|
|
// initialise a config window to apply all our settings
|
|
_ = new ConfigWindow(wnd, this.Config);
|
|
}
|
|
|
|
private void UpdateTheme() {
|
|
ThemeManager.Current.ApplicationTheme = this.Config.Theme switch {
|
|
Theme.System => null,
|
|
Theme.Dark => ApplicationTheme.Dark,
|
|
Theme.Light => ApplicationTheme.Light,
|
|
_ => null,
|
|
};
|
|
}
|
|
|
|
public void Connect(SavedServer server) {
|
|
if (this.Connected) {
|
|
return;
|
|
}
|
|
|
|
switch (server) {
|
|
case DirectServer direct:
|
|
this.Connection = new Connection(this, direct);
|
|
break;
|
|
case RelayServer relay:
|
|
this.Connection = new Connection(this, relay);
|
|
break;
|
|
default:
|
|
MessageBox.Show("Unknown server type.");
|
|
return;
|
|
}
|
|
|
|
this.Connection.ReceiveMessage += this.OnReceiveMessage;
|
|
Task.Run(async () => {
|
|
await this.Connection.Connect();
|
|
this.Dispatch(() => this.Connection = null);
|
|
});
|
|
}
|
|
|
|
public void Disconnect() {
|
|
if (!this.Connected) {
|
|
return;
|
|
}
|
|
|
|
this.Connection?.Disconnect();
|
|
this.Connection = null;
|
|
}
|
|
|
|
private static void Win10Notify(string title, string text, string? attribution) {
|
|
var builder = new ToastContentBuilder()
|
|
.AddText(title)
|
|
.AddText(text);
|
|
|
|
if (attribution != null) {
|
|
builder.AddAttributionText(attribution);
|
|
}
|
|
|
|
var content = builder.GetToastContent();
|
|
|
|
var document = new XmlDocument();
|
|
document.LoadXml(content.GetContent());
|
|
var toast = new ToastNotification(document);
|
|
|
|
ToastNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
|
}
|
|
|
|
private void Notify(string title, string text) {
|
|
this.TaskbarIcon.Value.ShowBalloonTip(title, text, BalloonIcon.None);
|
|
}
|
|
|
|
private void OnReceiveMessage(ServerMessage message) {
|
|
if (!this.Config.Notifications.Any(notif => notif.Matches(message))) {
|
|
return;
|
|
}
|
|
|
|
var sender = message.GetSenderPlayer();
|
|
|
|
string title;
|
|
if (sender != null) {
|
|
var name = sender.Name;
|
|
|
|
if (sender.Server != 0) {
|
|
name += $" ({Util.WorldName(sender.Server)})";
|
|
}
|
|
|
|
title = name;
|
|
} else {
|
|
title = "Notification";
|
|
}
|
|
|
|
var text = message.ContentText;
|
|
var attribution = message.Channel.Name();
|
|
|
|
if (Environment.OSVersion.Version.Major < 10) {
|
|
this.Notify(title, text);
|
|
} else {
|
|
Win10Notify(title, text, attribution);
|
|
}
|
|
}
|
|
|
|
public void Dispose() {
|
|
this.Sentry?.Dispose();
|
|
}
|
|
}
|
|
}
|