diff --git a/src/settings-ui/Settings.UI/NewUtilityAttribute.cs b/src/settings-ui/Settings.UI/NewUtilityAttribute.cs
new file mode 100644
index 0000000000..c7b557971c
--- /dev/null
+++ b/src/settings-ui/Settings.UI/NewUtilityAttribute.cs
@@ -0,0 +1,19 @@
+// Copyright (c) Microsoft Corporation
+// The Microsoft Corporation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace Microsoft.PowerToys.Settings.UI
+{
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
+ public sealed class NewUtilityAttribute : Attribute
+ {
+ public string Version { get; }
+
+ public NewUtilityAttribute(string version)
+ {
+ Version = version;
+ }
+ }
+}
diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/LightSwitchPage.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/Views/LightSwitchPage.xaml.cs
index d970700484..0f87cb170b 100644
--- a/src/settings-ui/Settings.UI/SettingsXAML/Views/LightSwitchPage.xaml.cs
+++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/LightSwitchPage.xaml.cs
@@ -21,10 +21,10 @@ using PowerToys.GPOWrapper;
using Settings.UI.Library;
using Settings.UI.Library.Helpers;
using Windows.Devices.Geolocation;
-using Windows.Services.Maps;
namespace Microsoft.PowerToys.Settings.UI.Views
{
+ [NewUtility("v0.95")]
public sealed partial class LightSwitchPage : Page
{
private readonly string _appName = "LightSwitch";
diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml
index c2de045ed2..84843bb1f4 100644
--- a/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml
+++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml
@@ -177,9 +177,6 @@
AutomationProperties.AutomationId="SystemToolsNavItem"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/SystemTools.png}"
SelectsOnInvoked="False">
-
-
-
-
-
-
-
+ Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/LightSwitch.png}" />
AppTitleBar;
+ private static string _version = Helper.GetProductVersion();
private Dictionary _navViewParentLookup = new Dictionary();
private List _searchSuggestions = [];
@@ -168,15 +166,26 @@ namespace Microsoft.PowerToys.Settings.UI.Views
}
var topLevelItems = navigationView.MenuItems.OfType().ToArray();
+ var newTopLevelItems = new HashSet();
foreach (var parent in topLevelItems)
{
foreach (var child in parent.MenuItems.OfType())
{
- _navViewParentLookup.TryAdd(child.GetValue(NavHelper.NavigateToProperty) as Type, parent);
+ var pageType = child.GetValue(NavHelper.NavigateToProperty) as Type;
+ _navViewParentLookup.TryAdd(pageType, parent);
_searchSuggestions.Add(child.Content?.ToString());
+ if (AddNewTagIfNeeded(child, pageType))
+ {
+ newTopLevelItems.Add(parent);
+ }
}
}
+
+ foreach (var parent in newTopLevelItems)
+ {
+ parent.InfoBadge = GetNewInfoBadge();
+ }
}
public static int SendDefaultIPCMessage(string msg)
@@ -717,6 +726,27 @@ namespace Microsoft.PowerToys.Settings.UI.Views
NavigationService.Navigate(searchParams);
}
+ private bool AddNewTagIfNeeded(NavigationViewItem item, Type pageType)
+ {
+ var newUtility = pageType.GetCustomAttribute();
+
+ if (newUtility != null && _version.StartsWith(newUtility.Version, StringComparison.InvariantCulture))
+ {
+ item.InfoBadge = GetNewInfoBadge();
+ return true;
+ }
+
+ return false;
+ }
+
+ private InfoBadge GetNewInfoBadge()
+ {
+ return new InfoBadge
+ {
+ Style = (Style)Application.Current.Resources["NewInfoBadge"],
+ };
+ }
+
public void Dispose()
{
if (_disposed)