Skip to content

Commit 8d60429

Browse files
committed
Fixed "On a fresh start, focusing on the Path Mode textbox doesn't open the suggestion flyout"
1 parent 89be2ba commit 8d60429

File tree

6 files changed

+40
-77
lines changed

6 files changed

+40
-77
lines changed

src/Files.App.Controls/Omnibar/IOmnibarTextMemberPathProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
namespace Files.App.Controls
55
{
66
/// <summary>
7-
/// An interface that provides a way to get the text member path of <see cref="OmnibarMode.SuggestionItemsSource"/>.
7+
/// An interface that provides a way to get the text member path of <see cref="OmnibarMode.ItemsSource"/>.
88
/// </summary>
99
/// <remarks>
1010
/// An alternative to this interface is to use an <see cref="Microsoft.UI.Xaml.Data.IBindableCustomPropertyImplementation"/> powered by CsWinRT.

src/Files.App.Controls/Omnibar/Omnibar.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ protected void ChangeMode(OmnibarMode? oldMode, OmnibarMode newMode)
156156
newMode.IsTabStop = false;
157157

158158
_textBox.PlaceholderText = newMode.PlaceholderText ?? string.Empty;
159-
_textBoxSuggestionsListView.ItemTemplate = newMode.SuggestionItemTemplate;
160-
_textBoxSuggestionsListView.ItemsSource = newMode.SuggestionItemsSource;
159+
_textBoxSuggestionsListView.ItemTemplate = newMode.ItemTemplate;
160+
_textBoxSuggestionsListView.ItemsSource = newMode.ItemsSource;
161161

162162
if (newMode.IsAutoFocusEnabled)
163163
{
@@ -196,9 +196,9 @@ internal protected void FocusTextBox()
196196
_textBox.Focus(FocusState.Keyboard);
197197
}
198198

199-
public bool TryToggleIsSuggestionsPopupOpen(bool wantToOpen)
199+
internal protected bool TryToggleIsSuggestionsPopupOpen(bool wantToOpen)
200200
{
201-
if (wantToOpen && (!IsFocused || CurrentSelectedMode?.SuggestionItemsSource is null || (CurrentSelectedMode?.SuggestionItemsSource is IList collection && collection.Count is 0)) ||
201+
if (wantToOpen && (!IsFocused || CurrentSelectedMode?.ItemsSource is null || (CurrentSelectedMode?.ItemsSource is IList collection && collection.Count is 0)) ||
202202
_textBoxSuggestionsPopup is null)
203203
return false;
204204

src/Files.App.Controls/Omnibar/OmnibarMode.Properties.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,9 @@ public partial class OmnibarMode
2828
[GeneratedDependencyProperty]
2929
public partial FrameworkElement? IconOnInactive { get; set; }
3030

31-
[GeneratedDependencyProperty]
32-
public partial object? SuggestionItemsSource { get; set; }
33-
34-
[GeneratedDependencyProperty]
35-
public partial DataTemplate? SuggestionItemTemplate { get; set; }
36-
3731
[GeneratedDependencyProperty]
3832
/// <remark>
39-
/// Implement <see cref="IOmnibarTextMemberPathProvider"/> in <see cref="SuggestionItemsSource"/> to get the text member path from the suggestion item correctly.
33+
/// Implement <see cref="IOmnibarTextMemberPathProvider"/> in <see cref="ItemsSource"/> to get the text member path from the suggestion item correctly.
4034
/// </remark>
4135
public partial string? TextMemberPath { get; set; }
4236

src/Files.App.Controls/Omnibar/OmnibarMode.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
namespace Files.App.Controls
77
{
88
[DebuggerDisplay("{" + nameof(ToString) + "(),nq}")]
9-
public partial class OmnibarMode : Control
9+
public partial class OmnibarMode : ItemsControl
1010
{
1111
// Constants
1212

@@ -66,6 +66,14 @@ protected override void OnKeyUp(KeyRoutedEventArgs args)
6666
}
6767
}
6868

69+
protected override void OnItemsChanged(object e)
70+
{
71+
base.OnItemsChanged(e);
72+
73+
if (_ownerRef is not null && _ownerRef.TryGetTarget(out var owner))
74+
owner.TryToggleIsSuggestionsPopupOpen(true);
75+
}
76+
6977
private void OmnibarMode_Loaded(object sender, RoutedEventArgs e)
7078
{
7179
// Set this mode as the current mode if it is the default mode

src/Files.App/UserControls/NavigationToolbar.xaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,9 @@
333333
IconOnActive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Path}, IsFilled=True}"
334334
IconOnInactive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Path}, IconType=Outline}"
335335
IsDefault="True"
336+
ItemsSource="{x:Bind ViewModel.PathModeSuggestionItems, Mode=OneWay}"
336337
ModeName="{x:Bind Commands.EditPath.LabelWithHotKey, Mode=OneWay}"
337338
PlaceholderText="{helpers:ResourceString Name=OmnibarPathModeTextPlaceholder}"
338-
SuggestionItemsSource="{x:Bind ViewModel.PathModeSuggestionItems, Mode=OneWay}"
339339
Text="{x:Bind ViewModel.PathText, Mode=TwoWay}"
340340
TextMemberPath="Path">
341341
<controls:OmnibarMode.ContentOnInactive>
@@ -364,25 +364,25 @@
364364
</controls:BreadcrumbBar.ItemTemplate>
365365
</controls:BreadcrumbBar>
366366
</controls:OmnibarMode.ContentOnInactive>
367-
<controls:OmnibarMode.SuggestionItemTemplate>
367+
<controls:OmnibarMode.ItemTemplate>
368368
<DataTemplate x:DataType="datamodels:OmnibarPathModeSuggestionModel">
369369
<TextBlock Text="{x:Bind DisplayName, Mode=OneWay}" />
370370
</DataTemplate>
371-
</controls:OmnibarMode.SuggestionItemTemplate>
371+
</controls:OmnibarMode.ItemTemplate>
372372
</controls:OmnibarMode>
373373

