123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469 |
- using InABox.Clients;
- using InABox.Core;
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
- using System.Diagnostics.CodeAnalysis;
- using System.Linq;
- using System.Runtime.CompilerServices;
- using System.Windows;
- using System.Windows.Controls;
- using System.IO;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- using InABox.WPF;
- namespace InABox.Wpf;
- public enum MessageWindowButtonPosition
- {
- Left,
- Right
- }
- public enum MessageWindowResult
- {
- None,
- OK,
- Cancel,
- Yes,
- No,
- Other
- }
- public class MessageWindowButton : INotifyPropertyChanged
- {
- public delegate void MessageWindowButtonDelegate(MessageWindow window, MessageWindowButton button);
- public MessageWindowButtonPosition Position { get; set; }
- private string _content;
- public string Content
- {
- get => _content;
- [MemberNotNull(nameof(_content))]
- set
- {
- _content = value;
- OnPropertyChanged();
- }
- }
- public MessageWindowButtonDelegate Action { get; set; }
- public MessageWindowButton(string content, MessageWindowButtonDelegate action, MessageWindowButtonPosition position)
- {
- Content = content;
- Action = action;
- Position = position;
- }
- public event PropertyChangedEventHandler? PropertyChanged;
- protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
- }
- /// <summary>
- /// Interaction logic for MessageWindow.xaml
- /// </summary>
- public partial class MessageWindow : Window, INotifyPropertyChanged
- {
- public ObservableCollection<MessageWindowButton> Buttons { get; private set; } = new();
- public IEnumerable<MessageWindowButton> LeftButtons => Buttons.Where(x => x.Position == MessageWindowButtonPosition.Left);
- public IEnumerable<MessageWindowButton> RightButtons => Buttons.Where(x => x.Position == MessageWindowButtonPosition.Right);
- private string _message = "";
- public string Message
- {
- get => _message;
- set
- {
- _message = value;
- OnPropertyChanged();
- }
- }
- public ImageSource? _image = null;
- public ImageSource? Image
- {
- get => _image;
- set
- {
- _image = value;
- OnPropertyChanged();
- }
- }
- private string _details = "";
- public string Details
- {
- get => _details;
- set
- {
- _details = value;
- OnPropertyChanged();
- }
- }
- public static readonly DependencyProperty ShowDetailsProperty = DependencyProperty.Register(nameof(ShowDetails), typeof(bool), typeof(MessageWindow));
- public bool ShowDetails
- {
- get => (bool)GetValue(ShowDetailsProperty);
- set => SetValue(ShowDetailsProperty, value);
- }
- public MessageWindowResult Result { get; set; } = MessageWindowResult.None;
- public object? OtherResult { get; set; }
- public MessageWindow()
- {
- InitializeComponent();
- Buttons.CollectionChanged += Buttons_CollectionChanged;
- }
- private void Button_Click(object sender, RoutedEventArgs e)
- {
- if (sender is not Button button || button.Tag is not MessageWindowButton winButton) return;
- winButton.Action(this, winButton);
- }
- private void Buttons_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
- {
- OnPropertyChanged(nameof(LeftButtons));
- OnPropertyChanged(nameof(RightButtons));
- }
- public MessageWindow AddButton(MessageWindowButton button)
- {
- Buttons.Add(button);
- return this;
- }
- public MessageWindow AddOKButton(string content = "OK")
- {
- Buttons.Add(new MessageWindowButton(content, OKButton_Click, MessageWindowButtonPosition.Right));
- return this;
- }
- public MessageWindow AddCancelButton(string content = "Cancel")
- {
- Buttons.Add(new MessageWindowButton(content, CancelButton_Click, MessageWindowButtonPosition.Right));
- return this;
- }
- public MessageWindow AddYesButton(string content = "Yes")
- {
- Buttons.Add(new MessageWindowButton(content, YesButton_Click, MessageWindowButtonPosition.Right));
- return this;
- }
- public MessageWindow AddNoButton(string content = "No")
- {
- Buttons.Add(new MessageWindowButton(content, NoButton_Click, MessageWindowButtonPosition.Right));
- return this;
- }
- private void YesButton_Click(MessageWindow window, MessageWindowButton button)
- {
- Result = MessageWindowResult.Yes;
- Close();
- }
- private void NoButton_Click(MessageWindow window, MessageWindowButton button)
- {
- Result = MessageWindowResult.No;
- Close();
- }
- private void CancelButton_Click(MessageWindow window, MessageWindowButton button)
- {
- Result = MessageWindowResult.Cancel;
- Close();
- }
- private void OKButton_Click(MessageWindow window, MessageWindowButton button)
- {
- Result = MessageWindowResult.OK;
- Close();
- }
- public event PropertyChangedEventHandler? PropertyChanged;
- protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
- #region Static Constructors
- public static readonly BitmapImage _warning = InABox.Wpf.Resources.warning.AsBitmapImage();
- public static BitmapImage WarningImage => _warning;
- public static readonly BitmapImage _question = InABox.Wpf.Resources.help.AsBitmapImage();
- public static BitmapImage QuestionImage => _question;
- public static MessageWindow New()
- {
- return new MessageWindow();
- }
- public static MessageWindow NewMessage(string message, string title, ImageSource? image = null)
- {
- return new MessageWindow()
- .Title(title)
- .Message(message)
- .Image(image)
- .AddOKButton();
- }
- public static void ShowMessage(string message, string title, ImageSource? image = null)
- {
- NewMessage(message, title, image).Display();
- }
- public static MessageWindow NewOKCancel(string message, string title, ImageSource? image = null)
- {
- return new MessageWindow()
- .Title(title)
- .Message(message)
- .Image(image)
- .AddOKButton()
- .AddCancelButton();
- }
- public static bool ShowOKCancel(string message, string title, ImageSource? image = null)
- {
- return NewOKCancel(message, title, image)
- .Display()
- .Result == MessageWindowResult.OK;
- }
- public static MessageWindow NewYesNo(string message, string title, ImageSource? image = null)
- {
- return new MessageWindow()
- .Title(title)
- .Message(message)
- .Image(image)
- .AddYesButton()
- .AddNoButton();
- }
- public static bool ShowYesNo(string message, string title, ImageSource? image = null)
- {
- return NewYesNo(message, title, image)
- .Display()
- .Result == MessageWindowResult.Yes;
- }
- public static MessageWindow NewYesNoCancel(string message, string title, ImageSource? image = null)
- {
- return new MessageWindow()
- .Title(title)
- .Message(message)
- .Image(image)
- .AddYesButton()
- .AddNoButton()
- .AddCancelButton();
- }
- public static MessageWindowResult ShowYesNoCancel(string message, string title, ImageSource? image = null)
- {
- return NewYesNoCancel(message, title, image)
- .Display().Result;
- }
- /// <summary>
- /// Display a message box for an exception, giving options to view the logs.
- /// </summary>
- /// <param name="message">The message to display. Set to <see langword="null"/> to default to the exception message.</param>
- /// <param name="exception"></param>
- /// <param name="title"></param>
- /// <param name="shouldLog">If <see langword="true"/>, also logs the exception.</param>
- public static MessageWindow NewError(string? message, Exception exception, string title = "Error", bool shouldLog = true, ImageSource? image = null)
- {
- if (shouldLog)
- {
- CoreUtils.LogException(ClientFactory.UserID, exception);
- }
- var window = new MessageWindow()
- .Message(message ?? exception.Message)
- .Title(title)
- .Details(CoreUtils.FormatException(exception))
- .Image(image ?? _warning)
- .AddButton(new MessageWindowButton("Email Logs", (window, button) =>
- {
- EmailLogs_Click(exception);
- }, MessageWindowButtonPosition.Left));
- var showDetailsButton = new MessageWindowButton("Show Details", (win, button) =>
- {
- win.ShowDetails = !win.ShowDetails;
- button.Content = win.ShowDetails
- ? "Hide Details"
- : "Show Details";
- }, MessageWindowButtonPosition.Left);
- return window.AddButton(showDetailsButton)
- .AddOKButton();
- }
- private static void EmailLogs_Click(Exception e)
- {
- var logFile = Path.Combine(CoreUtils.GetPath(), string.Format("{0:yyyy-MM-dd}.log", DateTime.Today));
- const int nRead = 1024 * 1024;
- byte[] data;
- using (var stream = File.OpenRead(logFile))
- {
- if (stream.Length > nRead)
- {
- stream.Seek(-nRead, SeekOrigin.End);
- }
- data = new BinaryReader(stream).ReadBytes(Math.Min(nRead, (int)stream.Length));
- }
- var message = EmailUtils.CreateMessage(
- subject: "Error logs",
- to: "support@prsdigital.com.au",
- body: $"Error logs for PRS:\n\nException: {CoreUtils.FormatException(e)}");
- message.AddAttachment("Error Logs.txt", data);
- EmailUtils.OpenEmail(message);
- }
- /// <summary>
- /// Display a message box for a non-exception error, giving options to view the logs.
- /// </summary>
- /// <param name="message">The message to display. Set to <see langword="null"/> to default to the exception message.</param>
- /// <param name="details"></param>
- /// <param name="title"></param>
- /// <param name="shouldLog">If <see langword="true"/>, also logs the exception.</param>
- public static MessageWindow NewError(string message, string? details = null, string title = "Error", bool shouldLog = true, ImageSource? image = null)
- {
- if (shouldLog)
- {
- Logger.Send(LogType.Error, ClientFactory.UserID, details ?? message);
- }
- var window = new MessageWindow()
- .Message(message)
- .Title(title);
- if(details is not null)
- {
- window.Details(details);
- }
- window.Image(image ?? _warning)
- .AddButton(new MessageWindowButton(
- "Email Logs",
- (window, button) => EmailLogs_Click(new Exception(details ?? message)),
- MessageWindowButtonPosition.Left));
- if(details is not null)
- {
- var showDetailsButton = new MessageWindowButton("Show Details", (win, button) =>
- {
- win.ShowDetails = !win.ShowDetails;
- button.Content = win.ShowDetails
- ? "Hide Details"
- : "Show Details";
- }, MessageWindowButtonPosition.Left);
- window.AddButton(showDetailsButton);
- }
- return window.AddOKButton();
- }
- public static void ShowError(string? message, Exception exception, string title = "Error", bool shouldLog = true, ImageSource? image = null)
- {
- NewError(message, exception, title, shouldLog, image).Display();
- }
- public static void ShowError(string message, string details, string title = "Error", bool shouldLog = true, ImageSource? image = null)
- {
- NewError(message, details, title, shouldLog, image).Display();
- }
- private static void ShowLogs_Click(MessageWindow window, MessageWindowButton button)
- {
- var console = new MessageWindowConsole("Logs", Path.Combine(CoreUtils.GetPath(), string.Format("{0:yyyy-MM-dd}.log", DateTime.Today)));
- console.ShowDialog();
- }
- #endregion
- }
- public static class MessageWindowBuilder
- {
- public static MessageWindow Title(this MessageWindow window, string title)
- {
- window.Title = title;
- return window;
- }
- public static MessageWindow Message(this MessageWindow window, string message)
- {
- window.Message = message;
- return window;
- }
- public static MessageWindow Image(this MessageWindow window, ImageSource? image)
- {
- window.Image = image;
- return window;
- }
- public static MessageWindow Icon(this MessageWindow window, ImageSource image)
- {
- window.Icon = image;
- return window;
- }
- public static MessageWindow Details(this MessageWindow window, string details)
- {
- window.Details = details;
- return window;
- }
- public static MessageWindow Display(this MessageWindow window)
- {
- window.ShowDialog();
- return window;
- }
- }
- public class MessageWindowConsole : Console.Console
- {
- public string FileName { get; set; }
- public MessageWindowConsole(string description, string file) : base(description)
- {
- FileName = file;
- ConsoleControl.AllowLoadLogButton = false;
- }
- protected override void OnLoaded()
- {
- base.OnLoaded();
- if (File.Exists(FileName))
- {
- var lines = File.ReadLines(FileName);
- ConsoleControl.LoadLogEntries(lines);
- }
- }
- protected override string GetLogDirectory()
- {
- return CoreUtils.GetPath();
- }
- }
|