mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-09 04:37:30 +02:00
CmdPal: Add actionable hint to empty results in File Search extension (#41982)
## Summary of the Pull Request This PR improves the user experience when no indexed files match the query in the File Search extension. - Show a hint on the empty results page when no indexed files are found. - Provide fallback actions: - Search entire PC – opens new File Explorer window with the query searched in This PC. - Open Windows Search settings – navigates to Windows Search settings to review indexed locations. <img width="1719" height="1072" alt="image" src="https://github.com/user-attachments/assets/51bd7b4a-563f-4339-b179-8125c057b0af" /> <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Related to: #38509 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed
This commit is contained in:
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.CmdPal.Ext.Indexer.Properties;
|
using Microsoft.CmdPal.Ext.Indexer.Properties;
|
||||||
using Microsoft.CommandPalette.Extensions;
|
using Microsoft.CommandPalette.Extensions;
|
||||||
@@ -23,6 +25,9 @@ internal sealed partial class IndexerPage : DynamicListPage, IDisposable
|
|||||||
|
|
||||||
private bool _isEmptyQuery = true;
|
private bool _isEmptyQuery = true;
|
||||||
|
|
||||||
|
private CommandItem _noSearchEmptyContent;
|
||||||
|
private CommandItem _nothingFoundEmptyContent;
|
||||||
|
|
||||||
public IndexerPage()
|
public IndexerPage()
|
||||||
{
|
{
|
||||||
Id = "com.microsoft.indexer.fileSearch";
|
Id = "com.microsoft.indexer.fileSearch";
|
||||||
@@ -31,6 +36,7 @@ internal sealed partial class IndexerPage : DynamicListPage, IDisposable
|
|||||||
PlaceholderText = Resources.Indexer_PlaceholderText;
|
PlaceholderText = Resources.Indexer_PlaceholderText;
|
||||||
_searchEngine = new();
|
_searchEngine = new();
|
||||||
_queryCookie = 10;
|
_queryCookie = 10;
|
||||||
|
CreateEmptyContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IndexerPage(string query, SearchEngine searchEngine, uint queryCookie, IList<IListItem> firstPageData)
|
public IndexerPage(string query, SearchEngine searchEngine, uint queryCookie, IList<IListItem> firstPageData)
|
||||||
@@ -43,9 +49,42 @@ internal sealed partial class IndexerPage : DynamicListPage, IDisposable
|
|||||||
initialQuery = query;
|
initialQuery = query;
|
||||||
SearchText = query;
|
SearchText = query;
|
||||||
disposeSearchEngine = false;
|
disposeSearchEngine = false;
|
||||||
|
CreateEmptyContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ICommandItem EmptyContent => GetEmptyContent();
|
private void CreateEmptyContent()
|
||||||
|
{
|
||||||
|
_noSearchEmptyContent = new CommandItem(new NoOpCommand())
|
||||||
|
{
|
||||||
|
Icon = Icon,
|
||||||
|
Title = Resources.Indexer_Subtitle,
|
||||||
|
Subtitle = Resources.Indexer_NoSearchQueryMessageTip,
|
||||||
|
};
|
||||||
|
|
||||||
|
_nothingFoundEmptyContent = new CommandItem(new AnonymousCommand(StartManualSearch) { Name = Resources.Indexer_Command_SearchAllFiles! })
|
||||||
|
{
|
||||||
|
Icon = Icon,
|
||||||
|
Title = Resources.Indexer_NoResultsMessage,
|
||||||
|
Subtitle = Resources.Indexer_NoResultsMessageTip,
|
||||||
|
MoreCommands = [
|
||||||
|
new CommandContextItem(new OpenUrlCommand("ms-settings:search") { Name = Resources.Indexer_Command_OpenIndexerSettings! })
|
||||||
|
{
|
||||||
|
Title = Resources.Indexer_Command_SearchAllFiles!,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartManualSearch()
|
||||||
|
{
|
||||||
|
// {20D04FE0-3AEA-1069-A2D8-08002B30309D} is CLSID for "This PC"
|
||||||
|
const string template = "search-ms:query={0}&crumb=location:::{{20D04FE0-3AEA-1069-A2D8-08002B30309D}}";
|
||||||
|
var encodedSearchText = UrlEncoder.Default.Encode(SearchText);
|
||||||
|
var command = string.Format(CultureInfo.CurrentCulture, template, encodedSearchText);
|
||||||
|
ShellHelpers.OpenInShell(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ICommandItem EmptyContent => _isEmptyQuery ? _noSearchEmptyContent : _nothingFoundEmptyContent;
|
||||||
|
|
||||||
public override void UpdateSearchText(string oldSearch, string newSearch)
|
public override void UpdateSearchText(string oldSearch, string newSearch)
|
||||||
{
|
{
|
||||||
@@ -74,16 +113,6 @@ internal sealed partial class IndexerPage : DynamicListPage, IDisposable
|
|||||||
RaiseItemsChanged(_indexerListItems.Count);
|
RaiseItemsChanged(_indexerListItems.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CommandItem GetEmptyContent()
|
|
||||||
{
|
|
||||||
return new CommandItem(new NoOpCommand())
|
|
||||||
{
|
|
||||||
Icon = Icon,
|
|
||||||
Title = _isEmptyQuery ? Resources.Indexer_Subtitle : Resources.Indexer_NoResultsMessage,
|
|
||||||
Subtitle = Resources.Indexer_NoResultsMessageTip,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Query(string query)
|
private void Query(string query)
|
||||||
{
|
{
|
||||||
++_queryCookie;
|
++_queryCookie;
|
||||||
|
|||||||
@@ -96,6 +96,15 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Open Windows Search settings.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Indexer_Command_OpenIndexerSettings {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Indexer_Command_OpenIndexerSettings", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Open path in console.
|
/// Looks up a localized string similar to Open path in console.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -123,6 +132,15 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Search all files.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Indexer_Command_SearchAllFiles {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Indexer_Command_SearchAllFiles", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Show in folder.
|
/// Looks up a localized string similar to Show in folder.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -187,7 +205,8 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Tip: Improve your search result using filters like in Windows Explorer. (For example: type:directory).
|
/// Looks up a localized string similar to Nothing was found in the indexed locations.
|
||||||
|
///You can try searching all files on this PC or adjust your indexing settings..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string Indexer_NoResultsMessageTip {
|
internal static string Indexer_NoResultsMessageTip {
|
||||||
get {
|
get {
|
||||||
@@ -195,6 +214,15 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Tip: Refine your search using filters, just like in File Explorer (e.g., type:directory)..
|
||||||
|
/// </summary>
|
||||||
|
internal static string Indexer_NoSearchQueryMessageTip {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Indexer_NoSearchQueryMessageTip", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Search for files and folders....
|
/// Looks up a localized string similar to Search for files and folders....
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -184,6 +184,16 @@
|
|||||||
<value>No items found</value>
|
<value>No items found</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Indexer_NoResultsMessageTip" xml:space="preserve">
|
<data name="Indexer_NoResultsMessageTip" xml:space="preserve">
|
||||||
|
<value>Nothing was found in the indexed locations.
|
||||||
|
You can try searching all files on this PC or adjust your indexing settings.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Indexer_NoSearchQueryMessageTip" xml:space="preserve">
|
||||||
<value>Tip: Refine your search using filters, just like in File Explorer (e.g., type:directory).</value>
|
<value>Tip: Refine your search using filters, just like in File Explorer (e.g., type:directory).</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Indexer_Command_OpenIndexerSettings" xml:space="preserve">
|
||||||
|
<value>Open Windows Search settings</value>
|
||||||
|
</data>
|
||||||
|
<data name="Indexer_Command_SearchAllFiles" xml:space="preserve">
|
||||||
|
<value>Search all files</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
Reference in New Issue
Block a user