Skip to content

Commit b345944

Browse files
committed
Merge branch 'external_preview_plugin_support' into quicklook
2 parents 29c1503 + 53e4bbb commit b345944

File tree

5 files changed

+153
-68
lines changed

5 files changed

+153
-68
lines changed

Flow.Launcher.Core/Plugin/PluginManager.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,38 @@ public static async Task ReloadDataAsync()
8888
}).ToArray());
8989
}
9090

91+
public static async Task OpenExternalPreviewAsync(string path, bool sendFailToast = true)
92+
{
93+
await Task.WhenAll(AllPlugins.Select(plugin => plugin.Plugin switch
94+
{
95+
IAsyncExternalPreview p => p.OpenPreviewAsync(path, sendFailToast),
96+
_ => Task.CompletedTask,
97+
}).ToArray());
98+
}
99+
100+
public static async Task CloseExternalPreviewAsync()
101+
{
102+
await Task.WhenAll(AllPlugins.Select(plugin => plugin.Plugin switch
103+
{
104+
IAsyncExternalPreview p => p.ClosePreviewAsync(),
105+
_ => Task.CompletedTask,
106+
}).ToArray());
107+
}
108+
109+
public static async Task SwitchExternalPreviewAsync(string path, bool sendFailToast = true)
110+
{
111+
await Task.WhenAll(AllPlugins.Select(plugin => plugin.Plugin switch
112+
{
113+
IAsyncExternalPreview p => p.SwitchPreviewAsync(path, sendFailToast),
114+
_ => Task.CompletedTask,
115+
}).ToArray());
116+
}
117+
118+
public static bool UseExternalPreview()
119+
{
120+
return GetPluginsForInterface<IAsyncExternalPreview>().Any(x => !x.Metadata.Disabled);
121+
}
122+
91123
static PluginManager()
92124
{
93125
// validate user directory
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Threading.Tasks;
2+
3+
namespace Flow.Launcher.Plugin
4+
{
5+
public interface IAsyncExternalPreview: IFeatures
6+
{
7+
public Task TogglePreviewAsync(string path);
8+
9+
public Task OpenPreviewAsync(string path, bool sendFailToast = true);
10+
11+
public Task ClosePreviewAsync();
12+
13+
public Task SwitchPreviewAsync(string path, bool sendFailToast = true);
14+
}
15+
}

Flow.Launcher/MainWindow.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@
399399
</StackPanel>
400400
<GridSplitter
401401
Grid.Column="1"
402-
Width="{Binding PreviewVisible, Converter={StaticResource SplitterConverter}}"
402+
Width="{Binding InternalPreviewVisible, Converter={StaticResource SplitterConverter}}"
403403
HorizontalAlignment="Center"
404404
VerticalAlignment="Stretch"
405405
Background="Transparent"
@@ -409,7 +409,7 @@
409409
Grid.Column="2"
410410
VerticalAlignment="Stretch"
411411
Style="{DynamicResource PreviewArea}"
412-
Visibility="{Binding PreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
412+
Visibility="{Binding InternalPreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
413413
<Border
414414
d:DataContext="{d:DesignInstance vm:ResultViewModel}"
415415
DataContext="{Binding SelectedItem, ElementName=ResultListBox}"

Flow.Launcher/MainWindow.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ private async void OnDeactivated(object sender, EventArgs e)
502502
if (_settings.UseAnimation)
503503
await Task.Delay(100);
504504

505-
if (_settings.HideWhenDeactivated && !_viewModel.ExternalPreviewOpen)
505+
if (_settings.HideWhenDeactivated && !_viewModel.ExternalPreviewVisible)
506506
{
507507
_viewModel.Hide();
508508
}

Flow.Launcher/ViewModel/MainViewModel.cs

Lines changed: 103 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -572,39 +572,86 @@ public string PreviewHotkey
572572
public string Image => Constant.QueryTextBoxIconImagePath;
573573

574574
public bool StartWithEnglishMode => Settings.AlwaysStartEn;
575-
576-
public bool PreviewVisible { get; set; } = false;
577-
578-
public int ResultAreaColumn { get; set; } = 1;
579-
575+
580576
#endregion
581577

582578
#region Preview
583579

584-
// Not accurate
585-
public bool ExternalPreviewOpen { get; set; } = false;
586-
587-
[RelayCommand]
588-
private void TogglePreview()
580+
public bool InternalPreviewVisible
589581
{
590-
if (PreviewVisible)
582+
get
591583
{
592-
// To deal with always preview
593-
HideInternalPreview();
584+
if (ResultAreaColumn == ResultAreaColumnPreviewShown)
585+
return true;
586+
587+
if (ResultAreaColumn == ResultAreaColumnPreviewHidden)
588+
return false;
589+
#if DEBUG
590+
throw new NotImplementedException("ResultAreaColumn should match ResultAreaColumnPreviewShown/ResultAreaColumnPreviewHidden value");
591+
#else
592+
Log.Error("MainViewModel", "ResultAreaColumnPreviewHidden/ResultAreaColumnPreviewShown int value not implemented", "InternalPreviewVisible");
593+
#endif
594+
return false;
594595
}
595-
else if(Settings.UseExternalPreview && CanExternalPreviewSelectedResult(out var path))
596+
}
597+
598+
private static readonly int ResultAreaColumnPreviewShown = 1;
599+
600+
private static readonly int ResultAreaColumnPreviewHidden = 3;
601+
602+
public int ResultAreaColumn { get; set; } = ResultAreaColumnPreviewShown;
603+
604+
// This is not a reliable indicator of whether external preview is visible due to the
605+
// ability of manually closing/exiting the external preview program, and this does not inform flow that
606+
// preview is no longer available.
607+
public bool ExternalPreviewVisible { get; set; } = false;
608+
609+
private void ShowPreview()
610+
{
611+
var useExternalPreview = PluginManager.UseExternalPreview();
612+
613+
if (!useExternalPreview)
614+
ShowInternalPreview();
615+
616+
if (useExternalPreview)
596617
{
597-
_ = ToggleExternalPreviewAsync(path);
618+
// Internal preview may still be on when user switches to external
619+
if (InternalPreviewVisible)
620+
HideInternalPreview();
621+
622+
if (CanExternalPreviewSelectedResult(out var path))
623+
OpenExternalPreview(path);
598624
}
599-
else
625+
626+
}
627+
628+
private void HidePreview()
629+
{
630+
if (PluginManager.UseExternalPreview())
631+
CloseExternalPreview();
632+
633+
if (InternalPreviewVisible)
634+
HideInternalPreview();
635+
}
636+
637+
[RelayCommand]
638+
private void TogglePreview()
639+
{
640+
switch (InternalPreviewVisible || ExternalPreviewVisible)
600641
{
601-
ShowInternalPreview();
642+
case true:
643+
HidePreview();
644+
break;
645+
646+
case false:
647+
ShowPreview();
648+
break;
602649
}
603650
}
604651

605652
private void ToggleInternalPreview()
606653
{
607-
if (!PreviewVisible)
654+
if (!InternalPreviewVisible)
608655
{
609656
ShowInternalPreview();
610657
}
@@ -614,81 +661,72 @@ private void ToggleInternalPreview()
614661
}
615662
}
616663

