Skip to content
Merged
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
50 changes: 50 additions & 0 deletions src/Files.App/Actions/Show/ToggleFilterHeaderAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) Files Community
// Licensed under the MIT License.

using CommunityToolkit.WinUI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;

namespace Files.App.Actions
{
internal sealed partial class ToggleFilterHeaderAction : ObservableObject, IToggleAction
{
private readonly IGeneralSettingsService generalSettingsService = Ioc.Default.GetRequiredService<IGeneralSettingsService>();

public string Label
=> Strings.ToggleFilterHeader.GetLocalizedResource();

public string Description
=> Strings.ToggleFilterHeaderDescription.GetLocalizedResource();

public RichGlyph Glyph
=> new(themedIconStyle: "App.ThemedIcons.Filter");

public bool IsOn
=> generalSettingsService.ShowFilterHeader;

public ToggleFilterHeaderAction()
{
generalSettingsService.PropertyChanged += GeneralSettingsService_PropertyChanged;
}

public Task ExecuteAsync(object? parameter = null)
{
generalSettingsService.ShowFilterHeader = !IsOn;

if (IsOn)
{
var filterTextBox = (MainWindow.Instance.Content as Frame)?.FindDescendant("FilterTextBox") as AutoSuggestBox;
filterTextBox?.Focus(FocusState.Programmatic);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I probably recommend to create a method

ContentPageContext.ShellPage?.TryFocusItemFilterTextBox();

}

return Task.CompletedTask;
}

private void GeneralSettingsService_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName is nameof(GeneralSettingsService.ShowFilterHeader))
OnPropertyChanged(nameof(IsOn));
}
}
}
1 change: 1 addition & 0 deletions src/Files.App/Data/Commands/Manager/CommandCodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public enum CommandCodes
ToggleInfoPane,
ToggleToolbar,
ToggleShelfPane,
ToggleFilterHeader,

// File System
CopyItem,
Expand Down
2 changes: 2 additions & 0 deletions src/Files.App/Data/Commands/Manager/CommandManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public IRichCommand this[HotKey hotKey]
public IRichCommand ToggleInfoPane => commands[CommandCodes.ToggleInfoPane];
public IRichCommand ToggleToolbar => commands[CommandCodes.ToggleToolbar];
public IRichCommand ToggleShelfPane => commands[CommandCodes.ToggleShelfPane];
public IRichCommand ToggleFilterHeader => commands[CommandCodes.ToggleFilterHeader];
public IRichCommand SelectAll => commands[CommandCodes.SelectAll];
public IRichCommand InvertSelection => commands[CommandCodes.InvertSelection];
public IRichCommand ClearSelection => commands[CommandCodes.ClearSelection];
Expand Down Expand Up @@ -264,6 +265,7 @@ public IEnumerator<IRichCommand> GetEnumerator() =>
[CommandCodes.ToggleInfoPane] = new ToggleInfoPaneAction(),
[CommandCodes.ToggleToolbar] = new ToggleToolbarAction(),
[CommandCodes.ToggleShelfPane] = new ToggleShelfPaneAction(),
[CommandCodes.ToggleFilterHeader] = new ToggleFilterHeaderAction(),
[CommandCodes.SelectAll] = new SelectAllAction(),
[CommandCodes.InvertSelection] = new InvertSelectionAction(),
[CommandCodes.ClearSelection] = new ClearSelectionAction(),
Expand Down
1 change: 1 addition & 0 deletions src/Files.App/Data/Commands/Manager/ICommandManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public interface ICommandManager : IEnumerable<IRichCommand>
IRichCommand ToggleInfoPane { get; }
IRichCommand ToggleToolbar { get; }
IRichCommand ToggleShelfPane { get; }
IRichCommand ToggleFilterHeader { get; }

IRichCommand CopyItem { get; }
IRichCommand CopyItemPath { get; }
Expand Down
10 changes: 10 additions & 0 deletions src/Files.App/Data/Contracts/IGeneralSettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ public interface IGeneralSettingsService : IBaseSettingsService, INotifyProperty
/// </summary>
List<string> PathHistoryList { get; set; }

/// <summary>
/// A list containing previous search queries.
/// </summary>
List<string> PreviousSearchQueriesList { get; set; }

/// <summary>
/// Gets or sets a value indicating which date and time format to use.
/// </summary>
Expand Down Expand Up @@ -295,6 +300,11 @@ public interface IGeneralSettingsService : IBaseSettingsService, INotifyProperty
/// </summary>
bool ShowShelfPane { get; set; }

/// <summary>
/// Gets or sets a value whether the filter header should be displayed.
/// </summary>
bool ShowFilterHeader { get; set; }

/// <summary>
/// Gets or sets a value indicating whether or not to enable the Omnibar.
/// </summary>
Expand Down
12 changes: 12 additions & 0 deletions src/Files.App/Services/Settings/GeneralSettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ public List<string> PathHistoryList
set => Set(value);
}

public List<string> PreviousSearchQueriesList
{
get => Get<List<string>>(null);
set => Set(value);
}

