Skip to content

Commit

Permalink
Merge pull request #2082 from VictoriousRaptor/quicklook
Browse files Browse the repository at this point in the history
Add external preview (QuickLook) support
  • Loading branch information
jjw24 authored Jun 16, 2024
2 parents 3f3612a + 7f31fef commit ea65c8f
Show file tree
Hide file tree
Showing 9 changed files with 300 additions and 66 deletions.
1 change: 1 addition & 0 deletions .github/actions/spelling/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ Português
Português (Brasil)
Italiano
Slovenský
quicklook
Tiếng Việt
Droplex
Preinstalled
Expand Down
44 changes: 43 additions & 1 deletion Flow.Launcher.Core/Plugin/PluginManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Core.ExternalPlugins;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
Expand Down Expand Up @@ -90,6 +90,48 @@ public static async Task ReloadDataAsync()
}).ToArray());
}

public static async Task OpenExternalPreviewAsync(string path, bool sendFailToast = true)
{
await Task.WhenAll(AllPlugins.Select(plugin => plugin.Plugin switch
{
IAsyncExternalPreview p => p.OpenPreviewAsync(path, sendFailToast),
_ => Task.CompletedTask,
}).ToArray());
}

public static async Task CloseExternalPreviewAsync()
{
await Task.WhenAll(AllPlugins.Select(plugin => plugin.Plugin switch
{
IAsyncExternalPreview p => p.ClosePreviewAsync(),
_ => Task.CompletedTask,
}).ToArray());
}

public static async Task SwitchExternalPreviewAsync(string path, bool sendFailToast = true)
{
await Task.WhenAll(AllPlugins.Select(plugin => plugin.Plugin switch
{
IAsyncExternalPreview p => p.SwitchPreviewAsync(path, sendFailToast),
_ => Task.CompletedTask,
}).ToArray());
}

public static bool UseExternalPreview()
{
return GetPluginsForInterface<IAsyncExternalPreview>().Any(x => !x.Metadata.Disabled);
}

public static bool AllowAlwaysPreview()
{
var plugin = GetPluginsForInterface<IAsyncExternalPreview>().FirstOrDefault(x => !x.Metadata.Disabled);

if (plugin is null)
return false;

return ((IAsyncExternalPreview)plugin.Plugin).AllowAlwaysPreview();
}

static PluginManager()
{
// validate user directory
Expand Down
2 changes: 2 additions & 0 deletions Flow.Launcher.Infrastructure/UserSettings/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,9 @@ public CustomBrowserViewModel CustomBrowser
/// when false Alphabet static service will always return empty results
/// </summary>
public bool ShouldUsePinyin { get; set; } = false;

public bool AlwaysPreview { get; set; } = false;

public bool AlwaysStartEn { get; set; } = false;

private SearchPrecisionScore _querySearchPrecision = SearchPrecisionScore.Regular;
Expand Down
40 changes: 40 additions & 0 deletions Flow.Launcher.Plugin/Interfaces/IAsyncExternalPreview.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System.Threading.Tasks;

namespace Flow.Launcher.Plugin
{
/// <summary>
/// This interface is for plugins that wish to provide file preview (external preview)
/// via a third party app instead of the default preview.
/// </summary>
public interface IAsyncExternalPreview : IFeatures
{
/// <summary>
/// Method for opening/showing the preview.
/// </summary>
/// <param name="path">The file path to open the preview for</param>
/// <param name="sendFailToast">Whether to send a toast message notification on failure for the user</param>
public Task OpenPreviewAsync(string path, bool sendFailToast = true);

/// <summary>
/// Method for closing/hiding the preview.
/// </summary>
public Task ClosePreviewAsync();

/// <summary>
/// Method for switching the preview to the next file result.
/// This requires the external preview be already open/showing
/// </summary>
/// <param name="path">The file path to switch the preview for</param>
/// <param name="sendFailToast">Whether to send a toast message notification on failure for the user</param>
public Task SwitchPreviewAsync(string path, bool sendFailToast = true);

/// <summary>
/// Allows the preview plugin to override the AlwaysPreview setting. Typically useful if plugin's preview does not
/// fully work well with being shown together when the query window appears with results.
/// When AlwaysPreview setting is on and this is set to false, the preview will not be shown when query
/// window appears with results, instead the internal preview will be shown.
/// </summary>
/// <returns></returns>
public bool AllowAlwaysPreview();
}
}
14 changes: 10 additions & 4 deletions Flow.Launcher.Plugin/Result.cs
Original file line number Diff line number Diff line change
Expand Up @@ -270,25 +270,30 @@ public record PreviewInfo
/// <summary>
/// Full image used for preview panel
/// </summary>
public string PreviewImagePath { get; set; }
public string PreviewImagePath { get; set; } = null;

/// <summary>
/// Determines if the preview image should occupy the full width of the preview panel.
/// </summary>
public bool IsMedia { get; set; }
public bool IsMedia { get; set; } = false;

/// <summary>
/// Result description text that is shown at the bottom of the preview panel.
/// </summary>
/// <remarks>
/// When a value is not set, the <see cref="SubTitle"/> will be used.
/// </remarks>
public string Description { get; set; }
public string Description { get; set; } = null;

/// <summary>
/// Delegate to get the preview panel's image
/// </summary>
public IconDelegate PreviewDelegate { get; set; }
public IconDelegate PreviewDelegate { get; set; } = null;

/// <summary>
/// File path of the result. For third-party programs providing external preview.
/// </summary>
public string FilePath { get; set; } = null;

/// <summary>
/// Default instance of <see cref="PreviewInfo"/>
Expand All @@ -299,6 +304,7 @@ public record PreviewInfo
Description = null,
IsMedia = false,
PreviewDelegate = null,
FilePath = null,
};
}
}
Expand Down
4 changes: 2 additions & 2 deletions Flow.Launcher/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@
VerticalAlignment="Stretch"
Background="Transparent"
ShowsPreview="True"
Visibility="{Binding PreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
Visibility="{Binding InternalPreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
<GridSplitter.Template>
<ControlTemplate TargetType="{x:Type GridSplitter}">
<Border Style="{DynamicResource PreviewBorderStyle}" />
Expand All @@ -439,7 +439,7 @@
Grid.Column="2"
VerticalAlignment="Stretch"
Style="{DynamicResource PreviewArea}"
Visibility="{Binding PreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
Visibility="{Binding InternalPreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
<Border
MinHeight="380"
d:DataContext="{d:DesignInstance vm:ResultViewModel}"
Expand Down
2 changes: 1 addition & 1 deletion Flow.Launcher/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ private async void OnDeactivated(object sender, EventArgs e)
if (_settings.UseAnimation)
await Task.Delay(100);

if (_settings.HideWhenDeactivated)
if (_settings.HideWhenDeactivated && !_viewModel.ExternalPreviewVisible)
{
_viewModel.Hide();
}
Expand Down
Loading

0 comments on commit ea65c8f

Please sign in to comment.