-
-
Notifications
You must be signed in to change notification settings - Fork 453
Add external preview (QuickLook) support #2082
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 48 commits
Commits
Show all changes
53 commits
Select commit
Hold shift + click to select a range
71376b8
Add FilePath property for PreviewInfo
VictoriousRaptor 96f5231
Add FilePath for Explorer results preview
VictoriousRaptor 0c4f50a
Default values for preview info
VictoriousRaptor 1cedb6e
Add file path in preview
VictoriousRaptor f460913
Move QuickLook support to QuickLookHelper
VictoriousRaptor 0b6f737
Add open/close QuickLook function
VictoriousRaptor ab20dcc
Reorganize preview code
VictoriousRaptor 98991fe
Implement open QuickLook feature
VictoriousRaptor 99b5197
Fix case when switching file
VictoriousRaptor 1e1f29b
Add UI to toggle QuickLook usage
VictoriousRaptor afa8a34
Tweak Win32 preview path
VictoriousRaptor a1600fa
Implement preview switching logic
VictoriousRaptor cf10a4a
Rename method for clarity
VictoriousRaptor 10d1410
Reduce unnecessary image load
VictoriousRaptor ba8bb3a
Fix switching preview logic
VictoriousRaptor 098e90b
Hide external preview when hiding flow
VictoriousRaptor 26ff98e
comment
VictoriousRaptor 9061da9
Formatting
VictoriousRaptor 441d4cb
Configure await for QuickLook calls
VictoriousRaptor 45a42a5
Log exception when QL timeout
VictoriousRaptor cda587f
Show toast when QL unavailable
VictoriousRaptor 2ed33a2
Refactor QuickLook toggle and update logic
VictoriousRaptor 64afeed
Rename variable
VictoriousRaptor d266e9e
Simplify QuickLook logic
VictoriousRaptor ff7457d
Keep FL open when focus lost if QL open
VictoriousRaptor cb33756
Remove QL support for programs
VictoriousRaptor abfbef4
update
VictoriousRaptor c705b01
Change glyph
VictoriousRaptor 7033bce
Add minimum gap time between fail toasts
VictoriousRaptor 2bb398d
Add sendFailToast arg
VictoriousRaptor 1eae693
Merge branch 'dev' into quicklook
VictoriousRaptor e248fcb
Fix build error introduced in 1eae69304f3f961b70fe224a58d870d85bcb08ad
VictoriousRaptor 8da88bd
Hide fail toast for closing
VictoriousRaptor c36cea7
Merge branch 'dev' into quicklook
VictoriousRaptor 29c1503
Merge branch 'dev' into quicklook
VictoriousRaptor 666211d
add plugin support for external preview
jjw24 8da1313
update external preview methods to use the external preview interface
jjw24 587536f
updated PreviewVisible logic to base on ResultAreaColumn size
jjw24 53e4bbb
updated internal and external preview's show and hide logic
jjw24 b345944
Merge branch 'external_preview_plugin_support' into quicklook
jjw24 70e530b
add QuickLook plugin for testing
jjw24 493a30e
remove QuickLook related code from flow
jjw24 f902eae
Merge remote-tracking branch 'origin/dev' into quicklook
jjw24 9e39e48
minor clean up and update
jjw24 f4f519b
minor clean up
jjw24 5ec474c
Merge branch 'dev' into quicklook
VictoriousRaptor 2e47da4
allow internal preview when external not available
jjw24 e6f0f28
Don't show external preview when always preview enabled
VictoriousRaptor 4dbecb1
allow preview plugin to override the AlwaysPreview setting
jjw24 03686dd
Merge remote-tracking branch 'origin/dev' into quicklook
jjw24 0c0806e
Merge branch 'dev' into quicklook
jjw24 25963ea
Merge branch 'dev' into quicklook
jjw24 7f31fef
remove QuickLook plugin test project
jjw24 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -98,6 +98,7 @@ Português | |
| Português (Brasil) | ||
| Italiano | ||
| Slovenský | ||
| quicklook | ||
| Tiếng Việt | ||
| Droplex | ||
| Preinstalled | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| 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); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,153 @@ | ||
| // Adapted from Files | ||
| // https://github.com/files-community/Files/blob/ad33c75c53382fcb9b16fa9cd66ae5399f3dff0b/src/Files.App/Helpers/QuickLookHelpers.cs | ||
| using System; | ||
| using System.IO.Pipes; | ||
| using System.IO; | ||
| using System.Security.Principal; | ||
| using System.Threading.Tasks; | ||
| using Flow.Launcher.Infrastructure.Logger; | ||
| using Flow.Launcher.Core.Resource; | ||
|
|
||
| namespace Flow.Launcher.Helper | ||
| { | ||
| internal static class QuickLookHelper | ||
| { | ||
| private const int TIMEOUT = 500; | ||
| private static DateTime lastNotificationTime = DateTime.MinValue; | ||
|
|
||
| private static readonly string pipeName = $"QuickLook.App.Pipe.{WindowsIdentity.GetCurrent().User?.Value}"; | ||
| private static readonly string pipeMessageSwitch = "QuickLook.App.PipeMessages.Switch"; | ||
| private static readonly string pipeMessageToggle = "QuickLook.App.PipeMessages.Toggle"; | ||
| private static readonly string pipeMessageClose = "QuickLook.App.PipeMessages.Close"; | ||
| private static readonly string pipeMessageInvoke = "QuickLook.App.PipeMessages.Invoke"; | ||
|
|
||
|
|
||
| /// <summary> | ||
| /// Toggle QuickLook | ||
| /// </summary> | ||
| /// <param name="path">File path to preview</param> | ||
| /// <param name="sendFailToast">Send toast when fails.</param> | ||
| /// <returns></returns> | ||
| public static async Task<bool> ToggleQuickLookAsync(string path, bool sendFailToast = true) | ||
| { | ||
| if (string.IsNullOrEmpty(path)) | ||
| return false; | ||
|
|
||
| bool success = await SendQuickLookPipeMsgAsync(pipeMessageToggle, path); | ||
| if (sendFailToast && !success) | ||
| { | ||
| ShowQuickLookUnavailableToast(); | ||
| } | ||
| return success; | ||
| } | ||
|
|
||
| public static async Task<bool> CloseQuickLookAsync() | ||
| { | ||
| bool success = await SendQuickLookPipeMsgAsync(pipeMessageClose); | ||
| return success; | ||
| } | ||
|
|
||
| public static async Task<bool> OpenQuickLookAsync(string path, bool sendFailToast = true) | ||
| { | ||
| if (string.IsNullOrEmpty(path)) | ||
| return false; | ||
|
|
||
| bool success = await SendQuickLookPipeMsgAsync(pipeMessageInvoke, path); | ||
| if (sendFailToast && !success) | ||
| { | ||
| ShowQuickLookUnavailableToast(); | ||
| } | ||
| return success; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Switch QuickLook to preview another file if it's on | ||
| /// </summary> | ||
| /// <param name="path">File path to preview</param> | ||
| /// <param name="sendFailToast">Send notification if fail</param> | ||
| /// <returns></returns> | ||
| public static async Task<bool> SwitchQuickLookAsync(string path, bool sendFailToast = true) | ||
| { | ||
| if (string.IsNullOrEmpty(path)) | ||
| return false; | ||
|
|
||
| bool success = await SendQuickLookPipeMsgAsync(pipeMessageSwitch, path); | ||
| if (sendFailToast && !success) | ||
| { | ||
| ShowQuickLookUnavailableToast(); | ||
| } | ||
| return success; | ||
| } | ||
|
|
||
| private static async Task<bool> SendQuickLookPipeMsgAsync(string message, string arg = "") | ||
| { | ||
| await using var client = new NamedPipeClientStream(".", pipeName, PipeDirection.Out); | ||
| try | ||
| { | ||
| await client.ConnectAsync(TIMEOUT); | ||
|
|
||
| await using var writer = new StreamWriter(client); | ||
| await writer.WriteLineAsync($"{message}|{arg}"); | ||
| await writer.FlushAsync(); | ||
| } | ||
| catch (TimeoutException) | ||
| { | ||
| client.Close(); | ||
| Log.Error($"{nameof(QuickLookHelper)}", "QuickLook timeout"); | ||
| return false; | ||
| } | ||
| catch (Exception e) | ||
| { | ||
| Log.Exception($"{nameof(QuickLookHelper)}", "QuickLook error", e); | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| public static async Task<bool> DetectQuickLookAvailabilityAsync() | ||
| { | ||
| static async Task<int> QuickLookServerAvailable() | ||
| { | ||
| await using var client = new NamedPipeClientStream(".", pipeName, PipeDirection.Out); | ||
| try | ||
| { | ||
| await client.ConnectAsync(TIMEOUT); | ||
| var serverInstances = client.NumberOfServerInstances; | ||
|
|
||
| await using var writer = new StreamWriter(client); | ||
| await writer.WriteLineAsync($"{pipeMessageSwitch}|"); | ||
| await writer.FlushAsync(); | ||
|
|
||
| return serverInstances; | ||
| } | ||
| catch (TimeoutException e) | ||
| { | ||
| client.Close(); | ||
| Log.Exception($"{nameof(QuickLookHelper)}", "QuickLook connection timeout", e); | ||
| return 0; | ||
| } | ||
| } | ||
|
|
||
| try | ||
| { | ||
| var result = await QuickLookServerAvailable(); | ||
| return result != 0; | ||
| } | ||
| catch (Exception e) | ||
| { | ||
| Log.Exception($"{nameof(QuickLookHelper)}", "QuickLook unavailable", e); | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| private static void ShowQuickLookUnavailableToast() | ||
| { | ||
| if (lastNotificationTime.AddSeconds(10) < DateTime.Now) | ||
| { | ||
| Notification.Show(InternationalizationManager.Instance.GetTranslation("QuickLookFail"), | ||
| InternationalizationManager.Instance.GetTranslation("QuickLookFailTips")); | ||
| lastNotificationTime = DateTime.Now; | ||
| } | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.