public DateTimeFormats DateTimeFormat
{
get => Get(DateTimeFormats.Application);
Expand Down Expand Up @@ -363,6 +369,12 @@ public bool ShowShelfPane
set => Set(value);
}

public bool ShowFilterHeader
{
get => Get(false);
set => Set(value);
}

public bool EnableOmnibar
{
get => Get(false);
Expand Down
1 change: 1 addition & 0 deletions src/Files.App/Services/Settings/UserSettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public override object ExportSettings()
export.Remove(nameof(GeneralSettingsService.LastSessionTabList));
export.Remove(nameof(GeneralSettingsService.LastCrashedTabList));
export.Remove(nameof(GeneralSettingsService.PathHistoryList));
export.Remove(nameof(GeneralSettingsService.PreviousSearchQueriesList));

return JsonSettingsSerializer.SerializeToJson(export);
}
Expand Down
12 changes: 12 additions & 0 deletions src/Files.App/Strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,12 @@
<data name="ToggleToolbarDescription" xml:space="preserve">
<value>Toggle visibility of the toolbar</value>
</data>
<data name="ToggleFilterHeader" xml:space="preserve">
<value>Toggle filter header</value>
</data>
<data name="ToggleFilterHeaderDescription" xml:space="preserve">
<value>Toggle visibility of the filter header</value>
</data>
<data name="DetailsPanePreviewNotAvaliableText" xml:space="preserve">
<value>No preview available</value>
</data>
Expand Down Expand Up @@ -4261,4 +4267,10 @@
<data name="SeeMore" xml:space="preserve">
<value>See more</value>
</data>
<data name="FilteringFor" xml:space="preserve">
<value>Filtering for</value>
</data>
<data name="Filename" xml:space="preserve">
<value>Filename</value>
</data>
</root>
4 changes: 4 additions & 0 deletions src/Files.App/UserControls/NavigationToolbar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
<converters:NullToVisibilityCollapsedConverter x:Key="NullToVisibilityCollapsedConverter" />
<converters1:BoolNegationConverter x:Key="BoolNegationConverter" />
<converters:VisibilityInvertConverter x:Key="VisibilityInvertConverter" />
<converters1:BoolToObjectConverter
x:Key="SearchSuggestionGlyphConverter"
FalseValue="&#xE7C3;"
TrueValue="&#xE81C;" />

<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ms-appx:///UserControls/KeyboardShortcut/KeyboardShortcut.xaml" />
Expand Down
25 changes: 23 additions & 2 deletions src/Files.App/UserControls/NavigationToolbar.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,22 @@ await DialogDisplayHelper.ShowDialogAsync(Strings.InvalidCommand.GetLocalizedRes
// Search mode
else if (mode == OmnibarSearchMode)
{
ContentPageContext.ShellPage?.SubmitSearch(args.Text);
var shellPage = ContentPageContext.ShellPage;

if (args.Item is SuggestionModel item && !string.IsNullOrWhiteSpace(item.ItemPath) && shellPage is not null)
await NavigationHelpers.OpenPath(item.ItemPath, shellPage);
else
{
var searchQuery = args.Item is SuggestionModel x && !string.IsNullOrWhiteSpace(x.Name)
? x.Name
: args.Text;

shellPage?.SubmitSearch(searchQuery); // use the resolved shellPage for consistency
ViewModel.SaveSearchQueryToList(searchQuery);
}

(MainPageViewModel.SelectedTabItem?.TabItemContent as Control)?.Focus(FocusState.Programmatic);
return;
}
}

Expand All @@ -338,6 +353,7 @@ await DispatcherQueue.EnqueueOrInvokeAsync(() =>
}
else if (Omnibar.CurrentSelectedMode == OmnibarSearchMode)
{
await ViewModel.PopulateOmnibarSuggestionsForSearchMode();
}
}

Expand Down Expand Up @@ -456,7 +472,12 @@ await DispatcherQueue.EnqueueOrInvokeAsync(() =>
}
else if (e.NewMode == OmnibarSearchMode)
{
if (!ViewModel.InstanceViewModel.IsPageTypeSearchResults)
ViewModel.OmnibarSearchModeText = string.Empty;
else
ViewModel.OmnibarSearchModeText = ViewModel.InstanceViewModel.CurrentSearchQuery;

await ViewModel.PopulateOmnibarSuggestionsForSearchMode();
}
}