374374
<controls:OmnibarMode
375375
x:Name="OmnibarCommandPaletteMode"
376376
IconOnActive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Commands}, IsFilled=True}"
377377
IconOnInactive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Commands}, IconType=Outline}"
378378
IsAutoFocusEnabled="True"
379+
ItemsSource="{x:Bind ViewModel.OmnibarCommandPaletteModeSuggestionItems, Mode=OneWay}"
379380
ModeName="{x:Bind Commands.OpenCommandPalette.LabelWithHotKey, Mode=OneWay}"
380381
PlaceholderText="{helpers:ResourceString Name=OmnibarCommandPaletteModeTextPlaceholder}"
381-
SuggestionItemsSource="{x:Bind ViewModel.OmnibarCommandPaletteModeSuggestionItems, Mode=OneWay}"
382382
Text="{x:Bind ViewModel.OmnibarCommandPaletteModeText, Mode=TwoWay}"
383383
TextMemberPath="Text"
384384
UpdateTextOnSelect="False">
385-
<controls:OmnibarMode.SuggestionItemTemplate>
385+
<controls:OmnibarMode.ItemTemplate>
386386
<DataTemplate x:DataType="dataitems:NavigationBarSuggestionItem">
387387
<Grid ColumnSpacing="12">
388388
<Grid.ColumnDefinitions>
@@ -421,7 +421,7 @@
421421
HotKeys="{x:Bind HotKeys}" />
422422
</Grid>
423423
</DataTemplate>
424-
</controls:OmnibarMode.SuggestionItemTemplate>
424+
</controls:OmnibarMode.ItemTemplate>
425425
</controls:OmnibarMode>
426426

427427
<controls:OmnibarMode

src/Files.App/ViewModels/UserControls/NavigationToolbarViewModel.cs

