diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 0deb4b9..e0b55a0 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -1,27 +1,27 @@
-name: Build (dagger)
+name: build
+
on:
push:
branches:
- - '**'
+ - "**"
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- - name: Checkout
- uses: actions/Checkout@v4
- with:
- submodules: 'true'
- ref: ${{ github.ref }}
- fetch-depth: 0
-
- - name: Build Project with Dagger
- uses: dagger/dagger-for-github@v5.6.0
- with:
- version: "latest"
- verb: call
- args: build --git=. stdout
- cloud-token: ${{ secrets.DAGGER_CLOUD_TOKEN }}
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
+ - name: Checkout
+ uses: actions/Checkout@v4
+ with:
+ submodules: "true"
+ ref: ${{ github.ref }}
+ fetch-depth: 0
+ - name: Build Project with Dagger
+ uses: dagger/dagger-for-github@v5.6.0
+ with:
+ version: "latest"
+ verb: call
+ args: build --git=. stdout
+ cloud-token: ${{ secrets.DAGGER_CLOUD_TOKEN }}
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/release-windows-v1.yaml b/.github/workflows/release-windows-v1.yaml
deleted file mode 100644
index 9338cb3..0000000
--- a/.github/workflows/release-windows-v1.yaml
+++ /dev/null
@@ -1,107 +0,0 @@
-name: ClickOnce Release v1
-
-on:
- push:
- tags:
- - 'v[0-9]+.[0-9]+.[0-9]+'
-
-permissions:
- contents: read
- pages: write
- id-token: write
-
-jobs:
- release:
- if: false # This condition disables the job. Change to `true` or remove to enable.
- runs-on: windows-latest
- environment:
- name: github-pages
- url: https://heroesreplay.github.io/HeroesProfile.Uploader/
-
- steps:
-
- - name: Checkout code
- uses: actions/checkout@v4
- with:
- ref: ${{ github.ref }}
- submodules: 'true'
- fetch-depth: 0
-
- - name: Setup .NET 8 SDK
- uses: actions/setup-dotnet@v4
- with:
- dotnet-version: '8.0.x'
-
- - name: Install dotnet-mage
- run: dotnet tool install --global microsoft.dotnet.mage --version 8.0.0
-
- - name: Prepare version and publish directory
- id: version
- run: |
- $version = "${{ github.ref }}" -replace "refs/tags/v", ""
- $publishDir = ".\publish\$version"
- echo "APP_PUBLISH_DIR=$publishDir" >> $GITHUB_ENV
- echo "APP_VERSION=$version" >> $GITHUB_ENV
-
- - name: Publish application
- run: |
- dotnet publish .\Heroesprofile.Uploader.Windows `
- --self-contained `
- --os win `
- -o $env:PUBLISH_DIR
- env:
- APP_PUBLISH_DIR: ${{ env.APP_PUBLISH_DIR }}
- APP_VERSION: ${{ env.APP_VERSION }}
-
- - name: ClickOnce manifest and application
- run: |
-
- $publishDir = $env:APP_PUBLISH_DIR
- $version = $env:APP_VERSION
-
- dotnet mage -al Heroesprofile.Uploader.exe `
- -TargetDirectory $publishDir
-
- dotnet mage -new Application `
- -ToFile $publishDir\Heroesprofile.Uploader.manifest `
- -FromDirectory $publishDir `
- -Version $version `
- -IconFile .\Heroesprofile.Uploader.Windows\Resources\uploader_icon_dark.ico
-
- dotnet mage -new Deployment `
- -Install true `
- -Publisher "Patrick Magee" `
- -Version $version `
- -AppManifest $publishDir\Heroesprofile.Uploader.manifest `
- -ToFile Heroesprofile.Uploader.application `
- -ProviderUrl https://heroesreplay.github.io/HeroesProfile.Uploader/
-
- env:
- APP_PUBLISH_DIR: ${{ env.APP_PUBLISH_DIR }}
- APP_VERSION: ${{ env.APP_VERSION }}
-
- - name: Setup Pages
- uses: actions/configure-pages@v5
- with:
- enablement: 'true'
- token: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Upload artifact
- uses: actions/upload-pages-artifact@v3
- with:
- path: ${{ env.APP_PUBLISH_DIR }}
- env:
- APP_PUBLISH_DIR: ${{ env.APP_PUBLISH_DIR }}
- APP_VERSION: ${{ env.APP_VERSION }}
-
- - name: Deploy to GitHub Pages
- id: deployment
- uses: actions/deploy-pages@v4
-
- - name: Create Release and Upload Assets
- uses: softprops/action-gh-release@v1
- with:
- files: ${{ env.PUBLISH_DIR }}
- token: ${{ secrets.GITHUB_TOKEN }}
- env:
- PUBLISH_DIR: ${{ env.PUBLISH_DIR }}
\ No newline at end of file
diff --git a/.github/workflows/release-windows-v2.yaml b/.github/workflows/release-windows-v2.yaml
deleted file mode 100644
index df43bbe..0000000
--- a/.github/workflows/release-windows-v2.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: ClickOnce Release v2
-permissions:
- contents: write
- packages: write
- pages: write
-
-on:
- push:
- tags: [v*]
-
-jobs:
- release:
- runs-on: windows-latest
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v3
- with:
- submodules: 'true'
- fetch-depth: 0
-
- - name: Setup Git
- run: |
- git config --global url."https://user:${{ secrets.GITHUB_TOKEN }}@github".insteadOf https://github
- git config --global user.name github-actions
- git config --global user.email github-actions@github.com
-
- - name: Run release script
- shell: pwsh
- run: ./release.ps1
\ No newline at end of file
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 980e50a..93b2095 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -1,33 +1,68 @@
-name: Release (dagger)
+name: release
+
+# Workflow with Windows & Linux
+# This is so we can use dotnet mage to build the manifests
+
+permissions:
+ pages: write
+ contents: write
+ id-token: write
+ deployments: write
on:
push:
tags:
- - 'v[0-9]+.[0-9]+.[0-9]+'
+ - "v[0-9]+.[0-9]+.[0-9]+"
-permissions:
- contents: write
- packages: write
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
jobs:
- release:
- if: false # This condition disables the job. Change to `true` or remove to enable.
- runs-on: ubuntu-latest
-
+ publish:
+ runs-on: windows-latest
steps:
- - name: Checkout
- uses: actions/Checkout@v4
- with:
- submodules: 'true'
- ref: ${{ github.ref }}
- fetch-depth: 0
-
- - name: Release
- uses: dagger/dagger-for-github@v5.6.0
- with:
- version: "latest"
- verb: call
- args: release --git=. --tag=${{ github.ref_name }} --token=env:GITHUB_TOKEN
- cloud-token: ${{ secrets.DAGGER_CLOUD_TOKEN }}
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
+ - name: Checkout code
+ uses: actions/checkout@v3
+ with:
+ submodules: "true"
+ fetch-depth: 0
+ ref: ${{ github.ref }}
+
+ - name: Setup .NET 8 SDK
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: "8.0.x"
+
+ - name: Run release script
+ run: .\dotnet-mage-release.ps1
+ continue-on-error: false
+
+ - name: Deploy to GitHub Pages
+ uses: peaceiris/actions-gh-pages@v4
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_branch: gh-pages
+ publish_dir: ./Heroesprofile.Uploader.Windows/bin/publish
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: published
+ path: .\Heroesprofile.Uploader.Windows\bin\publish
+ if-no-files-found: error
+ retention-days: 1
+ overwrite: true
+
+ - name: Release to GitHub
+ uses: ncipollo/release-action@v1
+ with:
+ artifacts: "*"
+ token: ${{ secrets.GITHUB_TOKEN }}
+ tag: ${{ github.ref }}
+ allowUpdates: true
+ makeLatest: true
+ replacesArtifacts: true
+ generateReleaseNotes: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/Heroesprofile.Uploader.Common/Analyzer.cs b/Heroesprofile.Uploader.Common/Analyzer.cs
index 7b35242..80db1e2 100644
--- a/Heroesprofile.Uploader.Common/Analyzer.cs
+++ b/Heroesprofile.Uploader.Common/Analyzer.cs
@@ -15,10 +15,6 @@ public class Analyzer : IAnalyzer
private static Logger _log = LogManager.GetCurrentClassLogger();
- ///
- /// Analyze replay locally before uploading
- ///
- /// Replay file
public Replay Analyze(ReplayFile file)
{
try {
@@ -89,29 +85,22 @@ public Replay Analyze(ReplayFile file)
return null;
}
- ///
- /// Get unique hash of replay. Compatible with HotsLogs
- ///
- ///
- ///
public string GetFingerprint(Replay replay)
{
var str = new StringBuilder();
replay.Players.Select(p => p.BattleNetId).OrderBy(x => x).Map(x => str.Append(x.ToString()));
str.Append(replay.RandomValue);
- var md5 = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(str.ToString()));
+ var md5 = MD5.HashData(Encoding.UTF8.GetBytes(str.ToString()));
var result = new Guid(md5);
return result.ToString();
}
- ///
- /// Swaps two bytes in a byte array
- ///
- private void SwapBytes(byte[] buf, int i, int j)
- {
- byte temp = buf[i];
- buf[i] = buf[j];
- buf[j] = temp;
- }
+
+ //private void SwapBytes(byte[] buf, int i, int j)
+ //{
+ // byte temp = buf[i];
+ // buf[i] = buf[j];
+ // buf[j] = temp;
+ //}
}
}
diff --git a/Heroesprofile.Uploader.Windows/App.xaml b/Heroesprofile.Uploader.Windows/App.xaml
index 507d965..6607971 100644
--- a/Heroesprofile.Uploader.Windows/App.xaml
+++ b/Heroesprofile.Uploader.Windows/App.xaml
@@ -2,4 +2,18 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup"
- Exit="Application_Exit" />
\ No newline at end of file
+ Exit="Application_Exit">
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Heroesprofile.Uploader.Windows/App.xaml.cs b/Heroesprofile.Uploader.Windows/App.xaml.cs
index c347f63..a575746 100644
--- a/Heroesprofile.Uploader.Windows/App.xaml.cs
+++ b/Heroesprofile.Uploader.Windows/App.xaml.cs
@@ -1,4 +1,6 @@
-using Heroesprofile.Uploader.Common;
+using H.NotifyIcon;
+
+using Heroesprofile.Uploader.Common;
using Heroesprofile.Uploader.Windows.Core;
using Microsoft.Extensions.Configuration;
@@ -8,42 +10,48 @@
using System;
using System.Collections.Generic;
-using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
-using System.Windows.Forms;
-
-using MessageBox = System.Windows.MessageBox;
namespace Heroesprofile.Uploader.Windows
{
-
- public partial class App : System.Windows.Application, INotifyPropertyChanged
+ public partial class App : Application
{
- public static IConfiguration Config { get; private set; }
+ public new static App Current => (App) Application.Current;
+
- public static Logger _log;
+ private static object _lock = new object();
- public AppConfig AppConfig { get; private set; }
+ public IConfiguration Config { get; private set; }
- public static bool StartWithWindowsCheckboxEnabled => true;
+ public Logger _log;
+
+ public UserSettings UserSettings { get; private set; }
+ public AppSettings AppSettings { get; private set; }
- public event PropertyChangedEventHandler PropertyChanged;
+ private SettingsManager settingsManager;
- public NotifyIcon TrayIcon { get; private set; }
+ public TaskbarIcon TaskbarIcon { get; private set; }
public Manager Manager { get; private set; }
- internal static Properties.Settings Settings => Uploader.Windows.Properties.Settings.Default;
- public static string AppExe => Assembly.GetExecutingAssembly().Location;
- public static string AppDir => Path.GetDirectoryName(AppExe);
- public static string AppFile => Path.GetFileName(AppExe);
- public static string SettingsDir => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Heroesprofile");
+
+ public string SettingsDir => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Heroesprofile");
- public static Version Version => Assembly.GetExecutingAssembly().GetName().Version;
- public string VersionString => $"v{Version.Major}.{Version.Minor}" + (Version.Build == 0 ? "" : $".{Version.Build}");
+ public Version Version
+ {
+ get {
+ if (ApplicationDeployment.IsNetworkDeployed) {
+ return ApplicationDeployment.CurrentDeployment.CurrentVersion;
+ }
+
+ return Assembly.GetExecutingAssembly().GetName().Version;
+ }
+ }
+
+ public string VersionString => $"v{Version}";
public bool StartWithWindows
{
@@ -64,29 +72,24 @@ public bool StartWithWindows
{ "MetroDark", "Themes/MetroDark/MetroDark.Heroesprofile.Implicit.xaml" },
};
-
- private static object _lock = new object();
- public MainWindow mainWindow;
-
- public App()
+ public App()
{
Config = new ConfigurationBuilder()
- .SetBasePath(AppDir)
+ .SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.Build();
+ settingsManager = new SettingsManager(Path.Combine(SettingsDir, "userSettings.json"));
+ UserSettings = settingsManager.LoadSettings();
+ AppSettings = Config.GetSection(nameof(AppSettings)).Get()!;
+
+ if (UserSettings == null) {
+ UserSettings = new UserSettings(AppSettings);
+ }
LogManager.Configuration = new NLogLoggingConfiguration(Config.GetSection("NLog"));
_log = LogManager.GetCurrentClassLogger();
-
- AppConfig = Config.GetSection("AppConfig").Get()!;
-
- Settings.WindowHeight = AppConfig.WindowHeight;
- Settings.WindowWidth = AppConfig.WindowWidth;
- Settings.WindowLeft = AppConfig.WindowLeft;
- Settings.WindowTop = AppConfig.WindowTop;
-
if (ApplicationDeployment.IsNetworkDeployed) {
_log.Info(JsonSerializer.Serialize(ApplicationDeployment.CurrentDeployment));
} else {
@@ -106,38 +109,38 @@ private void Application_Startup(object sender, StartupEventArgs e)
// Enable collection modification from any thread
BindingOperations.EnableCollectionSynchronization(Manager.Files, _lock);
- Manager.PreMatchPage = Settings.PreMatchPage;
- Manager.PostMatchPage = Settings.PostMatchPage;
- Manager.DeleteAfterUpload = Settings.DeleteAfterUpload;
+ Manager.PreMatchPage = UserSettings.PreMatchPage;
+ Manager.PostMatchPage = UserSettings.PostMatchPage;
+ Manager.DeleteAfterUpload = DeleteFiles.None;
- ApplyTheme(Settings.Theme);
+ ApplyTheme(AppSettings.Theme);
+ UserSettings.PropertyChanged += (o, ev) => {
- Settings.PropertyChanged += (o, ev) => {
- if (ev.PropertyName == nameof(Settings.DeleteAfterUpload)) {
- Manager.DeleteAfterUpload = Settings.DeleteAfterUpload;
- } else if (ev.PropertyName == nameof(Settings.Theme)) {
- ApplyTheme(Settings.Theme);
- } else if (ev.PropertyName == nameof(Settings.PreMatchPage)) {
- Manager.PreMatchPage = Settings.PreMatchPage;
- } else if (ev.PropertyName == nameof(Settings.PostMatchPage)) {
- Manager.PostMatchPage = Settings.PostMatchPage;
+ if (ev.PropertyName == nameof(UserSettings.PreMatchPage)) {
+ Manager.PreMatchPage = UserSettings.PreMatchPage;
+ } else if (ev.PropertyName == nameof(UserSettings.PostMatchPage)) {
+ Manager.PostMatchPage = UserSettings.PostMatchPage;
}
- };
+ settingsManager.SaveSettings(UserSettings);
+ };
- if (Settings.MinimizeToTray) {
- TrayIcon.Visible = true;
+ if (StartWithWindows) {
+ // TODO: running in the background
} else {
- mainWindow = new MainWindow();
- mainWindow.Show();
+ MainWindow = new MainWindow();
+ MainWindow.Deactivated += (o, ev) => {
+ // TODO: TrayIcon.Visible = true;
+ };
+ MainWindow.Show();
}
Manager.Start(new Monitor(), new LiveMonitor(), new Analyzer(), new Common.Uploader(), new LiveProcessor(Manager.PreMatchPage));
}
private void Application_Exit(object sender, ExitEventArgs e)
{
- TrayIcon?.Dispose();
+ TaskbarIcon?.Dispose();
}
public void ApplyTheme(string theme)
@@ -154,37 +157,20 @@ public void ApplyTheme(string theme)
}
public void Activate()
- {
- if (mainWindow != null) {
- if (mainWindow.WindowState == WindowState.Minimized) {
- mainWindow.WindowState = WindowState.Normal;
- }
- mainWindow.Activate();
- } else {
- mainWindow = new MainWindow();
- mainWindow.Show();
- mainWindow.WindowState = WindowState.Normal;
- TrayIcon.Visible = false;
- }
+ {
+ MainWindow = new MainWindow();
+ MainWindow.Activate();
+ MainWindow.WindowState = WindowState.Normal;
+ MainWindow.Show();
+
+ //
+ // TaskbarIcon.Visible = false;
}
private void SetupTrayIcon()
{
- TrayIcon = new NotifyIcon {
- Icon = System.Drawing.Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location),
- Visible = true
- };
- TrayIcon.Click += (o, e) => {
- if (mainWindow != null) {
- mainWindow.Activate();
- TrayIcon.Visible = false;
- return;
- } else {
- mainWindow = new MainWindow();
- mainWindow.Show();
- TrayIcon.Visible = false;
- }
- };
+ TaskbarIcon = (TaskbarIcon)FindResource("NotifyIcon");
+ TaskbarIcon.ForceCreate();
}
private void SetExceptionHandlers()
diff --git a/Heroesprofile.Uploader.Windows/Core/AppConfig.cs b/Heroesprofile.Uploader.Windows/Core/AppConfig.cs
deleted file mode 100644
index bd777bd..0000000
--- a/Heroesprofile.Uploader.Windows/Core/AppConfig.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-namespace Heroesprofile.Uploader.Windows.Core
-{
- public class AppConfig
- {
- public bool UpgradeRequired { get; set; }
- public bool AutoUpdate { get; set; }
- public string UpdateRepository { get; set; }
- public int WindowTop { get; set; }
- public int WindowLeft { get; set; }
- public bool MinimizeToTray { get; set; }
- public int WindowHeight { get; set; }
- public int WindowWidth { get; set; }
- public string DeleteAfterUpload { get; set; }
- public string Theme { get; set; }
- public bool AllowPreReleases { get; set; }
- public string ApplicationVersion { get; set; }
- public bool PreMatchPage { get; set; }
- public bool PostMatchPage { get; set; }
-
- }
-}
diff --git a/Heroesprofile.Uploader.Windows/Core/ApplicationDeployment.cs b/Heroesprofile.Uploader.Windows/Core/ApplicationDeployment.cs
index a378583..af8eb48 100644
--- a/Heroesprofile.Uploader.Windows/Core/ApplicationDeployment.cs
+++ b/Heroesprofile.Uploader.Windows/Core/ApplicationDeployment.cs
@@ -2,6 +2,7 @@
namespace Heroesprofile.Uploader.Windows.Core
{
+
/*
* https://learn.microsoft.com/en-us/visualstudio/deployment/debugging-clickonce-applications-that-use-system-deployment-application?view=vs-2019
* https://learn.microsoft.com/en-us/visualstudio/deployment/access-clickonce-deployment-properties-dotnet?view=vs-2022&viewFallbackFrom=vs-2019
@@ -33,7 +34,7 @@ public static bool IsApplicationDeployed
}
}
- public static ApplicationDeployment CurrentDeployment
+ public static ApplicationDeployment? CurrentDeployment
{
get {
if (!currentDeploymentInitialized) {
diff --git a/Heroesprofile.Uploader.Windows/Core/NotifyIconViewModel.cs b/Heroesprofile.Uploader.Windows/Core/NotifyIconViewModel.cs
new file mode 100644
index 0000000..936c291
--- /dev/null
+++ b/Heroesprofile.Uploader.Windows/Core/NotifyIconViewModel.cs
@@ -0,0 +1,47 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using H.NotifyIcon;
+using System.Windows;
+
+namespace Heroesprofile.Uploader.Windows.Core
+{
+ public partial class NotifyIconViewModel : ObservableObject
+ {
+ [ObservableProperty]
+ [NotifyCanExecuteChangedFor(nameof(ShowWindowCommand))]
+ public bool canExecuteShowWindow = true;
+
+ [ObservableProperty]
+ [NotifyCanExecuteChangedFor(nameof(HideWindowCommand))]
+ public bool canExecuteHideWindow = true;
+
+ ///
+ /// Shows a window, if none is already open.
+ ///
+ [RelayCommand(CanExecute = nameof(CanExecuteShowWindow))]
+ public void ShowWindow()
+ {
+ Application.Current.MainWindow ??= new MainWindow();
+ Application.Current.MainWindow.WindowState = WindowState.Normal;
+ Application.Current.MainWindow.Show();
+ }
+
+ ///
+ /// Hides the main window. This command is only enabled if a window is open.
+ ///
+ [RelayCommand(CanExecute = nameof(CanExecuteHideWindow))]
+ public void HideWindow()
+ {
+ Application.Current.MainWindow.Hide(enableEfficiencyMode: true);
+ }
+
+ ///
+ /// Shuts down the application.
+ ///
+ [RelayCommand]
+ public void ExitApplication()
+ {
+ Application.Current.Shutdown();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Heroesprofile.Uploader.Windows/Core/Settings.cs b/Heroesprofile.Uploader.Windows/Core/Settings.cs
new file mode 100644
index 0000000..5eb01f7
--- /dev/null
+++ b/Heroesprofile.Uploader.Windows/Core/Settings.cs
@@ -0,0 +1,133 @@
+using Heroesprofile.Uploader.Common;
+using Heroesprofile.Uploader.Windows.Properties;
+
+using System.ComponentModel;
+using System.Text.Json.Serialization;
+
+namespace Heroesprofile.Uploader.Windows.Core
+{
+ public class UserSettings : INotifyPropertyChanged
+ {
+ private int _windowTop;
+
+ [JsonPropertyName("windowTop")]
+ public int WindowTop
+ {
+ get => _windowTop;
+ set {
+ _windowTop = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(WindowTop)));
+ }
+ }
+
+ private int _windowLeft;
+
+ [JsonPropertyName("windowLeft")]
+ public int WindowLeft
+ {
+ get => _windowLeft;
+ set {
+ _windowLeft = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(WindowLeft)));
+ }
+ }
+
+ private bool _minimizeToTray;
+
+ [JsonPropertyName("minimizeToTray")]
+ public bool MinimizeToTray
+ {
+ get => _minimizeToTray;
+ set {
+ _minimizeToTray = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MinimizeToTray)));
+ }
+ }
+
+
+ private int windowHeight;
+
+ [JsonPropertyName("windowHeight")]
+ public int WindowHeight
+ {
+ get => windowHeight;
+ set {
+ windowHeight = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(WindowHeight)));
+ }
+ }
+
+ private int windowWidth;
+
+ [JsonPropertyName("windowWidth")]
+ public int WindowWidth
+ {
+ get => windowWidth;
+ set {
+ windowWidth = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(WindowWidth)));
+ }
+ }
+
+
+ private bool _preMatchPage;
+
+ [JsonPropertyName("preMatchPage")]
+
+ public bool PreMatchPage
+ {
+ get => _preMatchPage;
+ set {
+ _preMatchPage = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PreMatchPage)));
+ }
+ }
+
+
+ private bool _postMatchPage;
+
+ [JsonPropertyName("postMatchPage")]
+
+ public bool PostMatchPage
+ {
+ get => _postMatchPage;
+ set {
+ _postMatchPage = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PostMatchPage)));
+ }
+ }
+
+ public UserSettings()
+ {
+
+ }
+
+ public UserSettings(AppSettings settings)
+ {
+ WindowHeight = settings.WindowHeight;
+ WindowWidth = settings.WindowWidth;
+ WindowTop = settings.WindowTop;
+ WindowLeft = settings.WindowLeft;
+ MinimizeToTray = settings.MinimizeToTray;
+ PreMatchPage = settings.PreMatchPage;
+ PostMatchPage = settings.PostMatchPage;
+ }
+
+ public event PropertyChangedEventHandler? PropertyChanged;
+ }
+
+
+ public class AppSettings {
+
+ public int WindowTop { get; set; }
+ public int WindowLeft { get; set; }
+ public bool MinimizeToTray { get; set; }
+ public int WindowHeight { get; set; }
+ public int WindowWidth { get; set; }
+ public DeleteFiles DeleteAfterUpload { get; set; }
+ public bool PreMatchPage { get; set; }
+ public bool PostMatchPage { get; set; }
+ public string Theme { get; set; }
+
+ }
+}
diff --git a/Heroesprofile.Uploader.Windows/Core/SettingsManager.cs b/Heroesprofile.Uploader.Windows/Core/SettingsManager.cs
new file mode 100644
index 0000000..a4e078b
--- /dev/null
+++ b/Heroesprofile.Uploader.Windows/Core/SettingsManager.cs
@@ -0,0 +1,38 @@
+using System;
+using System.IO;
+using System.Text.Json;
+
+namespace Heroesprofile.Uploader.Windows.Core
+{
+ public class SettingsManager where T : class
+ {
+ private readonly string _filePath;
+
+ public SettingsManager(string fileName)
+ {
+ _filePath = GetLocalFilePath(fileName);
+ }
+
+ private string GetLocalFilePath(string fileName)
+ {
+ string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
+ return Path.Combine(appData, fileName);
+ }
+
+ public T? LoadSettings()
+ {
+ try {
+ return JsonSerializer.Deserialize(File.ReadAllText(_filePath), JsonSerializerOptions.Default);
+ }
+ catch {
+ return null;
+ }
+ }
+
+ public void SaveSettings(T settings)
+ {
+ string json = JsonSerializer.Serialize(settings);
+ File.WriteAllText(_filePath, json);
+ }
+ }
+}
diff --git a/Heroesprofile.Uploader.Windows/Heroesprofile.Uploader.Windows.csproj b/Heroesprofile.Uploader.Windows/Heroesprofile.Uploader.Windows.csproj
index d20e39c..e59e437 100644
--- a/Heroesprofile.Uploader.Windows/Heroesprofile.Uploader.Windows.csproj
+++ b/Heroesprofile.Uploader.Windows/Heroesprofile.Uploader.Windows.csproj
@@ -1,11 +1,11 @@
net8.0-windows
- win-x64
WinExe
Heroesprofile.Uploader
- true
true
+ true
+
true
@@ -18,20 +18,22 @@
Resources/uploader_icon_dark.ico
Heroesprofile.Uploader.Windows.App
enable
-
+
+
+
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -42,19 +44,15 @@
PreserveNewest
-
- True
- True
- Settings.settings
-
-
- SettingsSingleFileGenerator
- Settings.Designer.cs
+
Always
-
+
-
+
+
+ Always
+
Always
@@ -67,6 +65,12 @@
Always
+
+ Always
+
+
+ Always
+
\ No newline at end of file
diff --git a/Heroesprofile.Uploader.Windows/MainWindow.xaml b/Heroesprofile.Uploader.Windows/MainWindow.xaml
index da9f83f..e4c0521 100644
--- a/Heroesprofile.Uploader.Windows/MainWindow.xaml
+++ b/Heroesprofile.Uploader.Windows/MainWindow.xaml
@@ -8,10 +8,10 @@
xmlns:heroesprofile="clr-namespace:Heroesprofile.Uploader.Common;assembly=Heroesprofile.Uploader.Common"
mc:Ignorable="d"
StateChanged="Window_StateChanged" Closed="Window_Closed"
- Height="{Binding App.Settings.WindowHeight, Mode=TwoWay}" Width="{Binding App.Settings.WindowWidth, Mode=TwoWay}"
- Top="{Binding App.Settings.WindowTop, Mode=TwoWay}" Left="{Binding App.Settings.WindowLeft, Mode=TwoWay}"
- Title="{Binding App.VersionString, StringFormat=Heroesprofile.com Uploader {0}}"
- DataContext="{Binding RelativeSource={RelativeSource Self}}" d:DesignWidth="551">
+ Height="{Binding UserSettings.WindowHeight, Mode=TwoWay}" Width="{Binding UserSettings.WindowWidth, Mode=TwoWay}"
+ Top="{Binding UserSettings.WindowTop, Mode=TwoWay}" Left="{Binding UserSettings.WindowLeft, Mode=TwoWay}"
+ Title="{Binding VersionString, StringFormat=Heroesprofile.com Uploader {0}}"
+ d:DesignWidth="551">
@@ -30,10 +30,10 @@
-
-
+
+
-
+
@@ -47,29 +47,24 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
diff --git a/Heroesprofile.Uploader.Windows/MainWindow.xaml.cs b/Heroesprofile.Uploader.Windows/MainWindow.xaml.cs
index 7ed23a3..11a81bf 100644
--- a/Heroesprofile.Uploader.Windows/MainWindow.xaml.cs
+++ b/Heroesprofile.Uploader.Windows/MainWindow.xaml.cs
@@ -1,6 +1,8 @@
-// using Squirrel;
+using Heroesprofile.Uploader.Common;
+using Heroesprofile.Uploader.Windows.Core;
using System;
+using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Input;
@@ -9,40 +11,45 @@ namespace Heroesprofile.Uploader.Windows
{
public partial class MainWindow : Window
{
- public App App => Application.Current as App;
+ public string VersionString => App.Current.VersionString;
- private bool ShutdownOnClose = true;
+ public UserSettings UserSettings => App.Current.UserSettings;
- public MainWindow()
- {
- InitializeComponent();
+ public ObservableCollectionEx Files => App.Current.Manager.Files;
- }
+ public Manager Manager => App.Current.Manager;
- private void Twitch_Extension_Checkbox_Checked(object sender, RoutedEventArgs e)
+ public bool StartWithWindows
{
-
+ get => App.Current.StartWithWindows;
+ set => App.Current.StartWithWindows = value;
}
- private void Twitch_Extension_Checkbox_Unchecked(object sender, RoutedEventArgs e)
+
+ public MainWindow()
{
+ InitializeComponent();
+ DataContext = this;
+
}
+
private void Window_StateChanged(object sender, EventArgs e)
{
- if (App.Settings.MinimizeToTray && WindowState == WindowState.Minimized) {
- App.TrayIcon.Visible = true;
- ShutdownOnClose = false;
- Close();
+ if (App.Current.UserSettings.MinimizeToTray) {
+ if (WindowState == WindowState.Minimized) {
+ Hide();
+ }
}
}
private void Window_Closed(object sender, EventArgs e)
{
- App.mainWindow = null;
- if (ShutdownOnClose) {
- App.Shutdown();
+ if (App.Current.UserSettings.MinimizeToTray) {
+
+ } else {
+ App.Current.Shutdown();
}
}
@@ -53,25 +60,13 @@ private void Logo_MouseUp(object sender, MouseButtonEventArgs e)
private void ShowLog_Click(object sender, RoutedEventArgs e)
{
- Process.Start("explorer.exe", $@"{App.SettingsDir}\logs");
+ Process.Start("explorer.exe", $@"{App.Current.SettingsDir}\logs");
}
private void Settings_Click(object sender, RoutedEventArgs e)
{
var settings = new SettingsWindow() { Owner = this, DataContext = this };
settings.ShowDialog();
-
- }
-
- private async void Restart_Click(object sender, RoutedEventArgs e)
- {
- // Actually this should never happen when squirrel is disabled
-#pragma warning disable 162
- //if (!App.NoSquirrel) {
- // await UpdateManager.RestartAppWhenExited();
- //}
-#pragma warning restore 162
- App.Shutdown();
}
}
}
diff --git a/Heroesprofile.Uploader.Windows/NotifyIconResources.xaml b/Heroesprofile.Uploader.Windows/NotifyIconResources.xaml
new file mode 100644
index 0000000..ab0c01a
--- /dev/null
+++ b/Heroesprofile.Uploader.Windows/NotifyIconResources.xaml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Heroesprofile.Uploader.Windows/Properties/PublishProfiles/ClickOnceProfile.pubxml b/Heroesprofile.Uploader.Windows/Properties/PublishProfiles/ClickOnceProfile.pubxml
deleted file mode 100644
index e4abe66..0000000
--- a/Heroesprofile.Uploader.Windows/Properties/PublishProfiles/ClickOnceProfile.pubxml
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
- 0
- 2.0.3.0
- True
- Release
- True
- true
- True
- Web
- https://heroesreplay.github.io/HeroesProfile.Uploader/
- False
- True
- True
- False
- Any CPU
- bin\Release\net8.0-windows\win-x64\app.publish\
- bin\publish\
- ClickOnce
- False
- False
- True
- sha256RSA
- False
- net8.0-windows
- True
- Foreground
- False
- Publish.html
- True
- Heroes Profile Uploader
- Heroes Profile
- win-x64
- false
- en
- False
- True
-
-
\ No newline at end of file
diff --git a/Heroesprofile.Uploader.Windows/Properties/Settings.Designer.cs b/Heroesprofile.Uploader.Windows/Properties/Settings.Designer.cs
deleted file mode 100644
index d04fc46..0000000
--- a/Heroesprofile.Uploader.Windows/Properties/Settings.Designer.cs
+++ /dev/null
@@ -1,194 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated by a tool.
-// Runtime Version:4.0.30319.42000
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace Heroesprofile.Uploader.Windows.Properties {
-
-
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.11.0.0")]
- public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
-
- private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
-
- public static Settings Default {
- get {
- return defaultInstance;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("True")]
- public bool UpgradeRequired {
- get {
- return ((bool)(this["UpgradeRequired"]));
- }
- set {
- this["UpgradeRequired"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("True")]
- public bool AutoUpdate {
- get {
- return ((bool)(this["AutoUpdate"]));
- }
- set {
- this["AutoUpdate"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("https://github.com/Heroes-Profile/HeroesProfile.Uploader")]
- public string UpdateRepository {
- get {
- return ((string)(this["UpdateRepository"]));
- }
- set {
- this["UpdateRepository"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("400")]
- public int WindowTop {
- get {
- return ((int)(this["WindowTop"]));
- }
- set {
- this["WindowTop"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("400")]
- public int WindowLeft {
- get {
- return ((int)(this["WindowLeft"]));
- }
- set {
- this["WindowLeft"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("False")]
- public bool MinimizeToTray {
- get {
- return ((bool)(this["MinimizeToTray"]));
- }
- set {
- this["MinimizeToTray"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("600")]
- public int WindowHeight {
- get {
- return ((int)(this["WindowHeight"]));
- }
- set {
- this["WindowHeight"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("700")]
- public int WindowWidth {
- get {
- return ((int)(this["WindowWidth"]));
- }
- set {
- this["WindowWidth"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("None")]
- public global::Heroesprofile.Uploader.Common.DeleteFiles DeleteAfterUpload {
- get {
- return ((global::Heroesprofile.Uploader.Common.DeleteFiles)(this["DeleteAfterUpload"]));
- }
- set {
- this["DeleteAfterUpload"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("MetroDark")]
- public string Theme {
- get {
- return ((string)(this["Theme"]));
- }
- set {
- this["Theme"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("False")]
- public bool AllowPreReleases {
- get {
- return ((bool)(this["AllowPreReleases"]));
- }
- set {
- this["AllowPreReleases"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("")]
- public string ApplicationVersion {
- get {
- return ((string)(this["ApplicationVersion"]));
- }
- set {
- this["ApplicationVersion"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("False")]
- public bool PreMatchPage {
- get {
- return ((bool)(this["PreMatchPage"]));
- }
- set {
- this["PreMatchPage"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("False")]
- public bool PostMatchPage {
- get {
- return ((bool)(this["PostMatchPage"]));
- }
- set {
- this["PostMatchPage"] = value;
- }
- }
- }
-}
diff --git a/Heroesprofile.Uploader.Windows/Properties/Settings.settings b/Heroesprofile.Uploader.Windows/Properties/Settings.settings
deleted file mode 100644
index 3e56066..0000000
--- a/Heroesprofile.Uploader.Windows/Properties/Settings.settings
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
- True
-
-
- True
-
-
- https://github.com/Heroes-Profile/HeroesProfile.Uploader
-
-
- 400
-
-
- 400
-
-
- False
-
-
- 600
-
-
- 700
-
-
- None
-
-
- MetroDark
-
-
- False
-
-
-
-
-
- False
-
-
- False
-
-
-
\ No newline at end of file
diff --git a/Heroesprofile.Uploader.Windows/UIHelpers/FlagsConverter.cs b/Heroesprofile.Uploader.Windows/UIHelpers/FlagsConverter.cs
index 994156f..eeecec4 100644
--- a/Heroesprofile.Uploader.Windows/UIHelpers/FlagsConverter.cs
+++ b/Heroesprofile.Uploader.Windows/UIHelpers/FlagsConverter.cs
@@ -1,4 +1,5 @@
using System;
+using System.Windows;
namespace Heroesprofile.Uploader.Windows.UIHelpers
{
@@ -10,9 +11,8 @@ protected override bool Convert(Enum value, Enum parameter)
}
protected override Enum ConvertBack(bool value, Enum parameter)
- {
- // I was unable to find how to get source binding value, so let's use a dirty hack
- var val = App.Settings.DeleteAfterUpload;
+ {
+ var val = App.Current.AppSettings.DeleteAfterUpload;
if (value) {
val |= (Common.DeleteFiles)parameter;
diff --git a/Heroesprofile.Uploader.Windows/appsettings.json b/Heroesprofile.Uploader.Windows/appsettings.json
index 954e581..b44d42d 100644
--- a/Heroesprofile.Uploader.Windows/appsettings.json
+++ b/Heroesprofile.Uploader.Windows/appsettings.json
@@ -1,8 +1,5 @@
{
- "AppConfig": {
- "UpgradeRequired": true,
- "AutoUpdate": true,
- "UpdateRepository": "https://github.com/Heroes-Profile/HeroesProfile.Uploader",
+ "AppSettings": {
"WindowTop": 400,
"WindowLeft": 400,
"MinimizeToTray": false,
@@ -10,8 +7,6 @@
"WindowWidth": 700,
"DeleteAfterUpload": "None",
"Theme": "MetroDark",
- "AllowPreReleases": false,
- "ApplicationVersion": "",
"PreMatchPage": false,
"PostMatchPage": false
},
diff --git a/Heroesprofile.Uploader.Windows/icon.ico b/Heroesprofile.Uploader.Windows/icon.ico
new file mode 100644
index 0000000..9d21f00
Binary files /dev/null and b/Heroesprofile.Uploader.Windows/icon.ico differ
diff --git a/dotnet-mage-release.ps1 b/dotnet-mage-release.ps1
new file mode 100644
index 0000000..d7eeb9d
--- /dev/null
+++ b/dotnet-mage-release.ps1
@@ -0,0 +1,46 @@
+# Load current Git tag
+$tag = $(git describe --tags)
+$version = $tag.Split('-')[0].TrimStart('v')
+$version = "$version.0"
+
+Write-Output "Tag: $tag"
+Write-Output "Version: $version"
+
+$name = "Heroes Profile Uploader"
+$publisher = "Heroes Profile"
+$appName = "Heroesprofile.Uploader"
+$projDir = ".\Heroesprofile.Uploader.Windows"
+
+$outDir = "$projDir\bin\publish"
+if (Test-Path $outDir) {
+ Remove-Item -Path $outDir -Recurse
+}
+
+dotnet tool install --global microsoft.dotnet.mage --version 8.0.0
+
+dotnet publish "${projDir}" -c Release -r win-x64 --self-contained false -o "${outDir}"
+
+dotnet mage -ClearApplicationCache
+
+dotnet mage -al "${appName}.exe" -TargetDirectory "${outDir}"
+
+dotnet mage -New Application `
+ -FromDirectory "${outDir}" `
+ -ToFile "${outDir}\${appName}.manifest" `
+ -Name "${name}" `
+ -Version $version `
+ -IconFile "icon.ico"
+
+dotnet mage -New Deployment `
+ -Install true `
+ -Publisher "${publisher}" `
+ -Version $version `
+ -Name "${name}" `
+ -AppManifest "${outDir}\${appName}.manifest" `
+ -ToFile "${outDir}\${appName}.application" `
+ -ProviderUrl "https://heroesreplay.github.io/HeroesProfile.Uploader/" `
+ -SupportURL "https://www.heroesprofile.com/Contact"
+
+
+# dotnet mage -Verify "${outDir}\${appName}.application"
+# dotnet mage -Verify "${outDir}\${appName}.manifest"