617-
private async Task ToggleExternalPreviewAsync(string path)
618-
{
619-
bool success = await QuickLookHelper.ToggleQuickLookAsync(path).ConfigureAwait(false);
620-
if (success)
621-
{
622-
ExternalPreviewOpen = !ExternalPreviewOpen;
623-
}
624-
}
625-
626-
private async Task OpenExternalPreviewAsync(string path, bool sendFailToast = true)
664+
private void OpenExternalPreview(string path, bool sendFailToast = true)
627665
{
628-
bool success = await QuickLookHelper.OpenQuickLookAsync(path, sendFailToast).ConfigureAwait(false);
629-
if (success)
630-
{
631-
ExternalPreviewOpen = false;
632-
}
666+
_ = PluginManager.OpenExternalPreviewAsync(path, sendFailToast).ConfigureAwait(false);
667+
ExternalPreviewVisible = true;
633668
}
634669

635-
private async Task CloseExternalPreviewAsync()
670+
private void CloseExternalPreview()
636671
{
637-
bool success = await QuickLookHelper.CloseQuickLookAsync().ConfigureAwait(false);
638-
if (success)
639-
{
640-
ExternalPreviewOpen = false;
641-
}
672+
_ = PluginManager.CloseExternalPreviewAsync().ConfigureAwait(false);
673+
ExternalPreviewVisible = false;
642674
}
643675

