diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
index 9f60aaa4340..1cbcdd64de8 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,9 @@
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
+ {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 5c4accdc05f..6bbdcbe0a91 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; }
@@ -99,10 +101,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)
@@ -163,7 +162,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 ? GetFolderMoreInfoTooltip(path) : path,
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path, WindowsIndexed = windowsIndexed }
};
}
@@ -184,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,
@@ -202,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 }
};
}
@@ -269,7 +272,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
@@ -287,7 +289,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)
@@ -318,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 = filePath,
+ SubTitleToolTip = Settings.DisplayMoreInformationInToolTip ? GetFileMoreInfoTooltip(filePath) : filePath,
ContextData = new SearchResult { Type = ResultType.File, FullPath = filePath, WindowsIndexed = windowsIndexed }
};
return result;
@@ -349,6 +351,46 @@ private static void IncrementEverythingRunCounterIfNeeded(string fileOrFolder)
_ = Task.Run(() => EverythingApi.IncrementRunCounterAsync(fileOrFolder));
}
+ private static string GetFileMoreInfoTooltip(string filePath)
+ {
+ 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;
+ }
+ }
+
+ 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" };
}
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/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
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
index 47d53d46360..93012bd3624 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
@@ -92,41 +92,43 @@
+ Background="{TemplateBinding Background}"
+ BorderBrush="{TemplateBinding BorderBrush}"
+ BorderThickness="{TemplateBinding BorderThickness}"
+ SnapsToDevicePixels="true">
-
+ x:Name="HeaderSite"
+ MinWidth="0"
+ MinHeight="0"
+ Margin="0"
+ Padding="{TemplateBinding Padding}"
+ HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
+ VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
+ Content="{TemplateBinding Header}"
+ ContentTemplate="{TemplateBinding HeaderTemplate}"
+ ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
+ DockPanel.Dock="Top"
+ FocusVisualStyle="{StaticResource ExpanderHeaderFocusVisual}"
+ FontFamily="{TemplateBinding FontFamily}"
+ FontSize="{TemplateBinding FontSize}"
+ FontStretch="{TemplateBinding FontStretch}"
+ FontStyle="{TemplateBinding FontStyle}"
+ FontWeight="{TemplateBinding FontWeight}"
+ Foreground="{TemplateBinding Foreground}"
+ IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
+ Style="{StaticResource ExpanderHeaderRightArrowStyle}" />
+
+ x:Name="ExpandSite"
+ Margin="{TemplateBinding Padding}"
+ HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
+ VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
+ DockPanel.Dock="Bottom"
+ Focusable="false" />
@@ -141,13 +143,17 @@
+ Storyboard.TargetName="ContentPresenterBorder"
+ Storyboard.TargetProperty="(Border.LayoutTransform).(ScaleTransform.ScaleY)"
+ From="0.0"
+ To="1.0"
+ Duration="0:0:0" />
+ Storyboard.TargetName="ContentPresenterBorder"
+ Storyboard.TargetProperty="(Border.Opacity)"
+ From="0.0"
+ To="1.0"
+ Duration="0:0:0" />
@@ -155,13 +161,17 @@
+ Storyboard.TargetName="ContentPresenterBorder"
+ Storyboard.TargetProperty="(Border.LayoutTransform).(ScaleTransform.ScaleY)"
+ From="1.0"
+ To="0.0"
+ Duration="0:0:0" />
+ Storyboard.TargetName="ContentPresenterBorder"
+ Storyboard.TargetProperty="(Border.Opacity)"
+ From="1.0"
+ To="0.0"
+ Duration="0:0:0" />
@@ -197,6 +207,7 @@
+
@@ -220,16 +231,25 @@
Content="{DynamicResource plugin_explorer_default_open_in_file_manager}"
IsChecked="{Binding Settings.DefaultOpenFolderInFileManager}" />
-
+
+
@@ -248,7 +268,7 @@
@@ -275,7 +295,7 @@
@@ -302,14 +322,14 @@
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
index e1a957199a5..5714b0d0f3f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
@@ -2,7 +2,9 @@
using System.ComponentModel;
using System.Globalization;
using System.IO;
+using System.Linq;
using System.Runtime.CompilerServices;
+using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
@@ -16,8 +18,10 @@ 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 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();
@@ -50,7 +54,7 @@ private set
? Visibility.Visible
: Visibility.Collapsed;
- public PreviewPanel(Settings settings, string filePath)
+ public PreviewPanel(Settings settings, string filePath, ResultType type)
{
InitializeComponent();
@@ -60,43 +64,246 @@ public PreviewPanel(Settings settings, string filePath)
if (Settings.ShowFileSizeInPreviewPanel)
{
- var fileSize = new FileInfo(filePath).Length;
- FileSize = ResultManager.ToReadableSize(fileSize, 2);
+ if (type == ResultType.File)
+ {
+ FileSize = GetFileSize(filePath);
+ }
+ else
+ {
+ _ = Task.Run(() =>
+ {
+ FileSize = GetFolderSize(filePath);
+ OnPropertyChanged(nameof(FileSize));
+ }).ConfigureAwait(false);
+ }
}
if (Settings.ShowCreatedDateInPreviewPanel)
{
- DateTime createdDate = File.GetCreationTime(filePath);
- string formattedDate = createdDate.ToString(
- $"{Settings.PreviewPanelDateFormat} {Settings.PreviewPanelTimeFormat}",
+ CreatedAt = type == ResultType.File ?
+ GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel) :
+ GetFolderCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ }
+
+ if (Settings.ShowModifiedDateInPreviewPanel)
+ {
+ LastModifiedAt = type == ResultType.File ?
+ GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel) :
+ GetFolderLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ }
+
+ _ = LoadImageAsync();
+ }
+
+ private async Task LoadImageAsync()
+ {
+ PreviewImage = await Main.Context.API.LoadImageAsync(FilePath, true).ConfigureAwait(false);
+ }
+
+ public static string GetFileSize(string filePath)
+ {
+ try
+ {
+ 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);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ }
+
+ public static string GetFileCreatedAt(string filePath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
+ {
+ try
+ {
+ var createdDate = File.GetCreationTime(filePath);
+ var formattedDate = createdDate.ToString(
+ $"{previewPanelDateFormat} {previewPanelTimeFormat}",
CultureInfo.CurrentCulture
);
- string result = formattedDate;
- if (Settings.ShowFileAgeInPreviewPanel) result = $"{GetFileAge(createdDate)} - {formattedDate}";
- CreatedAt = result;
+ var result = formattedDate;
+ 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);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
}
+ }
- if (Settings.ShowModifiedDateInPreviewPanel)
+ public static string GetFileLastModifiedAt(string filePath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
+ {
+ try
{
- DateTime lastModifiedDate = File.GetLastWriteTime(filePath);
- string formattedDate = lastModifiedDate.ToString(
- $"{Settings.PreviewPanelDateFormat} {Settings.PreviewPanelTimeFormat}",
+ var lastModifiedDate = File.GetLastWriteTime(filePath);
+ var formattedDate = lastModifiedDate.ToString(
+ $"{previewPanelDateFormat} {previewPanelTimeFormat}",
CultureInfo.CurrentCulture
);
- string result = formattedDate;
- if (Settings.ShowFileAgeInPreviewPanel) result = $"{GetFileAge(lastModifiedDate)} - {formattedDate}";
- LastModifiedAt = result;
+
+ var result = formattedDate;
+ 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);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ }
- _ = LoadImageAsync();
+ 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 = directoryInfo.EnumerateFiles("*", SearchOption.AllDirectories)
+ .AsParallel()
+ .WithCancellation(timeoutCts.Token)
+ .Sum(file => file.Length);
+
+ 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}");
+ 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);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
}
- private async Task LoadImageAsync()
+ public static string GetFolderCreatedAt(string folderPath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
{
- PreviewImage = await Main.Context.API.LoadImageAsync(FilePath, true).ConfigureAwait(false);
+ 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 (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);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
+ }
+
+ public static string GetFolderLastModifiedAt(string folderPath, string previewPanelDateFormat, string previewPanelTimeFormat, bool showFileAgeInPreviewPanel)
+ {
+ 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 (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);
+ return Main.Context.API.GetTranslation("plugin_explorer_plugin_tooltip_more_info_unknown");
+ }
}
-
+
private static string GetFileAge(DateTime fileDateTime)
{
var now = DateTime.Now;