Expand Down Expand Up @@ -486,7 +507,7 @@ await DispatcherQueue.EnqueueOrInvokeAsync(() =>
}
else if (Omnibar.CurrentSelectedMode == OmnibarSearchMode)
{

await ViewModel.PopulateOmnibarSuggestionsForSearchMode();
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions src/Files.App/UserControls/Toolbar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,21 @@
Grid.Column="1"
DefaultLabelPosition="Right">

<!-- Toggle filter header -->
<AppBarToggleButton
x:Name="FilterHeader"
Width="Auto"
MinWidth="40"
AccessKey="F"
AccessKeyInvoked="AppBarButton_AccessKeyInvoked"
AutomationProperties.Name="{x:Bind Commands.ToggleFilterHeader.AutomationName}"
IsChecked="{x:Bind Commands.ToggleFilterHeader.IsOn, Mode=TwoWay}"
Label="{x:Bind Commands.ToggleFilterHeader.Label}"
LabelPosition="Collapsed"
ToolTipService.ToolTip="{x:Bind Commands.ToggleFilterHeader.LabelWithHotKey, Mode=OneWay}">
<controls:ThemedIcon Style="{StaticResource App.ThemedIcons.Filter}" />
</AppBarToggleButton>

<!-- Selection Commands -->
<AppBarButton
x:Name="SelectionOptions"
Expand Down
42 changes: 36 additions & 6 deletions src/Files.App/ViewModels/ShellViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
using Windows.Storage;
using Windows.Storage.FileProperties;
using Windows.Storage.Search;
using Windows.Win32.System.SystemServices;
using static Files.App.Helpers.Win32PInvoke;
using ByteSize = ByteSizeLib.ByteSize;
using DispatcherQueue = Microsoft.UI.Dispatching.DispatcherQueue;
using FileAttributes = System.IO.FileAttributes;
using ByteSize = ByteSizeLib.ByteSize;
using Windows.Win32.System.SystemServices;

namespace Files.App.ViewModels
{
Expand Down Expand Up @@ -114,6 +114,19 @@ public HorizontalAlignment FolderBackgroundImageHorizontalAlignment
private set => SetProperty(ref _FolderBackgroundImageHorizontalAlignment, value);
}

private ImageSource? _FolderThumbnailImageSource;
public ImageSource? FolderThumbnailImageSource
{
get => _FolderThumbnailImageSource;
private set => SetProperty(ref _FolderThumbnailImageSource, value);
}

public bool ShowFilterHeader =>
UserSettingsService.GeneralSettingsService.ShowFilterHeader &&
WorkingDirectory != "Home" &&
WorkingDirectory != "ReleaseNotes" &&
WorkingDirectory != "Settings";

private GitProperties _EnabledGitProperties;
public GitProperties EnabledGitProperties
{
Expand Down Expand Up @@ -213,7 +226,10 @@ public async Task SetWorkingDirectoryAsync(string? value)
GitDirectory = GitHelpers.GetGitRepositoryPath(WorkingDirectory, pathRoot);
IsValidGitDirectory = !string.IsNullOrEmpty((await GitHelpers.GetRepositoryHead(GitDirectory))?.Name);

_ = UpdateFolderThumbnailImageSource();

OnPropertyChanged(nameof(WorkingDirectory));
OnPropertyChanged(nameof(ShowFilterHeader));
}

public async Task<FilesystemResult<BaseStorageFolder>> GetFolderFromPathAsync(string value, CancellationToken cancellationToken = default)
Expand Down Expand Up @@ -275,6 +291,11 @@ public EmptyTextType EmptyTextType
set => SetProperty(ref emptyTextType, value);
}

public async Task UpdateFolderThumbnailImageSource()
{
FolderThumbnailImageSource = await NavigationHelpers.GetIconForPathAsync(WorkingDirectory);
}

public async Task UpdateSortOptionStatusAsync()
{
OnPropertyChanged(nameof(IsSortedByName));
Expand Down Expand Up @@ -676,6 +697,9 @@ await dispatcherQueue.EnqueueOrInvokeAsync(() =>
await OrderFilesAndFoldersAsync();
await ApplyFilesAndFoldersChangesAsync();
break;
case nameof(UserSettingsService.GeneralSettingsService.ShowFilterHeader):
OnPropertyChanged(nameof(ShowFilterHeader));
break;
}
}

Expand Down Expand Up @@ -715,7 +739,13 @@ public void UpdateEmptyTextType()
EmptyTextType = FilesAndFolders.Count == 0 ? (IsSearchResults ? EmptyTextType.NoSearchResultsFound : EmptyTextType.FolderEmpty) : EmptyTextType.None;
}

public string? FilesAndFoldersFilter { get; set; }
private string? _filesAndFoldersFilter;
public string? FilesAndFoldersFilter
{
get => _filesAndFoldersFilter;
set => SetProperty(ref _filesAndFoldersFilter, value);
}


// Apply changes immediately after manipulating on filesAndFolders completed
public async Task ApplyFilesAndFoldersChangesAsync()
Expand Down Expand Up @@ -1339,7 +1369,7 @@ public Task UpdateItemsTags(Dictionary<string, string[]> newTags)
return dispatcherQueue.EnqueueOrInvokeAsync(() =>
{
int count = newTags.Count;
foreach(var item in FilesAndFolders)
foreach (var item in FilesAndFolders)
{
if (newTags.TryGetValue(item.ItemPath, out var tags))
{
Expand Down Expand Up @@ -1635,15 +1665,15 @@ private async Task<int> EnumerateItemsFromStandardFolderAsync(string path, Cance
!isShellFolder &&
!isWslDistro;
bool isNetdisk = false;

try
{
// Special handling for network drives
if (!isNetwork)
isNetdisk = (new DriveInfo(path).DriveType == System.IO.DriveType.Network);
}
catch { }

bool isFtp = FtpHelpers.IsFtpPath(path);
bool enumFromStorageFolder = isBoxFolder || isFtp;

Expand Down
Loading
Loading