diff --git a/Directory.props b/Directory.props new file mode 100644 index 0000000..028fe5a --- /dev/null +++ b/Directory.props @@ -0,0 +1,6 @@ + + + + 2.1.8 + + diff --git a/TrackOMatic.Logic.Test/TrackOMatic.Logic.Test.csproj b/TrackOMatic.Logic.Test/TrackOMatic.Logic.Test.csproj index 7ab6493..f29c7f4 100644 --- a/TrackOMatic.Logic.Test/TrackOMatic.Logic.Test.csproj +++ b/TrackOMatic.Logic.Test/TrackOMatic.Logic.Test.csproj @@ -1,4 +1,6 @@ - + + + net10.0 @@ -22,4 +24,4 @@ - \ No newline at end of file + diff --git a/TrackOMatic.Logic/TrackOMatic.Logic.csproj b/TrackOMatic.Logic/TrackOMatic.Logic.csproj index b760144..4a41351 100644 --- a/TrackOMatic.Logic/TrackOMatic.Logic.csproj +++ b/TrackOMatic.Logic/TrackOMatic.Logic.csproj @@ -1,4 +1,6 @@ - + + + net10.0 diff --git a/TrackOMatic.Services.Test/TrackOMatic.Services.Test.csproj b/TrackOMatic.Services.Test/TrackOMatic.Services.Test.csproj index c809ff5..80f6f7a 100644 --- a/TrackOMatic.Services.Test/TrackOMatic.Services.Test.csproj +++ b/TrackOMatic.Services.Test/TrackOMatic.Services.Test.csproj @@ -1,4 +1,6 @@ - + + + net10.0 @@ -22,4 +24,4 @@ - \ No newline at end of file + diff --git a/TrackOMatic.Services.Test/VersionServiceTests.cs b/TrackOMatic.Services.Test/VersionServiceTests.cs new file mode 100644 index 0000000..d03531b --- /dev/null +++ b/TrackOMatic.Services.Test/VersionServiceTests.cs @@ -0,0 +1,120 @@ +namespace TrackOMatic.Services.Test; + +public class VersionServiceTests +{ + private readonly VersionService _sut = new(); + + [Fact] + public void GetApplicationVersion_ReturnsValidVersion() + { + // Arrange & Act + var version = _sut.GetApplicationVersion(); + + Assert.Multiple(() => + { + // Assert + Assert.NotNull(version); + Assert.True(version.Major >= 0, "Major version should be non-negative"); + }); + } + + [Fact] + public void GetApplicationVersion_ComponentsAreNonNegative() + { + // Arrange & Act + var version = _sut.GetApplicationVersion(); + + Assert.Multiple(() => + { + // Assert + Assert.True(version.Major >= 0, "Major version should be non-negative"); + Assert.True(version.Minor >= 0, "Minor version should be non-negative"); + Assert.True(version.Build >= 0, "Build version should be non-negative"); + Assert.True(version.Revision >= 0, "Revision should be non-negative"); + }); + } + + [Fact] + public void GetVersionString_ReturnsFormattedString() + { + // Arrange & Act + var versionString = _sut.GetVersionString(); + + // Assert + Assert.Multiple(() => + { + Assert.NotNull(versionString); + Assert.NotEmpty(versionString); + Assert.Matches(@"^\d+\.\d+\.\d+$", versionString); // Matches Major.Minor.Build format + }); + } + + [Fact] + public void GetVersionString_FormatsAsExpected() + { + // Arrange & Act + var version = _sut.GetApplicationVersion(); + var versionString = _sut.GetVersionString(); + var expectedFormat = $"{version.Major}.{version.Minor}.{version.Build}"; + + // Assert + Assert.Equal(expectedFormat, versionString); + } + + [Fact] + public void GetVersionString_DoesNotIncludeRevision() + { + // Arrange & Act + var version = _sut.GetApplicationVersion(); + var versionString = _sut.GetVersionString(); + + // Assert + // Should have exactly 2 dots for Major.Minor.Build format + var dotCount = versionString.Count(c => c == '.'); + Assert.Equal(2, dotCount); + } + + [Fact] + public void GetApplicationVersion_ConsistentBetweenCalls() + { + // Arrange & Act + var version1 = _sut.GetApplicationVersion(); + var version2 = _sut.GetApplicationVersion(); + + // Assert + Assert.Equal(version1, version2); + } + + [Fact] + public void GetVersionString_ConsistentBetweenCalls() + { + // Arrange & Act + var versionString1 = _sut.GetVersionString(); + var versionString2 = _sut.GetVersionString(); + + // Assert + Assert.Equal(versionString1, versionString2); + } + + [Fact] + public void GetVersionString_VersionStringAndApplicationVersionAreConsistent() + { + // Arrange & Act + var appVersion = _sut.GetApplicationVersion(); + var versionString = _sut.GetVersionString(); + + // Parse the version string to verify it matches the application version + var parts = versionString.Split('.'); + var parsedMajor = int.Parse(parts[0]); + var parsedMinor = int.Parse(parts[1]); + var parsedBuild = int.Parse(parts[2]); + + // Assert + Assert.Multiple(() => + { + Assert.Equal(appVersion.Major, parsedMajor); + Assert.Equal(appVersion.Minor, parsedMinor); + Assert.Equal(appVersion.Build, parsedBuild); + }); + } +} diff --git a/TrackOMatic.Services/IVersionService.cs b/TrackOMatic.Services/IVersionService.cs new file mode 100644 index 0000000..9d9f3f5 --- /dev/null +++ b/TrackOMatic.Services/IVersionService.cs @@ -0,0 +1,8 @@ +namespace TrackOMatic.Services; + +public interface IVersionService +{ + public Version GetApplicationVersion(); + + public string GetVersionString(); +} diff --git a/TrackOMatic.Services/ServiceLocator.cs b/TrackOMatic.Services/ServiceLocator.cs new file mode 100644 index 0000000..67a8111 --- /dev/null +++ b/TrackOMatic.Services/ServiceLocator.cs @@ -0,0 +1,20 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace TrackOMatic.Services; + +public static class ServiceLocator +{ + private static IServiceProvider? _provider; + + public static void Initialize(IServiceProvider provider) => _provider = provider; + + public static T GetService() where T : notnull + { + if (_provider == null) + { + throw new InvalidOperationException("ServiceLocator not initialized"); + } + + return _provider.GetRequiredService(); + } +} diff --git a/TrackOMatic.Services/TrackOMatic.Services.csproj b/TrackOMatic.Services/TrackOMatic.Services.csproj index 26e2721..9f3b625 100644 --- a/TrackOMatic.Services/TrackOMatic.Services.csproj +++ b/TrackOMatic.Services/TrackOMatic.Services.csproj @@ -1,4 +1,6 @@ - + + + net10.0 diff --git a/TrackOMatic.Services/VersionService.cs b/TrackOMatic.Services/VersionService.cs new file mode 100644 index 0000000..463ad24 --- /dev/null +++ b/TrackOMatic.Services/VersionService.cs @@ -0,0 +1,18 @@ +using System.Reflection; + +namespace TrackOMatic.Services; + +public class VersionService : IVersionService +{ + public Version GetApplicationVersion() + { + var version = Assembly.GetExecutingAssembly().GetName().Version; + return version ?? new(0, 0, 0, 0); + } + + public string GetVersionString() + { + var version = GetApplicationVersion(); + return $"{version.Major}.{version.Minor}.{version.Build}"; + } +} diff --git a/TrackOMatic.ViewModels.Test/TrackOMatic.ViewModels.Test.csproj b/TrackOMatic.ViewModels.Test/TrackOMatic.ViewModels.Test.csproj index 4809df1..ac1488e 100644 --- a/TrackOMatic.ViewModels.Test/TrackOMatic.ViewModels.Test.csproj +++ b/TrackOMatic.ViewModels.Test/TrackOMatic.ViewModels.Test.csproj @@ -1,4 +1,6 @@ - + + + net10.0 @@ -22,4 +24,4 @@ - \ No newline at end of file + diff --git a/TrackOMatic.ViewModels/TrackOMatic.ViewModels.csproj b/TrackOMatic.ViewModels/TrackOMatic.ViewModels.csproj index da7efb2..1d92261 100644 --- a/TrackOMatic.ViewModels/TrackOMatic.ViewModels.csproj +++ b/TrackOMatic.ViewModels/TrackOMatic.ViewModels.csproj @@ -1,4 +1,6 @@ - + + + net10.0 diff --git a/TrackOMatic/App.xaml b/TrackOMatic/App.xaml index b33a544..d87fa3b 100644 --- a/TrackOMatic/App.xaml +++ b/TrackOMatic/App.xaml @@ -1,9 +1,8 @@ - diff --git a/TrackOMatic/App.xaml.cs b/TrackOMatic/App.xaml.cs index ea2c6a9..3cb15a3 100644 --- a/TrackOMatic/App.xaml.cs +++ b/TrackOMatic/App.xaml.cs @@ -1,52 +1,60 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; -using System.Threading.Tasks; using System.Windows; + +using Microsoft.Extensions.DependencyInjection; + using TrackOMatic.Properties; +using TrackOMatic.Services; + +namespace TrackOMatic; -namespace TrackOMatic +/// +/// Interaction logic for App.xaml +/// +public partial class App : Application { - /// - /// Interaction logic for App.xaml - /// - public partial class App : Application + private readonly IServiceProvider _serviceProvider; + + App() { + var services = new ServiceCollection(); + services.AddSingleton(); - App() - { - Dispatcher.UnhandledException += OnDispatcherUnhandledException; - } + _serviceProvider = services.BuildServiceProvider(); + ServiceLocator.Initialize(_serviceProvider); + Dispatcher.UnhandledException += OnDispatcherUnhandledException; + } - private void App_Exit(object sender, ExitEventArgs e) - { - } + private void App_Exit(object sender, ExitEventArgs e) + { + } - void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) - { - } + void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) + { + } - protected override void OnStartup(StartupEventArgs e) - { - base.OnStartup(e); - UpdatePadBarrelImages(); - } + protected override void OnStartup(StartupEventArgs e) + { + base.OnStartup(e); + + var versionService = _serviceProvider.GetRequiredService(); + MainWindow mainWindow = new(versionService); + mainWindow.Show(); - public void UpdatePadBarrelImages() + UpdatePadBarrelImages(); + } + + public void UpdatePadBarrelImages() + { + var dicts = Resources.MergedDictionaries; + dicts.Clear(); + dicts.Add(new ResourceDictionary + { + Source = new Uri("Dictionary1.xaml", UriKind.Relative) + }); + var path = Settings.Default.ColoredBarrelPadMoves ? "ColoredBarrelPadImages.xaml" : "BaseBarrelPadImages.xaml"; + dicts.Add(new ResourceDictionary { - var dicts = Resources.MergedDictionaries; - dicts.Clear(); - dicts.Add(new ResourceDictionary - { - Source = new Uri("Dictionary1.xaml", UriKind.Relative) - }); - var path = Settings.Default.ColoredBarrelPadMoves ? "ColoredBarrelPadImages.xaml" : "BaseBarrelPadImages.xaml"; - dicts.Add(new ResourceDictionary - { - Source = new Uri(path, UriKind.Relative) - }); - } + Source = new Uri(path, UriKind.Relative) + }); } } diff --git a/TrackOMatic/AutoUpdateInfo.xml b/TrackOMatic/AutoUpdateInfo.xml index 309db53..714a3dc 100644 --- a/TrackOMatic/AutoUpdateInfo.xml +++ b/TrackOMatic/AutoUpdateInfo.xml @@ -5,3 +5,4 @@ https://github.com/Brian0255/Track-O-Matic/releases false + diff --git a/TrackOMatic/MainWindow.xaml b/TrackOMatic/MainWindow.xaml index de9294d..014a3ed 100644 --- a/TrackOMatic/MainWindow.xaml +++ b/TrackOMatic/MainWindow.xaml @@ -76,7 +76,10 @@ - + diff --git a/TrackOMatic/MainWindow.xaml.cs b/TrackOMatic/MainWindow.xaml.cs index 243519d..d987847 100644 --- a/TrackOMatic/MainWindow.xaml.cs +++ b/TrackOMatic/MainWindow.xaml.cs @@ -11,6 +11,7 @@ using Microsoft.Win32; using TrackOMatic.Properties; +using TrackOMatic.Services; using Timer = System.Timers.Timer; @@ -19,7 +20,7 @@ namespace TrackOMatic /// /// Interaction logic for MainWindow.xaml /// - public partial class MainWindow : Window + public partial class MainWindow : Window, INotifyPropertyChanged { public int TotalGBs { get; private set; } public BroadcastView? BroadcastView { get; private set; } @@ -48,10 +49,36 @@ public partial class MainWindow : Window public Dictionary ITEM_TO_DIRECT_HINT { get; } = new(); public Dictionary ITEM_NAME_TO_ITEM { get; } = new(); + public IVersionService VersionService { get; init; } + + private string _applicationVersion = ""; + public string ApplicationVersion + { + get => _applicationVersion; + private set + { + if (_applicationVersion != value) + { + _applicationVersion = value; + OnPropertyChanged(nameof(ApplicationVersion)); + } + } + } + + public event PropertyChangedEventHandler? PropertyChanged; + + private void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + // Timer to save the data every minute. This is properly initialized, but the compiler is finicky. private Timer SaveTimer = null!; - public MainWindow() + public MainWindow(IVersionService versionService) { + VersionService = versionService; + ApplicationVersion = VersionService.GetVersionString(); + DataContext = this; InitializeComponent(); HintData.Init(); InitOptions(); @@ -699,7 +726,7 @@ private void MainWindow_Loaded(object sender, RoutedEventArgs e) AutoUpdater.UpdateFormSize = new System.Drawing.Size(1300, 600); AutoUpdater.Icon = Properties.Resources.app.ToBitmap(); - AutoUpdater.InstalledVersion = new Version("2.1.8"); + AutoUpdater.InstalledVersion = VersionService.GetApplicationVersion(); AutoUpdater.Start("https://raw.githubusercontent.com/Brian0255/Track-O-Matic/master/TrackOMatic/AutoUpdateInfo.xml"); if (Settings.Default.DesiredHeight == 0 || Settings.Default.DesiredWidth == 0) diff --git a/TrackOMatic/Scripts/UpdateAutoUpdateInfo.ps1 b/TrackOMatic/Scripts/UpdateAutoUpdateInfo.ps1 new file mode 100644 index 0000000..4d197ee --- /dev/null +++ b/TrackOMatic/Scripts/UpdateAutoUpdateInfo.ps1 @@ -0,0 +1,15 @@ +param( + [string]$Version = "2.1.8", + [string]$OutputPath = "AutoUpdateInfo.xml" +) + +$xml = [xml](Get-Content $OutputPath) +$xml.item.version = $Version +$xml.item.url = "https://github.com/Brian0255/Track-O-Matic/releases/download/$Version/TrackOMatic_$Version.zip" +$xml.Save($OutputPath) + +# Ensure file ends with a blank line +Add-Content -Path $OutputPath -Value "" -NoNewline +Add-Content -Path $OutputPath -Value "" + +Write-Host "Updated AutoUpdateInfo.xml to version $Version" diff --git a/TrackOMatic/Scripts/UpdateAutoUpdateInfo.sh b/TrackOMatic/Scripts/UpdateAutoUpdateInfo.sh new file mode 100755 index 0000000..9399572 --- /dev/null +++ b/TrackOMatic/Scripts/UpdateAutoUpdateInfo.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Cross-platform script to update AutoUpdateInfo.xml with version information + +VERSION="${1:-2.1.8}" +OUTPUT_PATH="${2:-AutoUpdateInfo.xml}" + +# Check if the output file exists +if [ ! -f "$OUTPUT_PATH" ]; then + echo "Error: $OUTPUT_PATH not found" + exit 1 +fi + +# Use a temporary file to avoid issues with in-place editing +TEMP_FILE="${OUTPUT_PATH}.tmp" + +# Update the version in the XML file +# This approach handles the XML parsing in a cross-platform way +sed "s|.*|$VERSION|g" "$OUTPUT_PATH" > "$TEMP_FILE" + +# Update the URL to include the version +sed -i.bak "s|.*|https://github.com/Brian0255/Track-O-Matic/releases/download/$VERSION/TrackOMatic_$VERSION.zip|g" "$TEMP_FILE" + +# Remove the backup file created by sed -i +rm -f "${TEMP_FILE}.bak" + +# Move the temp file to replace the original +mv "$TEMP_FILE" "$OUTPUT_PATH" + +# Ensure file ends with a newline +echo "" >> "$OUTPUT_PATH" + +echo "Updated AutoUpdateInfo.xml to version $VERSION" diff --git a/TrackOMatic/Track-O-Matic.csproj b/TrackOMatic/Track-O-Matic.csproj index 5773e86..e158c27 100644 --- a/TrackOMatic/Track-O-Matic.csproj +++ b/TrackOMatic/Track-O-Matic.csproj @@ -1,5 +1,7 @@ + + net10.0-windows @@ -87,4 +89,12 @@ + + + + + + + +