644-
private async Task SwitchExternalPreviewAsync(string path, bool sendFailToast = true)
676+
private void SwitchExternalPreview(string path, bool sendFailToast = true)
645677
{
646-
// Switches preview content
647-
// When external is off, do nothing
648-
_ = QuickLookHelper.SwitchQuickLookAsync(path, sendFailToast).ConfigureAwait(false);
678+
_ = PluginManager.SwitchExternalPreviewAsync(path,sendFailToast).ConfigureAwait(false);
649679
}
650680

651681
private void ShowInternalPreview()
652682
{
653-
ResultAreaColumn = 1;
654-
PreviewVisible = true;
683+
ResultAreaColumn = ResultAreaColumnPreviewShown;
655684
Results.SelectedItem?.LoadPreviewImage();
656685
}
657686

658687
private void HideInternalPreview()
659688
{
660-
ResultAreaColumn = 3;
661-
PreviewVisible = false;
689+
ResultAreaColumn = ResultAreaColumnPreviewHidden;
662690
}
663691

664692
public void ResetPreview()
665693
{
666-
if (Settings.AlwaysPreview == true && !PreviewVisible)
667-
{
668-
ShowInternalPreview();
669-
}
670-
else
694+
switch (Settings.AlwaysPreview)
671695
{
672-
HideInternalPreview();
696+
case true:
697+
ShowPreview();
698+
break;
699+
700+
case false:
701+
HidePreview();
702+
break;
673703
}
674704
}
675705

676706
private void UpdatePreview()
677707
{
678-
if (PreviewVisible)
708+
if (InternalPreviewVisible)
679709
{
680710
Results.SelectedItem?.LoadPreviewImage();
711+
return;
681712
}
682-
else if (Settings.UseExternalPreview)
713+
714+
switch (PluginManager.UseExternalPreview())
683715
{
684-
if (CanExternalPreviewSelectedResult(out var path))
685-
{
686-
_ = SwitchExternalPreviewAsync(path, false);
687-
}
688-
else
689-
{
690-
_ = CloseExternalPreviewAsync();
691-
}
716+
case true
717+
when ExternalPreviewVisible && CanExternalPreviewSelectedResult(out var path):
718+
SwitchExternalPreview(path, false);
719+
break;
720+
721+
case true
722+
when !ExternalPreviewVisible && Settings.AlwaysPreview && CanExternalPreviewSelectedResult(out var path):
723+
ShowPreview();
724+
break;
725+
726+
case true
727+
when !CanExternalPreviewSelectedResult(out var _):
728+
HidePreview();
729+
break;
692730
}
693731
}
694732

@@ -1104,8 +1142,8 @@ public async void Hide()
11041142
// Trick for no delay
11051143
MainWindowOpacity = 0;
11061144

1107-
if (Settings.UseExternalPreview)
1108-
_ = CloseExternalPreviewAsync();
1145+
if (ExternalPreviewVisible)
1146+
CloseExternalPreview();
11091147

11101148
if (!SelectedIsFromQueryResults())
11111149
{

0 commit comments

Comments
 (0)