Lines changed: 19 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using CommunityToolkit.WinUI;
55
using Files.App.Controls;
66
using Files.Shared.Helpers;
7+
using Microsoft.Extensions.Logging;
78
using Microsoft.UI.Dispatching;
89
using Microsoft.UI.Xaml;
910
using Microsoft.UI.Xaml.Controls;
@@ -1042,93 +1043,53 @@ public async Task PopulateOmnibarSuggestionsForPathMode()
10421043
{
10431044
PathModeSuggestionItems.Clear();
10441045

1045-
var result = await SafetyExtensions.IgnoreExceptions((Func<Task<bool>>)(async () =>
1046+
try
10461047
{
10471048
List<OmnibarPathModeSuggestionModel>? newSuggestions = [];
1048-
var pathText = this.PathText;
1049+
var pathText = PathText;
10491050

10501051
// If the current input is special, populate navigation history instead.
1051-
if (string.IsNullOrWhiteSpace((string)pathText) ||
1052-
pathText is "Home" or "ReleaseNotes" or "Settings")
1052+
if (string.IsNullOrWhiteSpace(pathText) ||
1053+
pathText.Equals("Home", StringComparison.OrdinalIgnoreCase) ||
1054+
pathText.Equals("ReleaseNotes", StringComparison.OrdinalIgnoreCase) ||
1055+
pathText.Equals("Settings", StringComparison.OrdinalIgnoreCase))
10531056
{
10541057
// Load previously entered path
10551058
if (UserSettingsService.GeneralSettingsService.PathHistoryList is { } pathHistoryList)
10561059
{
1057-
newSuggestions.AddRange(pathHistoryList.Select(x => new OmnibarPathModeSuggestionModel(x, x)));
1060+
pathHistoryList.Select(x => new OmnibarPathModeSuggestionModel(x, x)).ForEach(PathModeSuggestionItems.Add);
10581061
}
10591062
}
10601063
else
10611064
{
1062-
var isFtp = FtpHelpers.IsFtpPath((string)pathText);
1063-
pathText = NormalizePathInput((string)pathText, isFtp);
1064-
var expandedPath = StorageFileExtensions.GetResolvedPath((string)pathText, isFtp);
1065+
var isFtp = FtpHelpers.IsFtpPath(pathText);
1066+
pathText = NormalizePathInput(pathText, isFtp);
1067+
var expandedPath = StorageFileExtensions.GetResolvedPath(pathText, isFtp);
10651068
var folderPath = PathNormalization.GetParentDir(expandedPath) ?? expandedPath;
10661069
StorageFolderWithPath folder = await ContentPageContext.ShellPage.ShellViewModel.GetFolderWithPathFromPathAsync(folderPath);
10671070
if (folder is null)
1068-
return false;
1071+
AddNoResultsItem();
10691072

10701073
var currPath = await folder.GetFoldersWithPathAsync(Path.GetFileName(expandedPath), MaxSuggestionsCount);
10711074
if (currPath.Count >= MaxSuggestionsCount)
10721075
{
1073-
newSuggestions.AddRange(currPath.Select(x => new OmnibarPathModeSuggestionModel(x.Path, x.Item.DisplayName)));
1076+
currPath.Select(x => new OmnibarPathModeSuggestionModel(x.Path, x.Item.DisplayName)).ForEach(PathModeSuggestionItems.Add);
10741077
}
10751078
else if (currPath.Any())
10761079
{
10771080
var subPath = await currPath.First().GetFoldersWithPathAsync((uint)(MaxSuggestionsCount - currPath.Count));
1078-
newSuggestions.AddRange(currPath.Select(x => new OmnibarPathModeSuggestionModel(x.Path, x.Item.DisplayName)));
1079-
newSuggestions.AddRange(subPath.Select(x => new OmnibarPathModeSuggestionModel(x.Path, PathNormalization.Combine(currPath.First().Item.DisplayName, x.Item.DisplayName))));
1081+
currPath.Select(x => new OmnibarPathModeSuggestionModel(x.Path, x.Item.DisplayName)).ForEach(PathModeSuggestionItems.Add);
1082+
currPath.Select(x => new OmnibarPathModeSuggestionModel(x.Path, PathNormalization.Combine(currPath.First().Item.DisplayName, x.Item.DisplayName))).ForEach(PathModeSuggestionItems.Add);
10801083
}
10811084
}
10821085

10831086
// If there are no suggestions, show "No suggestions"
1084-
if (newSuggestions.Count is 0)
1085-
{
1087+
if (PathModeSuggestionItems.Count is 0)
10861088
AddNoResultsItem();
1087-
}
1088-
1089-
// Check whether at least one item is in common between the old and the new suggestions
1090-
// since the suggestions popup becoming empty causes flickering
1091-
if (!PathModeSuggestionItems.IntersectBy(newSuggestions, x => x.DisplayName).Any())
1092-
{
1093-
// No items in common, update the list in-place
1094-
for (int index = 0; index < newSuggestions.Count; index++)
1095-
{
1096-
if (index < PathModeSuggestionItems.Count)
1097-
{
1098-
PathModeSuggestionItems[index] = newSuggestions[index];
1099-
}
1100-
else
1101-
{
1102-
PathModeSuggestionItems.Add(newSuggestions[index]);
1103-
}
1104-
}
1105-
1106-
while (PathModeSuggestionItems.Count > newSuggestions.Count)
1107-
PathModeSuggestionItems.RemoveAt(PathModeSuggestionItems.Count - 1);
1108-
}
1109-
else
1110-
{
1111-
// At least an element in common, show animation
1112-
foreach (var s in PathModeSuggestionItems.ExceptBy(newSuggestions, x => x.DisplayName).ToList())
1113-
PathModeSuggestionItems.Remove(s);
1114-
1115-
for (int index = 0; index < newSuggestions.Count; index++)
1116-
{
1117-
if (PathModeSuggestionItems.Count > index && PathModeSuggestionItems[index].DisplayName == newSuggestions[index].DisplayName)
1118-
{
1119-
PathModeSuggestionItems[index] = newSuggestions[index];
1120-
}
1121-
else
1122-
PathModeSuggestionItems.Insert(index, newSuggestions[index]);
1123-
}
1124-
}
1125-
1126-
return true;
1127-
}));
1128-
1129-
if (!result)
1089+
}
1090+
catch (Exception ex)
11301091
{
1131-
AddNoResultsItem();
1092+
App.Logger?.LogInformation(ex, ex.Message);
11321093
}
11331094

11341095
void AddNoResultsItem()

0 commit comments

Comments
 (0)