Skip to content

Commit 9a356c9

Browse files
authored
Feature: Upgrade note dialog (#3077)
* Feature: Upgrade note * Docs: #3077 * Chore: Rename dialog
1 parent 0ca4eff commit 9a356c9

File tree

14 files changed

+277
-28
lines changed

14 files changed

+277
-28
lines changed

Source/GlobalAssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
[assembly: AssemblyTrademark("")]
77
[assembly: AssemblyCulture("")]
88

9-
[assembly: AssemblyVersion("2025.5.22.0")]
10-
[assembly: AssemblyFileVersion("2025.5.22.0")]
9+
[assembly: AssemblyVersion("2025.6.13.0")]
10+
[assembly: AssemblyFileVersion("2025.6.13.0")]

Source/NETworkManager.Documentation/DocumentationIdentifier.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,5 +203,10 @@ public enum DocumentationIdentifier
203203
/// <summary>
204204
/// Command line arguments.
205205
/// </summary>
206-
CommandLineArguments
206+
CommandLineArguments,
207+
208+
/// <summary>
209+
/// Changelog base documentation page.
210+
/// </summary>
211+
ChangelogBase
207212
}

Source/NETworkManager.Documentation/DocumentationManager.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,12 @@ public static class DocumentationManager
137137
@"Documentation/profiles"),
138138

139139
new DocumentationInfo(DocumentationIdentifier.CommandLineArguments,
140-
@"docs/commandline-arguments")
140+
@"docs/commandline-arguments"),
141+
142+
new DocumentationInfo(DocumentationIdentifier.ChangelogBase,
143+
@"docs/changelog")
141144
];
142145

143-
/// <summary>
144-
/// Command to open a documentation page based on <see cref="DocumentationIdentifier" />.
145-
/// </summary>
146-
public static ICommand OpenDocumentationCommand => new RelayCommand(OpenDocumentationAction);
147-
148146
/// <summary>
149147
/// Method to create the documentation url from <see cref="DocumentationIdentifier" />.
150148
/// </summary>
@@ -179,13 +177,15 @@ public static void OpenDocumentation(DocumentationIdentifier documentationIdenti
179177
}
180178

181179
/// <summary>
182-
/// Method to open a documentation page based on <see cref="DocumentationIdentifier" />.
180+
/// Method to open the current changelog in the default web browser.
183181
/// </summary>
184-
/// <param name="documentationIdentifier"></param>
185-
private static void OpenDocumentationAction(object documentationIdentifier)
182+
public static void OpenChangelog()
186183
{
187-
if (documentationIdentifier != null)
188-
OpenDocumentation((DocumentationIdentifier)documentationIdentifier);
184+
var url = CreateUrl(DocumentationIdentifier.ChangelogBase);
185+
186+
url += $"/{AssemblyManager.Current.Version.ToString().Replace('.', '-')}";
187+
188+
ExternalProcessStarter.OpenUrl(url);
189189
}
190190

191191
/// <summary>

Source/NETworkManager.Localization/Resources/Strings.Designer.cs

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Source/NETworkManager.Localization/Resources/Strings.resx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3918,4 +3918,16 @@ Right-click for more options.</value>
39183918
<data name="RetryingInXSecondsDots" xml:space="preserve">
39193919
<value>Retrying in {0} seconds...</value>
39203920
</data>
3921+
<data name="WhatsNew" xml:space="preserve">
3922+
<value>What's new?</value>
3923+
</data>
3924+
<data name="Changelog" xml:space="preserve">
3925+
<value>Changelog</value>
3926+
</data>
3927+
<data name="UpgradedToXXX" xml:space="preserve">
3928+
<value>Upgraded to {0}</value>
3929+
</data>
3930+
<data name="WhatsNewMessage" xml:space="preserve">
3931+
<value>This release includes new features, improvements, and bug fixes. Check out the changelog for all the details!</value>
3932+
</data>
39213933
</root>

