Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/settings-ui/Settings.UI/Helpers/NavigablePage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Hosting;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using Windows.UI;

namespace Microsoft.PowerToys.Settings.UI.Helpers;
Expand All @@ -23,6 +24,10 @@ public abstract partial class NavigablePage : Page

public NavigablePage()
{
// Cache the page instance so re-navigating doesn't rebuild the XAML tree, ViewModel,
// file watchers and IPC handlers each time. The Frame's default CacheSize (10) is
// sufficient to keep all top-level settings pages warm.
NavigationCacheMode = NavigationCacheMode.Enabled;
Loaded += OnPageLoaded;
}

Expand Down
3 changes: 1 addition & 2 deletions src/settings-ui/Settings.UI/SettingsXAML/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,9 @@
<tkcontrols:MarkdownConfig x:Key="DescriptionTextMarkdownConfig" Themes="{StaticResource DescriptionTextMarkdownThemeConfig}" />

<TransitionCollection x:Key="SettingsCardsAnimations">
<EntranceThemeTransition FromVerticalOffset="50" />
<!-- Animates cards when loaded -->
<RepositionThemeTransition IsStaggeringEnabled="False" />
<!-- Smoothly animates individual cards upon whenever Expanders are expanded/collapsed -->
<!-- EntranceThemeTransition removed: it replayed on every page navigation, causing a visible "second load" reflow and slowing perceived nav. -->
</TransitionCollection>
</ResourceDictionary>
</Application.Resources>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public sealed partial class AdvancedPastePage : NavigablePage, IRefreshablePage,
private CancellationTokenSource _foundryModelLoadCts;
private bool _suppressFoundrySelectionChanged;
private bool _isFoundryLocalAvailable;
private bool _isPasteAIProviderDialogOpen;
private bool _disposed;
private const string PasteAiDialogDefaultTitle = "Paste with AI provider configuration";

Expand Down Expand Up @@ -60,11 +61,16 @@ public AdvancedPastePage()
FoundryLocalPicker.LoadRequested += FoundryLocalPicker_LoadRequested;
}

Loaded += async (s, e) =>
Loaded += (s, e) =>
{
ViewModel.OnPageLoaded();
UpdatePasteAIUIVisibility();
await UpdateFoundryLocalUIAsync();

// Note: UpdatePasteAIUIVisibility() and UpdateFoundryLocalUIAsync() are deliberately
// NOT called here. They only affect controls inside PasteAIProviderConfigurationDialog,
// which is hidden until the user clicks Add/Edit provider. Both Add/Edit handlers call
// them right before ShowAsync(), so running them on every navigation is wasted work
// that produced a visible second reflow ("double load") and, for FoundryLocal, an
// unnecessary process probe.
};

Unloaded += (_, _) =>
Expand All @@ -81,8 +87,15 @@ public AdvancedPastePage()
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
UpdatePasteAIUIVisibility();
_ = UpdateFoundryLocalUIAsync();

// Only refresh the provider-configuration dialog state if it is currently open;
// otherwise this is wasted work (and, for FoundryLocal, an unnecessary process probe)
// that fires every time the runner broadcasts a general-settings update.
if (_isPasteAIProviderDialogOpen)
{
UpdatePasteAIUIVisibility();
_ = UpdateFoundryLocalUIAsync();
}
}

private void EnableAdvancedPasteAI() => ViewModel.EnableAI();
Expand Down Expand Up @@ -1116,6 +1129,7 @@ private async void ProviderMenuFlyoutItem_Click(object sender, RoutedEventArgs e
RefreshDialogBindings();

PasteAIApiKeyPasswordBox.Password = string.Empty;
_isPasteAIProviderDialogOpen = true;
await PasteAIProviderConfigurationDialog.ShowAsync();
}

Expand Down Expand Up @@ -1143,6 +1157,7 @@ private async void EditPasteAIProviderButton_Click(object sender, RoutedEventArg
await UpdateFoundryLocalUIAsync();
RefreshDialogBindings();
PasteAIApiKeyPasswordBox.Password = ViewModel.GetPasteAIApiKey(provider.Id, provider.ServiceType);
_isPasteAIProviderDialogOpen = true;
await PasteAIProviderConfigurationDialog.ShowAsync();
}

Expand All @@ -1159,6 +1174,7 @@ private void RemovePasteAIProviderButton_Click(object sender, RoutedEventArgs e)

private void PasteAIProviderConfigurationDialog_Closed(ContentDialog sender, ContentDialogClosedEventArgs args)
{
_isPasteAIProviderDialogOpen = false;
ViewModel?.CancelPasteAIProviderDraft();
PasteAIProviderConfigurationDialog.Title = PasteAiDialogDefaultTitle;
PasteAIApiKeyPasswordBox.Password = string.Empty;
Expand Down
Loading