From 155eecd86fa5fc35220cf2fc7b7f4e8fcca4fc63 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 16:17:14 +0800
Subject: [PATCH 01/19] Expose part functions to helper
---
.../Views/PreviewPanel.xaml.cs | 56 ++++++++++++-------
1 file changed, 36 insertions(+), 20 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index e1a957199a5..d8715530ca7 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -60,33 +60,17 @@ public PreviewPanel(Settings settings, string filePath)
if (Settings.ShowFileSizeInPreviewPanel)
{
- var fileSize = new FileInfo(filePath).Length;
- FileSize = ResultManager.ToReadableSize(fileSize, 2);
+ FileSize = GetFileSize(filePath);
}
if (Settings.ShowCreatedDateInPreviewPanel)
{
- DateTime createdDate = File.GetCreationTime(filePath);
- string formattedDate = createdDate.ToString(
- $"{Settings.PreviewPanelDateFormat} {Settings.PreviewPanelTimeFormat}",
- CultureInfo.CurrentCulture
- );
-
- string result = formattedDate;
- if (Settings.ShowFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
- CreatedAt = result;
+ CreatedAt = GetCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
}
if (Settings.ShowModifiedDateInPreviewPanel)
{
- DateTime lastModifiedDate = File.GetLastWriteTime(filePath);
- string formattedDate = lastModifiedDate.ToString(
- $"{Settings.PreviewPanelDateFormat} {Settings.PreviewPanelTimeFormat}",
- CultureInfo.CurrentCulture
- );
- string result = formattedDate;
- if (Settings.ShowFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
- LastModifiedAt = result;
+ LastModifiedAt = GetLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
}
_ = LoadImageAsync();
@@ -96,7 +80,39 @@ private async Task LoadImageAsync()
{
PreviewImage = await Main.Context.API.LoadImageAsync(FilePath, true).ConfigureAwait(false);
}
-
+
+ public static string GetFileSize(string filePath)
+ {
+ var fileInfo = new FileInfo(filePath);
+ return ResultManager.ToReadableSize(fileInfo.Length, 2);
+ }
+
+ public static string GetCreatedAt(string filePath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
+ {
+ var createdDate = File.GetCreationTime(filePath);
+ var formattedDate = createdDate.ToString(
+ $"{previewPanelDateFormat} {previewPanelTimeFormat}",
+ CultureInfo.CurrentCulture
+ );
+
+ var result = formattedDate;
+ if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
+ return result;
+ }
+
+ public static string GetLastModifiedAt(string filePath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
+ {
+ var lastModifiedDate = File.GetLastWriteTime(filePath);
+ var formattedDate = lastModifiedDate.ToString(
+ $"{previewPanelDateFormat} {previewPanelTimeFormat}",
+ CultureInfo.CurrentCulture
+ );
+
+ var result = formattedDate;
+ if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
+ return result;
+ }
+
private static string GetFileAge(DateTime fileDateTime)
{
var now = DateTime.Now;
From 16551396b985337901cf4ced1e20545fb2812678 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 17:01:15 +0800
Subject: [PATCH 02/19] Add ui for new setting
---
.../Languages/en.xaml | 3 ++
.../Flow.Launcher.Plugin.Explorer/Settings.cs | 2 +
.../Views/ExplorerSettings.xaml | 46 +++++++++++--------
3 files changed, 33 insertions(+), 18 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index eefd6f4eb53..1cb050e64df 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
@@ -43,6 +43,7 @@
Shell Path
Index Search Excluded Paths
Use search result's location as the working directory of the executable
+ Display more information like size and age in tooltips
Hit Enter to open folder in Default File Manager
Use Index Search For Path Search
Indexing Options
@@ -79,6 +80,8 @@
Ctrl + Enter to open the directory
Ctrl + Enter to open the containing folder
+ {0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
+ Unknown
Copy path
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
index 4f83fc72e5b..77540f3a87b 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
@@ -37,6 +37,8 @@ public class Settings
public bool DefaultOpenFolderInFileManager { get; set; } = false;
+ public bool DisplayMoreInformationInToolTip { get; set; } = false;
+
public string SearchActionKeyword { get; set; } = Query.GlobalPluginWildcardSign;
public bool SearchActionKeywordEnabled { get; set; } = true;
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 4302e721a51..50151d0b018 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -198,6 +198,7 @@
+
@@ -222,16 +223,25 @@
Content="{DynamicResource plugin_explorer_default_open_in_file_manager}"
IsChecked="{Binding Settings.DefaultOpenFolderInFileManager}" />
-
+
+
@@ -250,7 +260,7 @@
@@ -277,7 +287,7 @@
@@ -304,14 +314,14 @@
-
+
Date: Wed, 4 Jun 2025 17:01:46 +0800
Subject: [PATCH 03/19] Show more info in file & folder tooltip
---
.../Search/ResultManager.cs | 27 ++++++++--
.../Views/PreviewPanel.xaml.cs | 52 +++++++++++++++++--
2 files changed, 72 insertions(+), 7 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
index 5c4accdc05f..426d519187e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -163,7 +163,7 @@ internal static Result CreateFolderResult(string title, string subtitle, string
},
Score = score,
TitleToolTip = Main.Context.API.GetTranslation("plugin_explorer_plugin_ToolTipOpenDirectory"),
- SubTitleToolTip = path,
+ SubTitleToolTip = Settings.DisplayMoreInformationInToolTip ? GetMoreInfoToolTip(path, ResultType.Folder) : path,
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path, WindowsIndexed = windowsIndexed }
};
}
@@ -269,7 +269,6 @@ internal static Result CreateFileResult(string filePath, Query query, int score
bool isMedia = IsMedia(Path.GetExtension(filePath));
var title = Path.GetFileName(filePath);
-
/* Preview Detail */
var result = new Result
@@ -318,7 +317,7 @@ internal static Result CreateFileResult(string filePath, Query query, int score
return true;
},
TitleToolTip = Main.Context.API.GetTranslation("plugin_explorer_plugin_ToolTipOpenContainingFolder"),
- SubTitleToolTip = filePath,
+ SubTitleToolTip = Settings.DisplayMoreInformationInToolTip ? GetMoreInfoToolTip(filePath, ResultType.File) : filePath,
ContextData = new SearchResult { Type = ResultType.File, FullPath = filePath, WindowsIndexed = windowsIndexed }
};
return result;
@@ -349,6 +348,28 @@ private static void IncrementEverythingRunCounterIfNeeded(string fileOrFolder)
_ = Task.Run(() => EverythingApi.IncrementRunCounterAsync(fileOrFolder));
}
+ private static string GetMoreInfoToolTip(string filePath, ResultType type)
+ {
+ switch (type)
+ {
+ case ResultType.Folder:
+ var folderSize = PreviewPanel.GetFolderSize(filePath);
+ if (string.IsNullOrEmpty(folderSize)) folderSize = Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ var folderCreatedAt = PreviewPanel.GetFolderCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ var folderModifiedAt = PreviewPanel.GetFolderLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
+ filePath, folderSize, folderCreatedAt, folderModifiedAt, Environment.NewLine);
+ case ResultType.File:
+ var fileSize = PreviewPanel.GetFileSize(filePath);
+ var fileCreatedAt = PreviewPanel.GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ var fileModifiedAt = PreviewPanel.GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
+ filePath, fileSize, fileCreatedAt, fileModifiedAt, Environment.NewLine);
+ default:
+ return filePath;
+ }
+ }
+
private static readonly string[] MediaExtensions = { ".jpg", ".png", ".avi", ".mkv", ".bmp", ".gif", ".wmv", ".mp3", ".flac", ".mp4" };
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index d8715530ca7..cd462be696e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -65,12 +65,12 @@ public PreviewPanel(Settings settings, string filePath)
if (Settings.ShowCreatedDateInPreviewPanel)
{
- CreatedAt = GetCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ CreatedAt = GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
}
if (Settings.ShowModifiedDateInPreviewPanel)
{
- LastModifiedAt = GetLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ LastModifiedAt = GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
}
_ = LoadImageAsync();
@@ -87,7 +87,7 @@ public static string GetFileSize(string filePath)
return ResultManager.ToReadableSize(fileInfo.Length, 2);
}
- public static string GetCreatedAt(string filePath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
+ public static string GetFileCreatedAt(string filePath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
{
var createdDate = File.GetCreationTime(filePath);
var formattedDate = createdDate.ToString(
@@ -100,7 +100,7 @@ public static string GetCreatedAt(string filePath, string previewPanelDateFormat
return result;
}
- public static string GetLastModifiedAt(string filePath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
+ public static string GetFileLastModifiedAt(string filePath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
{
var lastModifiedDate = File.GetLastWriteTime(filePath);
var formattedDate = lastModifiedDate.ToString(
@@ -113,6 +113,50 @@ public static string GetLastModifiedAt(string filePath, string previewPanelDateF
return result;
}
+ public static string GetFolderSize(string folderPath)
+ {
+ var directoryInfo = new DirectoryInfo(folderPath);
+ long size = 0;
+ try
+ {
+ foreach (var file in directoryInfo.GetFiles("*", SearchOption.AllDirectories))
+ {
+ size += file.Length;
+ }
+ }
+ catch (Exception)
+ {
+ return string.Empty;
+ }
+ return ResultManager.ToReadableSize(size, 2);
+ }
+
+ public static string GetFolderCreatedAt(string folderPath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
+ {
+ var createdDate = Directory.GetCreationTime(folderPath);
+ var formattedDate = createdDate.ToString(
+ $"{previewPanelDateFormat} {previewPanelTimeFormat}",
+ CultureInfo.CurrentCulture
+ );
+
+ var result = formattedDate;
+ if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
+ return result;
+ }
+
+ public static string GetFolderLastModifiedAt(string folderPath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
+ {
+ var lastModifiedDate = Directory.GetLastWriteTime(folderPath);
+ var formattedDate = lastModifiedDate.ToString(
+ $"{previewPanelDateFormat} {previewPanelTimeFormat}",
+ CultureInfo.CurrentCulture
+ );
+
+ var result = formattedDate;
+ if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
+ return result;
+ }
+
private static string GetFileAge(DateTime fileDateTime)
{
var now = DateTime.Now;
From 85c038719e7aff30c03d3ac857a03f7b9a104ab9 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 17:12:53 +0800
Subject: [PATCH 04/19] Support custom preview panel for folder results
---
.../Search/ResultManager.cs | 8 ++------
.../Views/PreviewPanel.xaml.cs | 14 +++++++++-----
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
index 426d519187e..27206f9eaf7 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -99,10 +99,7 @@ internal static Result CreateFolderResult(string title, string subtitle, string
AutoCompleteText = GetAutoCompleteText(title, query, path, ResultType.Folder),
TitleHighlightData = Context.API.FuzzySearch(query.Search, title).MatchData,
CopyText = path,
- Preview = new Result.PreviewInfo
- {
- FilePath = path,
- },
+ PreviewPanel = new Lazy(() => new PreviewPanel(Settings, path, ResultType.Folder)),
Action = c =>
{
if (c.SpecialKeyState.ToModifierKeys() == ModifierKeys.Alt)
@@ -286,7 +283,7 @@ internal static Result CreateFileResult(string filePath, Query query, int score
TitleHighlightData = Context.API.FuzzySearch(query.Search, title).MatchData,
Score = score,
CopyText = filePath,
- PreviewPanel = new Lazy(() => new PreviewPanel(Settings, filePath)),
+ PreviewPanel = new Lazy(() => new PreviewPanel(Settings, filePath, ResultType.File)),
Action = c =>
{
if (c.SpecialKeyState.ToModifierKeys() == ModifierKeys.Alt)
@@ -354,7 +351,6 @@ private static string GetMoreInfoToolTip(string filePath, ResultType type)
{
case ResultType.Folder:
var folderSize = PreviewPanel.GetFolderSize(filePath);
- if (string.IsNullOrEmpty(folderSize)) folderSize = Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
var folderCreatedAt = PreviewPanel.GetFolderCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
var folderModifiedAt = PreviewPanel.GetFolderLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index cd462be696e..13339fa45e1 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -50,7 +50,7 @@ private set
? Visibility.Visible
: Visibility.Collapsed;
- public PreviewPanel(Settings settings, string filePath)
+ public PreviewPanel(Settings settings, string filePath, ResultType type)
{
InitializeComponent();
@@ -60,17 +60,21 @@ public PreviewPanel(Settings settings, string filePath)
if (Settings.ShowFileSizeInPreviewPanel)
{
- FileSize = GetFileSize(filePath);
+ FileSize = type == ResultType.File ? GetFileSize(filePath) : GetFolderSize(filePath);
}
if (Settings.ShowCreatedDateInPreviewPanel)
{
- CreatedAt = GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ CreatedAt = type == ResultType.File ?
+ GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel) :
+ GetFolderCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
}
if (Settings.ShowModifiedDateInPreviewPanel)
{
- LastModifiedAt = GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ LastModifiedAt = type == ResultType.File ?
+ GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel) :
+ GetFolderLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
}
_ = LoadImageAsync();
@@ -126,7 +130,7 @@ public static string GetFolderSize(string folderPath)
}
catch (Exception)
{
- return string.Empty;
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
}
return ResultManager.ToReadableSize(size, 2);
}
From ce0729923cc1c1465e9aa438e06b7a7a1f47aa47 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 17:26:33 +0800
Subject: [PATCH 05/19] Add try-catch for tooltip getter
---
.../Search/ResultManager.cs | 38 ++++++++++++++-----
1 file changed, 28 insertions(+), 10 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
index 27206f9eaf7..4e9a376ab55 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -14,6 +14,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
public static class ResultManager
{
+ private static readonly string ClassName = nameof(ResultManager);
+
private static readonly string[] SizeUnits = { "B", "KB", "MB", "GB", "TB" };
private static PluginInitContext Context;
private static Settings Settings { get; set; }
@@ -350,17 +352,33 @@ private static string GetMoreInfoToolTip(string filePath, ResultType type)
switch (type)
{
case ResultType.Folder:
- var folderSize = PreviewPanel.GetFolderSize(filePath);
- var folderCreatedAt = PreviewPanel.GetFolderCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
- var folderModifiedAt = PreviewPanel.GetFolderLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
- return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
- filePath, folderSize, folderCreatedAt, folderModifiedAt, Environment.NewLine);
+ try
+ {
+ var folderSize = PreviewPanel.GetFolderSize(filePath);
+ var folderCreatedAt = PreviewPanel.GetFolderCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ var folderModifiedAt = PreviewPanel.GetFolderLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
+ filePath, folderSize, folderCreatedAt, folderModifiedAt, Environment.NewLine);
+ }
+ catch (Exception e)
+ {
+ Context.API.LogException(ClassName, $"Failed to load tooltip for {filePath}", e);
+ return filePath;
+ }
case ResultType.File:
- var fileSize = PreviewPanel.GetFileSize(filePath);
- var fileCreatedAt = PreviewPanel.GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
- var fileModifiedAt = PreviewPanel.GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
- return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
- filePath, fileSize, fileCreatedAt, fileModifiedAt, Environment.NewLine);
+ try
+ {
+ var fileSize = PreviewPanel.GetFileSize(filePath);
+ var fileCreatedAt = PreviewPanel.GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ var fileModifiedAt = PreviewPanel.GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
+ filePath, fileSize, fileCreatedAt, fileModifiedAt, Environment.NewLine);
+ }
+ catch (Exception e)
+ {
+ Context.API.LogException(ClassName, $"Failed to load tooltip for {filePath}", e);
+ return filePath;
+ }
default:
return filePath;
}
From b1557dd4affb3d37949a515ea6e6c1585a13e501 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 17:32:30 +0800
Subject: [PATCH 06/19] Add try-catch for preview panel operation
---
.../Views/PreviewPanel.xaml.cs | 127 ++++++++++++------
1 file changed, 85 insertions(+), 42 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index 13339fa45e1..f4d7f843677 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -16,6 +16,8 @@ namespace Flow.Launcher.Plugin.Explorer.Views;
public partial class PreviewPanel : UserControl, INotifyPropertyChanged
{
+ private static readonly string ClassName = nameof(PreviewPanel);
+
private string FilePath { get; }
public string FileSize { get; } = "";
public string CreatedAt { get; } = "";
@@ -87,78 +89,119 @@ private async Task LoadImageAsync()
public static string GetFileSize(string filePath)
{
- var fileInfo = new FileInfo(filePath);
- return ResultManager.ToReadableSize(fileInfo.Length, 2);
+ try
+ {
+ var fileInfo = new FileInfo(filePath);
+ return ResultManager.ToReadableSize(fileInfo.Length, 2);
+ }
+ catch (Exception e)
+ {
+ Main.Context.API.LogException(ClassName, $"Failed to get file size for {filePath}", e);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
}
public static string GetFileCreatedAt(string filePath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
{
- var createdDate = File.GetCreationTime(filePath);
- var formattedDate = createdDate.ToString(
- $"{previewPanelDateFormat} {previewPanelTimeFormat}",
- CultureInfo.CurrentCulture
- );
-
- var result = formattedDate;
- if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
- return result;
+ try
+ {
+ var createdDate = File.GetCreationTime(filePath);
+ var formattedDate = createdDate.ToString(
+ $"{previewPanelDateFormat} {previewPanelTimeFormat}",
+ CultureInfo.CurrentCulture
+ );
+
+ var result = formattedDate;
+ if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
+ return result;
+ }
+ catch (Exception e)
+ {
+ Main.Context.API.LogException(ClassName, $"Failed to get file created date for {filePath}", e);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
}
public static string GetFileLastModifiedAt(string filePath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
{
- var lastModifiedDate = File.GetLastWriteTime(filePath);
- var formattedDate = lastModifiedDate.ToString(
- $"{previewPanelDateFormat} {previewPanelTimeFormat}",
- CultureInfo.CurrentCulture
- );
-
- var result = formattedDate;
- if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
- return result;
+ try
+ {
+ var lastModifiedDate = File.GetLastWriteTime(filePath);
+ var formattedDate = lastModifiedDate.ToString(
+ $"{previewPanelDateFormat} {previewPanelTimeFormat}",
+ CultureInfo.CurrentCulture
+ );
+
+ var result = formattedDate;
+ if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
+ return result;
+ }
+ catch (Exception e)
+ {
+ Main.Context.API.LogException(ClassName, $"Failed to get file modified date for {filePath}", e);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
}
public static string GetFolderSize(string folderPath)
{
- var directoryInfo = new DirectoryInfo(folderPath);
- long size = 0;
try
{
+ var directoryInfo = new DirectoryInfo(folderPath);
+ long size = 0;
foreach (var file in directoryInfo.GetFiles("*", SearchOption.AllDirectories))
{
size += file.Length;
}
+ return ResultManager.ToReadableSize(size, 2);
}
- catch (Exception)
+ catch (Exception e)
{
+ Main.Context.API.LogException(ClassName, $"Failed to get folder size for {folderPath}", e);
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
}
- return ResultManager.ToReadableSize(size, 2);
}
public static string GetFolderCreatedAt(string folderPath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
{
- var createdDate = Directory.GetCreationTime(folderPath);
- var formattedDate = createdDate.ToString(
- $"{previewPanelDateFormat} {previewPanelTimeFormat}",
- CultureInfo.CurrentCulture
- );
-
- var result = formattedDate;
- if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
- return result;
+ try
+ {
+ var createdDate = Directory.GetCreationTime(folderPath);
+ var formattedDate = createdDate.ToString(
+ $"{previewPanelDateFormat} {previewPanelTimeFormat}",
+ CultureInfo.CurrentCulture
+ );
+
+ var result = formattedDate;
+ if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
+ return result;
+ }
+ catch (Exception e)
+ {
+ Main.Context.API.LogException(ClassName, $"Failed to get folder created date for {folderPath}", e);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
}
public static string GetFolderLastModifiedAt(string folderPath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
{
- var lastModifiedDate = Directory.GetLastWriteTime(folderPath);
- var formattedDate = lastModifiedDate.ToString(
- $"{previewPanelDateFormat} {previewPanelTimeFormat}",
- CultureInfo.CurrentCulture
- );
-
- var result = formattedDate;
- if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
- return result;
+ try
+ {
+ var lastModifiedDate = Directory.GetLastWriteTime(folderPath);
+ var formattedDate = lastModifiedDate.ToString(
+ $"{previewPanelDateFormat} {previewPanelTimeFormat}",
+ CultureInfo.CurrentCulture
+ );
+
+ var result = formattedDate;
+ if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
+ return result;
+ }
+ catch (Exception e)
+ {
+ Main.Context.API.LogException(ClassName, $"Failed to get folder modified date for {folderPath}", e);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
}
private static string GetFileAge(DateTime fileDateTime)
From edb4d743e9d193624871d1522a53c775ee2f1fa2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 17:36:37 +0800
Subject: [PATCH 07/19] Add timeout for folder size calculation
---
.../Views/PreviewPanel.xaml.cs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index f4d7f843677..a427a0a426b 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -3,6 +3,7 @@
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
+using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
@@ -149,8 +150,15 @@ public static string GetFolderSize(string folderPath)
{
var directoryInfo = new DirectoryInfo(folderPath);
long size = 0;
+ var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));
foreach (var file in directoryInfo.GetFiles("*", SearchOption.AllDirectories))
{
+ if (cancellationTokenSource.Token.IsCancellationRequested)
+ {
+ // Timeout occurred, return unknown size
+ cancellationTokenSource.Dispose();
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
size += file.Length;
}
return ResultManager.ToReadableSize(size, 2);
From f2a7536298965fd77d83ba74e4af83750b7143bf Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Wed, 4 Jun 2025 17:42:56 +0800
Subject: [PATCH 08/19] Use EnumerateFiles instead of GetFiles
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
.../Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index a427a0a426b..80c99ab9fce 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -151,7 +151,7 @@ public static string GetFolderSize(string folderPath)
var directoryInfo = new DirectoryInfo(folderPath);
long size = 0;
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));
- foreach (var file in directoryInfo.GetFiles("*", SearchOption.AllDirectories))
+ foreach (var file in directoryInfo.EnumerateFiles("*", SearchOption.AllDirectories))
{
if (cancellationTokenSource.Token.IsCancellationRequested)
{
From 32b75b4a4fcbc1039be92d55535049e0b0eaa05b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 4 Jun 2025 17:44:24 +0800
Subject: [PATCH 09/19] Fix CancellationTokenSource dispose state
---
.../Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index 80c99ab9fce..a3a0ad0aa0e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -150,13 +150,12 @@ public static string GetFolderSize(string folderPath)
{
var directoryInfo = new DirectoryInfo(folderPath);
long size = 0;
- var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));
+ using var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));
foreach (var file in directoryInfo.EnumerateFiles("*", SearchOption.AllDirectories))
{
if (cancellationTokenSource.Token.IsCancellationRequested)
{
// Timeout occurred, return unknown size
- cancellationTokenSource.Dispose();
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
}
size += file.Length;
From e61151dc437bf62deb92291302ecc88b1ea1a780 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 11:18:07 +0800
Subject: [PATCH 10/19] Improve preview panel performance
---
.../Views/PreviewPanel.xaml | 2 +-
.../Views/PreviewPanel.xaml.cs | 15 +++++++++++++--
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
index 22aa8f5971c..e200a187f19 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
@@ -117,7 +117,7 @@
HorizontalAlignment="Right"
VerticalAlignment="Top"
Style="{DynamicResource PreviewItemSubTitleStyle}"
- Text="{Binding FileSize, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
+ Text="{Binding FileSize, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Mode=OneWay}"
TextWrapping="Wrap"
Visibility="{Binding FileSizeVisibility, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index a3a0ad0aa0e..ec60a3c1390 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -20,7 +20,7 @@ public partial class PreviewPanel : UserControl, INotifyPropertyChanged
private static readonly string ClassName = nameof(PreviewPanel);
private string FilePath { get; }
- public string FileSize { get; } = "";
+ public string FileSize { get; private set; } = Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
public string CreatedAt { get; } = "";
public string LastModifiedAt { get; } = "";
private ImageSource _previewImage = new BitmapImage();
@@ -63,7 +63,18 @@ public PreviewPanel(Settings settings, string filePath, ResultType type)
if (Settings.ShowFileSizeInPreviewPanel)
{
- FileSize = type == ResultType.File ? GetFileSize(filePath) : GetFolderSize(filePath);
+ if (type == ResultType.File)
+ {
+ FileSize = GetFileSize(filePath);
+ }
+ else
+ {
+ _ = Task.Run(() =>
+ {
+ FileSize = GetFolderSize(filePath);
+ OnPropertyChanged(nameof(FileSize));
+ }).ConfigureAwait(false);
+ }
}
if (Settings.ShowCreatedDateInPreviewPanel)
From 19061df586b2d2d37b3757fb4ef25eb0d931cec3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 11:24:20 +0800
Subject: [PATCH 11/19] Use concurrent version
---
.../Views/PreviewPanel.xaml.cs | 24 ++++++++++---------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index ec60a3c1390..5c250c8a898 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -2,6 +2,7 @@
using System.ComponentModel;
using System.Globalization;
using System.IO;
+using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
@@ -157,22 +158,23 @@ public static string GetFileLastModifiedAt(string filePath, string previewPanelD
public static string GetFolderSize(string folderPath)
{
+ using var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
+
try
{
+ // Use parallel enumeration for better performance
var directoryInfo = new DirectoryInfo(folderPath);
- long size = 0;
- using var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));
- foreach (var file in directoryInfo.EnumerateFiles("*", SearchOption.AllDirectories))
- {
- if (cancellationTokenSource.Token.IsCancellationRequested)
- {
- // Timeout occurred, return unknown size
- return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
- }
- size += file.Length;
- }
+ long size = directoryInfo.EnumerateFiles("*", SearchOption.AllDirectories)
+ .AsParallel()
+ .WithCancellation(timeoutCts.Token)
+ .Sum(file => file.Length);
+
return ResultManager.ToReadableSize(size, 2);
}
+ catch (OperationCanceledException)
+ {
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
catch (Exception e)
{
Main.Context.API.LogException(ClassName, $"Failed to get folder size for {folderPath}", e);
From 617c62f6c6ee5c87ab4356d5af9d03bec134e25d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 11:25:48 +0800
Subject: [PATCH 12/19] Add error log message
---
Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index 5c250c8a898..e4a9e5bb215 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -173,6 +173,7 @@ public static string GetFolderSize(string folderPath)
}
catch (OperationCanceledException)
{
+ Main.Context.API.LogError(ClassName, $"Operation timed out while calculating folder size for {folderPath}");
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
}
catch (Exception e)
From 14ffe3c6757f086dc4fbd360caa4f70801ad82d2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 11:38:08 +0800
Subject: [PATCH 13/19] Handle more exceptions
---
.../Views/PreviewPanel.xaml.cs | 60 +++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index e4a9e5bb215..5c0832871c6 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -107,6 +107,16 @@ public static string GetFileSize(string filePath)
var fileInfo = new FileInfo(filePath);
return ResultManager.ToReadableSize(fileInfo.Length, 2);
}
+ catch (FileNotFoundException)
+ {
+ Main.Context.API.LogError(ClassName, $"File not found: {filePath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ catch (UnauthorizedAccessException)
+ {
+ Main.Context.API.LogError(ClassName, $"Access denied to file: {filePath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
catch (Exception e)
{
Main.Context.API.LogException(ClassName, $"Failed to get file size for {filePath}", e);
@@ -128,6 +138,16 @@ public static string GetFileCreatedAt(string filePath, string previewPanelDateFo
if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
return result;
}
+ catch (FileNotFoundException)
+ {
+ Main.Context.API.LogError(ClassName, $"File not found: {filePath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ catch (UnauthorizedAccessException)
+ {
+ Main.Context.API.LogError(ClassName, $"Access denied to file: {filePath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
catch (Exception e)
{
Main.Context.API.LogException(ClassName, $"Failed to get file created date for {filePath}", e);
@@ -149,6 +169,16 @@ public static string GetFileLastModifiedAt(string filePath, string previewPanelD
if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
return result;
}
+ catch (FileNotFoundException)
+ {
+ Main.Context.API.LogError(ClassName, $"File not found: {filePath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ catch (UnauthorizedAccessException)
+ {
+ Main.Context.API.LogError(ClassName, $"Access denied to file: {filePath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
catch (Exception e)
{
Main.Context.API.LogException(ClassName, $"Failed to get file modified date for {filePath}", e);
@@ -171,6 +201,16 @@ public static string GetFolderSize(string folderPath)
return ResultManager.ToReadableSize(size, 2);
}
+ catch (FileNotFoundException)
+ {
+ Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ catch (UnauthorizedAccessException)
+ {
+ Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
catch (OperationCanceledException)
{
Main.Context.API.LogError(ClassName, $"Operation timed out while calculating folder size for {folderPath}");
@@ -197,6 +237,16 @@ public static string GetFolderCreatedAt(string folderPath, string previewPanelDa
if (showFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
return result;
}
+ catch (FileNotFoundException)
+ {
+ Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ catch (UnauthorizedAccessException)
+ {
+ Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
catch (Exception e)
{
Main.Context.API.LogException(ClassName, $"Failed to get folder created date for {folderPath}", e);
@@ -218,6 +268,16 @@ public static string GetFolderLastModifiedAt(string folderPath, string previewPa
if (showFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
return result;
}
+ catch (FileNotFoundException)
+ {
+ Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ catch (UnauthorizedAccessException)
+ {
+ Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
catch (Exception e)
{
Main.Context.API.LogException(ClassName, $"Failed to get folder modified date for {folderPath}", e);
From 1a95632ddf2617c059554a95469c90d55acb70a3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 11:45:18 +0800
Subject: [PATCH 14/19] Handle AggregateException
---
.../Views/PreviewPanel.xaml.cs | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index 5c0832871c6..5714b0d0f3f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -216,6 +216,25 @@ public static string GetFolderSize(string folderPath)
Main.Context.API.LogError(ClassName, $"Operation timed out while calculating folder size for {folderPath}");
return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
}
+ // For parallel operations, AggregateException may be thrown if any of the tasks fail
+ catch (AggregateException ae)
+ {
+ switch (ae.InnerException)
+ {
+ case FileNotFoundException:
+ Main.Context.API.LogError(ClassName, $"Folder not found: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ case UnauthorizedAccessException:
+ Main.Context.API.LogError(ClassName, $"Access denied to folder: {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ case OperationCanceledException:
+ Main.Context.API.LogError(ClassName, $"Operation timed out while calculating folder size for {folderPath}");
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ default:
+ Main.Context.API.LogException(ClassName, $"Failed to get folder size for {folderPath}", ae);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ }
catch (Exception e)
{
Main.Context.API.LogException(ClassName, $"Failed to get folder size for {folderPath}", e);
From 4c7a4fec1f09a44887baadb4c4026019046c28b0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 5 Jun 2025 11:56:21 +0800
Subject: [PATCH 15/19] Add more info tooltip support for volumes
---
.../Languages/en.xaml | 1 +
.../Search/ResultManager.cs | 79 ++++++++++---------
2 files changed, 44 insertions(+), 36 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index 1cb050e64df..f782a59fa81 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
@@ -82,6 +82,7 @@
Ctrl + Enter to open the containing folder
{0}{4}Size: {1}{4}Date created: {2}{4}Date modified: {3}
Unknown
+ {0}{3}Space free: {1}{3}Total size: {2}
Copy path
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
index 4e9a376ab55..6bbdcbe0a91 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -162,7 +162,7 @@ internal static Result CreateFolderResult(string title, string subtitle, string
},
Score = score,
TitleToolTip = Main.Context.API.GetTranslation("plugin_explorer_plugin_ToolTipOpenDirectory"),
- SubTitleToolTip = Settings.DisplayMoreInformationInToolTip ? GetMoreInfoToolTip(path, ResultType.Folder) : path,
+ SubTitleToolTip = Settings.DisplayMoreInformationInToolTip ? GetFolderMoreInfoTooltip(path) : path,
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path, WindowsIndexed = windowsIndexed }
};
}
@@ -183,6 +183,10 @@ internal static Result CreateDriveSpaceDisplayResult(string path, string actionK
if (progressValue >= 90)
progressBarColor = "#da2626";
+ var tooltip = Settings.DisplayMoreInformationInToolTip
+ ? GetVolumeMoreInfoTooltip(path, freespace, totalspace)
+ : path;
+
return new Result
{
Title = title,
@@ -201,8 +205,8 @@ internal static Result CreateDriveSpaceDisplayResult(string path, string actionK
OpenFolder(path);
return true;
},
- TitleToolTip = path,
- SubTitleToolTip = path,
+ TitleToolTip = tooltip,
+ SubTitleToolTip = tooltip,
ContextData = new SearchResult { Type = ResultType.Volume, FullPath = path, WindowsIndexed = windowsIndexed }
};
}
@@ -316,7 +320,7 @@ internal static Result CreateFileResult(string filePath, Query query, int score
return true;
},
TitleToolTip = Main.Context.API.GetTranslation("plugin_explorer_plugin_ToolTipOpenContainingFolder"),
- SubTitleToolTip = Settings.DisplayMoreInformationInToolTip ? GetMoreInfoToolTip(filePath, ResultType.File) : filePath,
+ SubTitleToolTip = Settings.DisplayMoreInformationInToolTip ? GetFileMoreInfoTooltip(filePath) : filePath,
ContextData = new SearchResult { Type = ResultType.File, FullPath = filePath, WindowsIndexed = windowsIndexed }
};
return result;
@@ -347,43 +351,46 @@ private static void IncrementEverythingRunCounterIfNeeded(string fileOrFolder)
_ = Task.Run(() => EverythingApi.IncrementRunCounterAsync(fileOrFolder));
}
- private static string GetMoreInfoToolTip(string filePath, ResultType type)
+ private static string GetFileMoreInfoTooltip(string filePath)
{
- switch (type)
+ try
{
- case ResultType.Folder:
- try
- {
- var folderSize = PreviewPanel.GetFolderSize(filePath);
- var folderCreatedAt = PreviewPanel.GetFolderCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
- var folderModifiedAt = PreviewPanel.GetFolderLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
- return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
- filePath, folderSize, folderCreatedAt, folderModifiedAt, Environment.NewLine);
- }
- catch (Exception e)
- {
- Context.API.LogException(ClassName, $"Failed to load tooltip for {filePath}", e);
- return filePath;
- }
- case ResultType.File:
- try
- {
- var fileSize = PreviewPanel.GetFileSize(filePath);
- var fileCreatedAt = PreviewPanel.GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
- var fileModifiedAt = PreviewPanel.GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
- return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
- filePath, fileSize, fileCreatedAt, fileModifiedAt, Environment.NewLine);
- }
- catch (Exception e)
- {
- Context.API.LogException(ClassName, $"Failed to load tooltip for {filePath}", e);
- return filePath;
- }
- default:
- return filePath;
+ var fileSize = PreviewPanel.GetFileSize(filePath);
+ var fileCreatedAt = PreviewPanel.GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ var fileModifiedAt = PreviewPanel.GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
+ filePath, fileSize, fileCreatedAt, fileModifiedAt, Environment.NewLine);
+ }
+ catch (Exception e)
+ {
+ Context.API.LogException(ClassName, $"Failed to load tooltip for {filePath}", e);
+ return filePath;
}
}
+ private static string GetFolderMoreInfoTooltip(string folderPath)
+ {
+ try
+ {
+ var folderSize = PreviewPanel.GetFolderSize(folderPath);
+ var folderCreatedAt = PreviewPanel.GetFolderCreatedAt(folderPath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ var folderModifiedAt = PreviewPanel.GetFolderLastModifiedAt(folderPath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info"),
+ folderPath, folderSize, folderCreatedAt, folderModifiedAt, Environment.NewLine);
+ }
+ catch (Exception e)
+ {
+ Context.API.LogException(ClassName, $"Failed to load tooltip for {folderPath}", e);
+ return folderPath;
+ }
+ }
+
+ private static string GetVolumeMoreInfoTooltip(string volumePath, string freespace, string totalspace)
+ {
+ return string.Format(Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_volume"),
+ volumePath, freespace, totalspace, Environment.NewLine);
+ }
+
private static readonly string[] MediaExtensions = { ".jpg", ".png", ".avi", ".mkv", ".bmp", ".gif", ".wmv", ".mp3", ".flac", ".mp4" };
}
From abe287f47c606aa2c4616a35277a5fb8cc0e2a5f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 09:33:34 +0800
Subject: [PATCH 16/19] Add MMM date format
---
.../ViewModels/SettingsViewModel.cs | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index fb33dacab01..680663e1ed6 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -243,6 +243,21 @@ public string PreviewPanelTimeFormat
"yyyy-MM-dd",
"yyyy-MM-dd ddd",
"yyyy-MM-dd, dddd",
+ "dd/MMM/yyyy",
+ "dd/MMM/yyyy ddd",
+ "dd/MMM/yyyy, dddd",
+ "dd-MMM-yyyy",
+ "dd-MMM-yyyy ddd",
+ "dd-MMM-yyyy, dddd",
+ "dd.MMM.yyyy",
+ "dd.MMM.yyyy ddd",
+ "dd.MMM.yyyy, dddd",
+ "MMM/dd/yyyy",
+ "MMM/dd/yyyy ddd",
+ "MMM/dd/yyyy, dddd",
+ "yyyy-MMM-dd",
+ "yyyy-MMM-dd ddd",
+ "yyyy-MMM-dd, dddd",
};
#endregion
From 82f3e99f0eec30c493169c1cf754ab80b88f7f8a Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 6 Jun 2025 20:08:11 +0800
Subject: [PATCH 17/19] Revert changes in ExplorerSettings.xaml
---
.../Views/ExplorerSettings.xaml | 44 +++++++------------
1 file changed, 17 insertions(+), 27 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 50151d0b018..b5ac95c445b 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -198,7 +198,6 @@
-
@@ -223,17 +222,8 @@
Content="{DynamicResource plugin_explorer_default_open_in_file_manager}"
IsChecked="{Binding Settings.DefaultOpenFolderInFileManager}" />
-
-
@@ -260,7 +250,7 @@
@@ -287,7 +277,7 @@
@@ -314,14 +304,14 @@