Source/NETworkManager.Settings/ConfigurationInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public ConfigurationInfo(bool isAdmin, string executionPath, string applicationF
3131
/// <summary>
3232
/// Indicates that the application is running as administrator.
3333
/// </summary>
34-
public bool IsAdmin { get; set; }
34+
public bool IsAdmin { get; }
3535

3636
/// <summary>
3737
/// Execution path of the application like "C:\Program Files\NETworkManager".

Source/NETworkManager.Settings/ConfigurationManager.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
using System.IO;
1+
using NETworkManager.Models;
2+
using System.IO;
23
using System.Security.Principal;
3-
using NETworkManager.Models;
44

55
namespace NETworkManager.Settings;
66

@@ -26,11 +26,12 @@ public static class ConfigurationManager
2626
static ConfigurationManager()
2727
{
2828
Current = new ConfigurationInfo(
29-
new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator),
30-
AssemblyManager.Current.Location,
31-
Path.Combine(AssemblyManager.Current.Location, AssemblyManager.Current.Name + ".exe"),
32-
AssemblyManager.Current.Name,
33-
File.Exists(Path.Combine(AssemblyManager.Current.Location, $"{IsPortableFileName}.{IsPortableExtension}")));
29+
isAdmin: new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator),
30+
executionPath: AssemblyManager.Current.Location,
31+
applicationFullName: Path.Combine(AssemblyManager.Current.Location, AssemblyManager.Current.Name + ".exe"),
32+
applicationName: AssemblyManager.Current.Name,
33+
isPortable: File.Exists(Path.Combine(AssemblyManager.Current.Location, $"{IsPortableFileName}.{IsPortableExtension}"))
34+
);
3435
}
3536

3637
/// <summary>

Source/NETworkManager.Settings/SettingsInfo.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,18 @@ namespace NETworkManager.Settings;
2222

