diff --git a/HabiticaHourUpVSIX/AppSettings/Models/HabiticaSettingsModel.cs b/HabiticaHourUpVSIX/AppSettings/Models/HabiticaSettingsModel.cs index 867b349..e276af4 100644 --- a/HabiticaHourUpVSIX/AppSettings/Models/HabiticaSettingsModel.cs +++ b/HabiticaHourUpVSIX/AppSettings/Models/HabiticaSettingsModel.cs @@ -2,4 +2,4 @@ namespace HabiticaHourUpVSIX.AppSettings.Models; -public record struct HabiticaSettingsModel(TimeSpan LastWorkTime, int TotalTicks); \ No newline at end of file +public record struct HabiticaSettingsModel(TimeSpan LastWorkTimeLeft, DateTime LastCloseDateTime, int TotalTicks); \ No newline at end of file diff --git a/HabiticaHourUpVSIX/AppSettings/Settings.cs b/HabiticaHourUpVSIX/AppSettings/Settings.cs index 21de282..7d2ceed 100644 --- a/HabiticaHourUpVSIX/AppSettings/Settings.cs +++ b/HabiticaHourUpVSIX/AppSettings/Settings.cs @@ -72,6 +72,8 @@ public override void Save() internal class SettingsInFile(string fileName, T defaultSettings) : SettingsWithSaving where T : struct { + private readonly JsonSerializerSettings _deserializationSettings = new() { MissingMemberHandling = MissingMemberHandling.Error }; + public override T Read() { if (!File.Exists(fileName)) @@ -81,7 +83,19 @@ public override T Read() } string data = File.ReadAllText(fileName); - var result = JsonConvert.DeserializeObject(data); + + T result = defaultSettings; + try + { + result = JsonConvert.DeserializeObject(data, _deserializationSettings); + } + catch (JsonSerializationException) + { + // On member not found we read all existing members and write it + result = JsonConvert.DeserializeObject(data); + Write(result); + return result; + } return result; } diff --git a/HabiticaHourUpVSIX/HabiticaHourUpVSIXPackage.cs b/HabiticaHourUpVSIX/HabiticaHourUpVSIXPackage.cs index f5f955d..929cc51 100644 --- a/HabiticaHourUpVSIX/HabiticaHourUpVSIXPackage.cs +++ b/HabiticaHourUpVSIX/HabiticaHourUpVSIXPackage.cs @@ -10,6 +10,7 @@ using Microsoft.VisualStudio; using Microsoft.VisualStudio.Threading; using System.IO; +using System.Reflection; using System.Runtime.InteropServices; using System.Threading; #nullable enable @@ -23,6 +24,9 @@ namespace HabiticaHourUpVSIX; [ProvideToolWindow(typeof(SettingsToolWindow.Pane))] public sealed class HabiticaHourUpVSIXPackage : ToolkitPackage { + private readonly TimeSpan OneMinute = TimeSpan.FromMinutes(1d); + private readonly TimeSpan OneDay = TimeSpan.FromDays(1d); + private IAudioPlayer _soundPlayer; public SettingsWithSaving HabiticaSettingsReader { get; private set; } @@ -74,6 +78,50 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke TimeSpan tickAfter = vsSettings.Divisor; Timer.Change(tickAfter, vsSettings.Divisor); + + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); + VS.Events.SolutionEvents.OnAfterCloseSolution += OnClose; + + await SetLastTimerIfUserAgreeAsync(habiticaSettings, vsSettings.Divisor); + } + + private async Task SetLastTimerIfUserAgreeAsync(HabiticaSettingsModel habiticaSettings, TimeSpan divisor) + { + var lastWorkTimeLeft = habiticaSettings.LastWorkTimeLeft; + //if (lastWorkTimeLeft < OneMinute) + // return; + + var lastCloseAgo = DateTime.Now - habiticaSettings.LastCloseDateTime; + string lastCloseAgoFormat = @"hh\:mm\:ss"; + if (lastCloseAgo >= OneDay) + lastCloseAgoFormat = @"dd\:hh\:mm\:ss"; + + string setLastNextTickMessage = $""" +On last session next tick was: {lastWorkTimeLeft}. +Do you want to load it? +Last session was on: {habiticaSettings.LastCloseDateTime}({lastCloseAgo.ToString(lastCloseAgoFormat)} ago) +"""; + + var model = new InfoBarModel(setLastNextTickMessage, new[] { new InfoBarHyperlink("Click here to load") }); + + var infoBar = await VS.InfoBar.CreateAsync(model); + // if infoBar was null, maybe solution not loaded, then we wait for it. + if (infoBar is null) + { + VS.Events.SolutionEvents.OnAfterOpenSolution += SolutionOpened; + return; + async void SolutionOpened(Solution? obj) + { + VS.Events.SolutionEvents.OnAfterOpenSolution -= SolutionOpened; + // We read because there may have been changes in settings outside(settings file may be changed) + await SetLastTimerIfUserAgreeAsync(HabiticaSettingsReader.Read(), UserSettingsReader.Read().Divisor); + } + } + + // Maybe close infoBar on click + infoBar.ActionItemClicked += (s, e) => { Timer.Change(lastWorkTimeLeft, divisor); /*((InfoBar)s).Close();*/ }; + + await infoBar.TryShowInfoBarUIAsync(); } internal void PlayBeep() @@ -131,6 +179,11 @@ async delegate } }).FireAndForget(); } + private void OnClose() + { + HabiticaSettingsReader.SetWithSave(x => x.LastWorkTimeLeft, Timer.NextTick); + HabiticaSettingsReader.SetWithSave(x => x.LastCloseDateTime, DateTime.Now); + } private void UserSettingsReader_OnSaving(UserSettingsModel userSettingsModel) { @@ -152,6 +205,7 @@ private void AddTicksToAllSettings(int addedTicks) protected override void Dispose(bool disposing) { + VS.Events.SolutionEvents.OnAfterCloseSolution -= OnClose; Timer?.Dispose(); base.Dispose(disposing); } diff --git a/HabiticaHourUpVSIX/SettingsExtensions.cs b/HabiticaHourUpVSIX/SettingsExtensions.cs index 7c0a2dc..6b39329 100644 --- a/HabiticaHourUpVSIX/SettingsExtensions.cs +++ b/HabiticaHourUpVSIX/SettingsExtensions.cs @@ -6,14 +6,6 @@ namespace HabiticaHourUpVSIX; // Need read before write, because there may be data that needs to be left untouched public static partial class SettingsExtensions { - public static void SetLastTickAfterWithSave(this SettingsWithSaving obj1, TimeSpan lastTickToSet) - { - HabiticaSettingsModel settingsRead = obj1.Read(); - var settingsToWrite = settingsRead with { LastWorkTime = lastTickToSet }; - - obj1.Write(settingsToWrite); - obj1.Save(); - } public static void SetTotalTicksWithSave(this SettingsWithSaving obj1, int ticksToSet) { HabiticaSettingsModel settingsRead = obj1.Read(); diff --git a/HabiticaHourUpVSIX/source.extension.cs b/HabiticaHourUpVSIX/source.extension.cs index edc4323..c940064 100644 --- a/HabiticaHourUpVSIX/source.extension.cs +++ b/HabiticaHourUpVSIX/source.extension.cs @@ -11,7 +11,7 @@ internal sealed partial class Vsix public const string Name = "HabiticaHourUpVSIX"; public const string Description = @"Empty VSIX Project."; public const string Language = "en-US"; - public const string Version = "1.5.1"; + public const string Version = "1.5.2"; public const string Author = "Ar6"; public const string Tags = ""; } diff --git a/HabiticaHourUpVSIX/source.extension.vsixmanifest b/HabiticaHourUpVSIX/source.extension.vsixmanifest index 57ab15d..307e299 100644 --- a/HabiticaHourUpVSIX/source.extension.vsixmanifest +++ b/HabiticaHourUpVSIX/source.extension.vsixmanifest @@ -1,7 +1,7 @@  - + HabiticaHourUpVSIX Empty VSIX Project. Resources\Icon.png