From 480474c34353dd586bd664a3f68936a85acc8317 Mon Sep 17 00:00:00 2001 From: Mario Steele Date: Fri, 1 Aug 2025 22:09:46 -0500 Subject: [PATCH] Updated App.axaml.cs Added fields for Normal icon, Waiting to Sync Icon, and Syncing Complete icons to let user know of changes in the state of the Syncer. Added function to ensure that we are changing the Icon and Tooltip on the UI Thread, instead of some other thread. Updated SyncMonitor to check for any dirty syncers, and if so, we update our SysTray icon. Added update to show we are syncing the data (Tooltip only) Added update to show we have compeleted sync. Added timer for 3 seconds before resetting SysTray and tooltip back to normal status. --- FreeTubeSyncer/App.axaml.cs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/FreeTubeSyncer/App.axaml.cs b/FreeTubeSyncer/App.axaml.cs index 4f96b59..bbfd8ac 100644 --- a/FreeTubeSyncer/App.axaml.cs +++ b/FreeTubeSyncer/App.axaml.cs @@ -8,8 +8,11 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Avalonia; +using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; +using Avalonia.Platform; +using Avalonia.Threading; using FreeTubeSyncer.Library; using FreeTubeSyncer.Models; using FreeTubeSyncer.Models.DatabaseModels; @@ -39,13 +42,23 @@ public partial class App : Application private TimeSpan _checkInterval; private DateTime _lastUpdated; + private WindowIcon? _normalTrayIcon; + private WindowIcon? _waitingTrayIcon; + private WindowIcon? _completeTrayIcon; + public event EventHandler? SettingsChanged; public static App GetApp() => (App)App.Current!; public static ClassicDesktopStyleApplicationLifetime GetDesktop() => (ClassicDesktopStyleApplicationLifetime)App.Current!.ApplicationLifetime!; public override void Initialize() { + _normalTrayIcon = new WindowIcon(AssetLoader.Open(new Uri("avares://FreeTubeSyncer/Assets/freetubesyncer.64.png"))); + _waitingTrayIcon = new WindowIcon(AssetLoader.Open(new Uri("avares://FreeTubeSyncer/Assets/awaiting_sync.png"))); + _completeTrayIcon = new WindowIcon(AssetLoader.Open(new Uri("avares://FreeTubeSyncer/Assets/sync_complete.png"))); + var vm = new AppViewModel(); + vm.AppIcon = _normalTrayIcon; AvaloniaXamlLoader.Load(this); + DataContext = vm; } public override void OnFrameworkInitializationCompleted() @@ -159,6 +172,18 @@ public partial class App : Application Log.Information("Log Started."); } + private async Task UpdateSTIconHint(WindowIcon icon, string? hint = null) + { + await Dispatcher.UIThread.InvokeAsync(async () => + { + await _semaphoreSlim.WaitAsync(); + ((AppViewModel)DataContext!).AppIcon = icon; + if (hint != null) ((AppViewModel)DataContext).HintTooltip = hint; + _semaphoreSlim.Release(); + + }); + } + private async Task SyncMonitor() { Log.Information("Sync Monitor Starting Up."); @@ -191,6 +216,11 @@ public partial class App : Application while (_isRunning) { await Task.Delay(100); + + if (_syncers.Any(x => x.IsDirty())) + { + await UpdateSTIconHint(_waitingTrayIcon!, "FreeTube Syncer - Changes waiting to be written..."); + } var sinceLastCheck = DateTime.Now - lastCheck; if (sinceLastCheck.TotalSeconds > _checkInterval.TotalSeconds) @@ -219,6 +249,7 @@ public partial class App : Application if (procs.Length > 0) continue; Log.Information("FreeTube instance closed, and we have writes to make..."); await Task.Delay(1500); + await UpdateSTIconHint(_waitingTrayIcon, "FreeTube Syncer - Syncing data..."); await _semaphoreSlim.WaitAsync(); var syncStart = DateTime.Now; @@ -227,6 +258,12 @@ public partial class App : Application var syncEnd = DateTime.Now - syncStart; _semaphoreSlim.Release(); Log.Information("Sync Completed. Total Time: {EndTime}", syncEnd); + await UpdateSTIconHint(_completeTrayIcon, "FreeTube Syncer - Sync completed."); + Task.Run(async () => + { + await Task.Delay(3000); + await UpdateSTIconHint(_normalTrayIcon, "FreeTube Syncer - Watching files..."); + }); } Log.Information("Filesystem Sync Monitor shutdown.");