diff --git a/src/ioList/App.xaml.cs b/src/ioList/App.xaml.cs index f75054f..bff5bef 100644 --- a/src/ioList/App.xaml.cs +++ b/src/ioList/App.xaml.cs @@ -1,12 +1,18 @@ -using System.Windows; +using System; +using System.IO; +using System.Windows; +using ioList.ViewModels; +using MaterialDesignThemes.Wpf; +using Microsoft.Extensions.DependencyInjection; using Squirrel; namespace ioList { - public partial class App : Application + public partial class App { public App() { + Services = ConfigureServices(); InitializeComponent(); } @@ -17,15 +23,49 @@ protected override void OnStartup(StartupEventArgs e) onAppUninstall: OnAppUninstall, onEveryRun: OnAppRun); } + + /// + /// Gets the current instance in use + /// + public new static App Current => (App)Application.Current; + + /// + /// Gets the instance to resolve application services. + /// + public IServiceProvider Services { get; } + + public readonly string InstallDirectory = + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"ioList"); + + public const string RepositoryUrl = @"https://github.com/tnunnink/ioList"; + + public const string IssuesUrl = @"https://github.com/tnunnink/ioList/issues"; + + public const string PagesUrl = @"https://github.com/tnunnink/ioList/issues"; + + /// + /// Configures the services for the application. + /// + private static IServiceProvider ConfigureServices() + { + var services = new ServiceCollection(); + + services.AddSingleton(); + + services.AddTransient(); + services.AddTransient(); + + return services.BuildServiceProvider(); + } private static void OnAppInstall(SemanticVersion version, IAppTools tools) { - tools.CreateShortcutForThisExe(ShortcutLocation.StartMenu | ShortcutLocation.Desktop); + tools.CreateShortcutForThisExe(ShortcutLocation.StartMenu); } private static void OnAppUninstall(SemanticVersion version, IAppTools tools) { - tools.RemoveShortcutForThisExe(ShortcutLocation.StartMenu | ShortcutLocation.Desktop); + tools.RemoveShortcutForThisExe(ShortcutLocation.StartMenu); } private static void OnAppRun(SemanticVersion version, IAppTools tools, bool firstRun) diff --git a/src/ioList/Shared/Converters.cs b/src/ioList/Shared/Converters.cs new file mode 100644 index 0000000..73fa4a4 --- /dev/null +++ b/src/ioList/Shared/Converters.cs @@ -0,0 +1,15 @@ +using System.Windows; +using System.Windows.Data; +using LambdaConverters; + +namespace ioList.Shared +{ + public static class Converters + { + public static readonly IValueConverter VisibleIfTrue = + ValueConverter.Create(e => e.Value ? Visibility.Visible : Visibility.Collapsed); + + public static readonly IValueConverter VisibleIfFalse = + ValueConverter.Create(e => e.Value ? Visibility.Collapsed : Visibility.Visible); + } +} \ No newline at end of file diff --git a/src/ioList/Generator.cs b/src/ioList/Shared/Generator.cs similarity index 99% rename from src/ioList/Generator.cs rename to src/ioList/Shared/Generator.cs index 5917bcb..b25caab 100644 --- a/src/ioList/Generator.cs +++ b/src/ioList/Shared/Generator.cs @@ -10,7 +10,7 @@ using L5Sharp.Enums; using L5Sharp.Extensions; -namespace ioList; +namespace ioList.Shared; public class Generator { diff --git a/src/ioList/Shell.xaml b/src/ioList/Shell.xaml index 234f130..d3d1ad9 100644 --- a/src/ioList/Shell.xaml +++ b/src/ioList/Shell.xaml @@ -1,11 +1,11 @@ - @@ -43,35 +43,6 @@ - - - - - - - + \ No newline at end of file diff --git a/src/ioList/Shell.xaml.cs b/src/ioList/Shell.xaml.cs index 9ea1ea8..dddb7d3 100644 --- a/src/ioList/Shell.xaml.cs +++ b/src/ioList/Shell.xaml.cs @@ -1,11 +1,11 @@ -namespace ioList +namespace ioList.Views { public partial class Shell { public Shell() { InitializeComponent(); - DataContext = new ShellViewModel(); + DataContext = new ViewModels.ShellViewModel(); } } } \ No newline at end of file diff --git a/src/ioList/ViewModels/FooterViewModel.cs b/src/ioList/ViewModels/FooterViewModel.cs new file mode 100644 index 0000000..8f5ca1e --- /dev/null +++ b/src/ioList/ViewModels/FooterViewModel.cs @@ -0,0 +1,103 @@ +using System; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using MaterialDesignThemes.Wpf; +using Squirrel; +using Squirrel.Sources; + +namespace ioList.ViewModels +{ + public partial class FooterViewModel : ObservableObject + { + public FooterViewModel(ISnackbarMessageQueue messageQueue) + { + _messageQueue = messageQueue; + UpdateAvailable = false; + LoadTask = CheckForUpdates(); + } + + [ObservableProperty] private ISnackbarMessageQueue _messageQueue; + + #region PropertyRegion + + [ObservableProperty] private string _versionText; + + [ObservableProperty] private string _updateText; + + [ObservableProperty] private bool _updateAvailable; + + #endregion + + private readonly TaskNotifier _loadTask; + + private Task LoadTask + { + get => _loadTask; + init => SetPropertyAndNotifyOnCompletion(ref _loadTask, value); + } + + [RelayCommand] + private async Task CheckForUpdates() + { + try + { + using var manager = new UpdateManager(new GithubSource("https://github.com/tnunnink/ioList", "", false)); + var updateInfo = await manager.CheckForUpdate(); + + VersionText = $"ioList {updateInfo.CurrentlyInstalledVersion.Version}"; + + UpdateAvailable = updateInfo.ReleasesToApply.Count > 0; + + if (!UpdateAvailable) + { + MessageQueue.Enqueue( + "You have the latest updates! We will notify when new releases ar published. Enjoy!"); + return; + } + + var latest = updateInfo.ReleasesToApply.MaxBy(r => r.Version)?.Version; + UpdateText = $"Update to version {latest}"; + MessageQueue.Enqueue("New updates are available! Click update to start installing."); + } + catch (Exception e) + { + MessageQueue.Enqueue("Unable to contact Github to find new updates..."); + } + } + + [RelayCommand(CanExecute = nameof(CanExecuteUpdateCommand))] + private async Task PerformUpdate() + { + try + { + using var manager = new UpdateManager(new GithubSource("https://github.com/tnunnink/ioList", "", false)); + var release = await manager.UpdateApp(); + MessageQueue.Enqueue($"Update complete. You are running version {release.Version}. Enjoy!"); + VersionText = $"ioList {release.Version}"; + UpdateAvailable = false; + } + catch (Exception e) + { + MessageQueue.Enqueue("Failed performing application update. You hate to see it..."); + } + } + + private bool CanExecuteUpdateCommand() => UpdateAvailable; + + [RelayCommand] + private void LaunchSite(string url) + { + try + { + Process.Start(new ProcessStartInfo("cmd", $"/c start {url}") { CreateNoWindow = true }); + } + catch (Exception e) + { + MessageQueue.Enqueue($"Unable to open site {url}"); + } + } + } +} \ No newline at end of file diff --git a/src/ioList/ShellViewModel.cs b/src/ioList/ViewModels/ShellViewModel.cs similarity index 98% rename from src/ioList/ShellViewModel.cs rename to src/ioList/ViewModels/ShellViewModel.cs index eafe02b..a51f5b7 100644 --- a/src/ioList/ShellViewModel.cs +++ b/src/ioList/ViewModels/ShellViewModel.cs @@ -5,9 +5,10 @@ using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; +using ioList.Shared; using Ookii.Dialogs.Wpf; -namespace ioList +namespace ioList.ViewModels { public partial class ShellViewModel : ObservableValidator { diff --git a/src/ioList/Views/CompleteView.xaml b/src/ioList/Views/CompleteView.xaml index 19b4038..a559816 100644 --- a/src/ioList/Views/CompleteView.xaml +++ b/src/ioList/Views/CompleteView.xaml @@ -5,12 +5,13 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:ioList="clr-namespace:ioList" + xmlns:viewModels="clr-namespace:ioList.ViewModels" TextElement.Foreground="{DynamicResource MaterialDesignBody}" Background="{DynamicResource MaterialDesignPaper}" TextElement.FontWeight="Medium" TextElement.FontSize="14" FontFamily="{md:MaterialDesignFont}" - d:DataContext="{d:DesignInstance ioList:ShellViewModel, IsDesignTimeCreatable=True}" + d:DataContext="{d:DesignInstance viewModels:ShellViewModel, IsDesignTimeCreatable=True}" mc:Ignorable="d"> diff --git a/src/ioList/Views/EntryView.xaml b/src/ioList/Views/EntryView.xaml index 24756e2..e45197e 100644 --- a/src/ioList/Views/EntryView.xaml +++ b/src/ioList/Views/EntryView.xaml @@ -6,12 +6,13 @@ xmlns:b="http://schemas.microsoft.com/xaml/behaviors" xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:ioList="clr-namespace:ioList" + xmlns:viewModels="clr-namespace:ioList.ViewModels" TextElement.Foreground="{DynamicResource MaterialDesignBody}" Background="{DynamicResource MaterialDesignPaper}" TextElement.FontWeight="Medium" TextElement.FontSize="14" FontFamily="{md:MaterialDesignFont}" - d:DataContext="{d:DesignInstance ioList:ShellViewModel, IsDesignTimeCreatable=True}" + d:DataContext="{d:DesignInstance viewModels:ShellViewModel, IsDesignTimeCreatable=True}" mc:Ignorable="d"> diff --git a/src/ioList/Views/ErrorView.xaml b/src/ioList/Views/ErrorView.xaml index 02355eb..d35331d 100644 --- a/src/ioList/Views/ErrorView.xaml +++ b/src/ioList/Views/ErrorView.xaml @@ -5,12 +5,13 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:ioList="clr-namespace:ioList" + xmlns:viewModels="clr-namespace:ioList.ViewModels" TextElement.Foreground="{DynamicResource MaterialDesignBody}" Background="{DynamicResource MaterialDesignPaper}" TextElement.FontWeight="Medium" TextElement.FontSize="14" FontFamily="{md:MaterialDesignFont}" - d:DataContext="{d:DesignInstance ioList:ShellViewModel, IsDesignTimeCreatable=True}" + d:DataContext="{d:DesignInstance viewModels:ShellViewModel, IsDesignTimeCreatable=True}" mc:Ignorable="d"> diff --git a/src/ioList/Views/FooterView.xaml b/src/ioList/Views/FooterView.xaml new file mode 100644 index 0000000..0773686 --- /dev/null +++ b/src/ioList/Views/FooterView.xaml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ioList/Views/FooterView.xaml.cs b/src/ioList/Views/FooterView.xaml.cs new file mode 100644 index 0000000..ab97e14 --- /dev/null +++ b/src/ioList/Views/FooterView.xaml.cs @@ -0,0 +1,14 @@ +using ioList.ViewModels; +using Microsoft.Extensions.DependencyInjection; + +namespace ioList.Views +{ + public partial class FooterView + { + public FooterView() + { + InitializeComponent(); + DataContext = App.Current.Services.GetService(); + } + } +} \ No newline at end of file diff --git a/src/ioList/Views/ProcessingView.xaml b/src/ioList/Views/ProcessingView.xaml index c6b2509..33d69ad 100644 --- a/src/ioList/Views/ProcessingView.xaml +++ b/src/ioList/Views/ProcessingView.xaml @@ -5,12 +5,13 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:ioList="clr-namespace:ioList" + xmlns:viewModels="clr-namespace:ioList.ViewModels" TextElement.Foreground="{DynamicResource MaterialDesignBody}" Background="{DynamicResource MaterialDesignPaper}" TextElement.FontWeight="Medium" TextElement.FontSize="14" FontFamily="{md:MaterialDesignFont}" - d:DataContext="{d:DesignInstance ioList:ShellViewModel, IsDesignTimeCreatable=True}" + d:DataContext="{d:DesignInstance viewModels:ShellViewModel, IsDesignTimeCreatable=True}" mc:Ignorable="d"> diff --git a/src/ioList/Views/StartupView.xaml b/src/ioList/Views/StartupView.xaml index 5025b64..022b84f 100644 --- a/src/ioList/Views/StartupView.xaml +++ b/src/ioList/Views/StartupView.xaml @@ -5,12 +5,13 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:ioList="clr-namespace:ioList" + xmlns:viewModels="clr-namespace:ioList.ViewModels" TextElement.Foreground="{DynamicResource MaterialDesignBody}" Background="{DynamicResource MaterialDesignPaper}" TextElement.FontWeight="Medium" TextElement.FontSize="14" FontFamily="{md:MaterialDesignFont}" - d:DataContext="{d:DesignInstance ioList:ShellViewModel, IsDesignTimeCreatable=True}" + d:DataContext="{d:DesignInstance viewModels:ShellViewModel, IsDesignTimeCreatable=True}" mc:Ignorable="d"> diff --git a/src/ioList/ioList.csproj b/src/ioList/ioList.csproj index 5348f03..8282638 100644 --- a/src/ioList/ioList.csproj +++ b/src/ioList/ioList.csproj @@ -16,7 +16,9 @@ + + diff --git a/tests/ioList.Tests/GeneratorTests.cs b/tests/ioList.Tests/GeneratorTests.cs index b1d8c66..2076976 100644 --- a/tests/ioList.Tests/GeneratorTests.cs +++ b/tests/ioList.Tests/GeneratorTests.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using ioList.Shared; using NUnit.Framework; namespace ioList.Tests;