2323
public class SettingsInfo : INotifyPropertyChanged
2424
{
25+
/// <summary>
26+
/// Occurs when a property value changes.
27+
/// </summary>
28+
/// <remarks>This event is typically used to notify subscribers that a property value has been updated. It
29+
/// is commonly implemented in classes that support data binding or need to signal changes to property
30+
/// values.</remarks>
2531
public event PropertyChangedEventHandler PropertyChanged;
2632

33+
/// <summary>
34+
/// Helper method to raise the <see cref="PropertyChanged" /> event.
35+
/// </summary>
36+
/// <param name="propertyName">Name of the property that changed.</param>
2737
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
2838
{
2939
SettingsChanged = true;
@@ -35,8 +45,14 @@ private void OnPropertyChanged([CallerMemberName] string propertyName = null)
3545

3646
[XmlIgnore] public bool SettingsChanged { get; set; }
3747

48+
/// <summary>
49+
/// Private field for the <see cref="WelcomeDialog_Show" /> property.
50+
/// </summary>
3851
private bool _welcomeDialog_Show = true;
3952

53+
/// <summary>
54+
/// Determines if the welcome dialog should be shown on application start.
55+
/// </summary>
4056
public bool WelcomeDialog_Show
4157
{
4258
get => _welcomeDialog_Show;
@@ -50,8 +66,37 @@ public bool WelcomeDialog_Show
5066
}
5167
}
5268

69+
/// <summary>
70+
/// Private field for the <see cref="UpgradeDialog_Show" /> property.
71+
/// </summary>
72+
private bool _upgradeDialog_Show;
73+
74+
/// <summary>
75+
/// Indicates if the update dialog should be shown on application start.
76+
/// Usually this is set to true if the application has been updated to a new version.
77+
/// </summary>
78+
public bool UpgradeDialog_Show
79+
{
80+
get => _upgradeDialog_Show;
81+
set
82+
{
83+
if (value == _upgradeDialog_Show)
84+
return;
85+
86+
_upgradeDialog_Show = value;
87+
OnPropertyChanged();
88+
}
89+
}
90+
91+
/// <summary>
92+
/// Private field for the <see cref="Version" /> property.
93+
/// </summary>
5394
private string _version;
5495

96+
/// <summary>
97+
/// Version of the settings file. Should be identical to the version of the application.
98+
/// It is used to determine if the settings file needs to be updated.
99+
/// </summary>
55100
public string Version
56101
{
57102
get => _version;

Source/NETworkManager.Settings/SettingsManager.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,6 @@ public static void Upgrade(Version fromVersion, Version toVersion)
186186
if (fromVersion < new Version(2023, 11, 28, 0))
187187
UpgradeTo_2023_11_28_0();
188188

189-
190189
// 2024.11.11.0
191190
if (fromVersion < new Version(2024, 11, 11, 0))
192191
UpgradeTo_2024_11_11_0();
@@ -196,7 +195,9 @@ public static void Upgrade(Version fromVersion, Version toVersion)
196195
UpgradeToLatest(toVersion);
197196

198197
// Update to the latest version and save
198+
Current.UpgradeDialog_Show = true;
199199
Current.Version = toVersion.ToString();
200+
200201
Save();
201202

202203
Log.Info("Settings upgrade finished!");

Source/NETworkManager/MainWindow.xaml.cs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ public ProfileFileInfo SelectedProfileFile
393393
{
394394
if (!_isProfileFileUpdating)
395395
LoadProfile(value);
396-
396+
397397
ConfigurationManager.Current.ProfileManagerShowUnlock = value.IsEncrypted && !value.IsPasswordValid;
398398
SettingsManager.Current.Profiles_LastSelected = value.Name;
399399
}
@@ -513,6 +513,27 @@ await this.ShowMessageAsync(Strings.SettingsHaveBeenReset,
513513

514514
await this.ShowChildWindowAsync(childWindow);
515515
}
516+
else if (SettingsManager.Current.UpgradeDialog_Show)
517+
{
518+
var childWindow = new UpgradeChildWindow();
519+
520+
var viewModel = new UpgradeViewModel(instance =>
521+
{
522+
childWindow.IsOpen = false;
523+
524+
SettingsManager.Current.UpgradeDialog_Show = false;
525+
526+
SettingsManager.Save();
527+
528+
Load();
529+
});
530+
531+
childWindow.DataContext = viewModel;
532+
533+
ConfigurationManager.Current.IsChildWindowOpen = true;
534+
535+
await this.ShowChildWindowAsync(childWindow);
536+
}
516537
else
517538
{
518539
Load();
@@ -826,11 +847,11 @@ private void OnApplicationViewVisible(ApplicationName name, bool fromSettings =
826847
ContentControlApplication.Content = _sntpLookupHostView;
827848
break;
828849
case ApplicationName.HostsFileEditor:
829-
if(_hostsFileEditorView == null)
850+
if (_hostsFileEditorView == null)
830851
_hostsFileEditorView = new HostsFileEditorView();
831852
else
832853
_hostsFileEditorView.OnViewVisible();
833-
854+
834855
ContentControlApplication.Content = _hostsFileEditorView;
835856
break;
836857
case ApplicationName.DiscoveryProtocol:
@@ -913,7 +934,7 @@ private void OnApplicationViewVisible(ApplicationName name, bool fromSettings =
913934

914935
ContentControlApplication.Content = _arpTableView;
915936
break;
916-
937+
917938
default:
918939
Log.Error("Cannot show unknown application view: " + name);
919940
break;
@@ -1387,7 +1408,7 @@ private void LoadProfiles()
13871408
.FirstOrDefault(x => x.Name == SettingsManager.Current.Profiles_LastSelected);
13881409
SelectedProfileFile ??= ProfileFiles.SourceCollection.Cast<ProfileFileInfo>().FirstOrDefault();
13891410
}
1390-
1411+
13911412
private async void LoadProfile(ProfileFileInfo info, bool showWrongPassword = false)
13921413
{
13931414
// Disable profile management while switching profiles
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using NETworkManager.Documentation;
2+
using NETworkManager.Settings;
3+
using NETworkManager.Utilities;
4+
using System;
5+
using System.Windows.Input;
6+
7+
namespace NETworkManager.ViewModels;
8+
9+
public class UpgradeViewModel : ViewModelBase
10+
{
11+
public static string Title => string.Format(Localization.Resources.Strings.UpgradedToXXX, AssemblyManager.Current.Version);
12+
13+
public UpgradeViewModel(Action<UpgradeViewModel> continueCommand)
14+
{
15+
ContinueCommand = new RelayCommand(_ => continueCommand(this));
16+
}
17+
18+
public ICommand OpenWebsiteCommand => new RelayCommand(OpenWebsiteAction);
19+
20+
private static void OpenWebsiteAction(object url)
21+
{
22+
ExternalProcessStarter.OpenUrl((string)url);
23+
}
24+
25+
public ICommand OpenChangelogCommand => new RelayCommand(OpenChangelogAction);
26+
27+
private void OpenChangelogAction(object obj)
28+
{
29+
DocumentationManager.OpenChangelog();
30+
}
31+
32+
public ICommand ContinueCommand { get; }
33+
}

0 commit comments

Comments
 (0)