Skip to content

Conversation

Jack251970
Copy link
Member

Fix Explorer preview panel issue

  • Fix many preview panel binding issue in Explorer plugin.
  • Add file name & file path in preview panel of Explorer plugin.
  • Use DataContext instead of RelativeResource for code quality.
  • Use ObservableProperty to generate dependency properties.

Test

Original:

image

with many binding issues

image

After:

image

@prlabeler prlabeler bot added the bug Something isn't working label Aug 17, 2025
@Jack251970 Jack251970 added this to the 2.0.0 milestone Aug 17, 2025
@Jack251970 Jack251970 added the kind/ui related to UI, icons, themes, etc label Aug 17, 2025
@Jack251970 Jack251970 requested a review from Copilot August 17, 2025 06:37
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes data binding issues in the Explorer plugin's preview panel by replacing RelativeSource bindings with direct DataContext bindings and refactoring property implementations. The changes improve code quality by using ObservableProperty attributes to generate dependency properties and add file name display alongside the existing file path.

  • Replace problematic RelativeSource bindings with DataContext bindings for better reliability
  • Refactor properties to use ObservableProperty attributes for automatic dependency property generation
  • Add FileName property to display just the file name in addition to the full file path

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
PreviewPanel.xaml.cs Refactored properties to use ObservableProperty attributes and added FileName property
PreviewPanel.xaml Updated bindings to use DataContext instead of RelativeSource and set explicit binding modes

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link

gitstream-cm bot commented Aug 17, 2025

🥷 Code experts: onesounds

Jack251970 has most 👩‍💻 activity in the files.
Jack251970, onesounds have most 🧠 knowledge in the files.

See details

Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml

Activity based on git-commit:

Jack251970
AUG
JUL
JUN 71 additions & 76 deletions
MAY
APR
MAR

Knowledge based on git-blame:
Jack251970: 43%
onesounds: 41%

Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs

Activity based on git-commit:

Jack251970
AUG
JUL
JUN 297 additions & 96 deletions
MAY 13 additions & 9 deletions
APR 1 additions & 2 deletions
MAR

Knowledge based on git-blame:
Jack251970: 74%

✨ Comment /gs review for LinearB AI review. Learn how to automate it here.

Copy link

gitstream-cm bot commented Aug 17, 2025

Be a legend 🏆 by adding a before and after screenshot of the changes you made, especially if they are around UI/UX.

@Jack251970 Jack251970 requested a review from onesounds August 17, 2025 06:39
Copy link
Contributor

coderabbitai bot commented Aug 17, 2025

📝 Walkthrough

Walkthrough

Bindings in PreviewPanel.xaml were reworked to bind directly to the control (Self) and its local properties. Ancestor-based bindings and triggers were removed or replaced. PreviewPanel.xaml.cs switched to MVVM Toolkit [ObservableProperty] for several properties, added FileName, and adjusted initialization order in the constructor.

Changes

Cohort / File(s) Summary
XAML bindings refactor
Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
DataContext bound to Self; image binding simplified (fixed 96 size, OneWay IsAsync source); title/subtitle now bind to FileName/FilePath (OneTime); removed ancestor-based bindings; visibility and metadata bindings switched to direct local properties with OneTime/OneWay; updated MultiDataTrigger to use local visibility properties.
Property model and init adjustments
Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
Introduced MVVM Toolkit [ObservableProperty] for FileSize, CreatedAt, LastModifiedAt, PreviewImage (now public settable); added FileName; reorganized constructor to compute FileName before InitializeComponent; retained LoadImageAsync updating PreviewImage.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • onesounds
  • taooceros

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch explorer_preview_panel

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (2)
Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs (2)

66-81: Cross-thread UI updates: FileSize set from a background thread

Inside Task.Run you mutate a property on this UserControl (a DispatcherObject), and also call OnPropertyChanged from a background thread. This is unsafe in WPF and can intermittently throw cross-thread exceptions. The ConfigureAwait(false) on a non-awaited Task here is also a no-op, and OnPropertyChanged is redundant because [ObservableProperty] setters already raise notifications.

Apply this diff to marshal the assignment to the UI thread and remove the redundant notification:

-                _ = Task.Run(() =>
-                {
-                    FileSize = GetFolderSize(filePath);
-                    OnPropertyChanged(nameof(FileSize));
-                }).ConfigureAwait(false);
+                _ = Task.Run(() =>
+                {
+                    var size = GetFolderSize(filePath);
+                    Dispatcher.Invoke(() => FileSize = size);
+                });

99-103: Avoid ConfigureAwait(false) when updating UI-bound properties

The continuation after await runs off the UI thread due to ConfigureAwait(false), then assigns PreviewImage on a background thread, which is unsafe for WPF and ImageSource. Let the continuation resume on the UI thread (or explicitly dispatch).

Apply this diff:

-        PreviewImage = await Main.Context.API.LoadImageAsync(FilePath, true).ConfigureAwait(false);
+        PreviewImage = await Main.Context.API.LoadImageAsync(FilePath, true);

Alternatively, if you prefer keeping ConfigureAwait(false), dispatch the assignment:

var img = await Main.Context.API.LoadImageAsync(FilePath, true).ConfigureAwait(false);
await Dispatcher.InvokeAsync(() => PreviewImage = img);
🧹 Nitpick comments (2)
Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml (1)

73-73: Consider making FileInfoVisibility reactive to settings changes

Binding uses Mode=OneTime and FileInfoVisibility doesn't raise PropertyChanged. If users toggle preview settings at runtime, the existing panel won't update. If that's intended, ignore. Otherwise, emit change notifications (and use OneWay here).

Would you like me to wire Settings.PropertyChanged to raise PropertyChanged for FileInfoVisibility, FileSizeVisibility, CreatedAtVisibility, and LastModifiedAtVisibility so these update live?

Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs (1)

62-63: Handle trailing directory separators when computing FileName

Path.GetFileName returns empty when the path ends with a separator (e.g., “C:\” or “C:\Folder\”). Trim separators first to avoid an empty title for root or folder paths.

Apply this diff:

-        FileName = Path.GetFileName(filePath);
+        FileName = Path.GetFileName(filePath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4b41578 and 6751942.

📒 Files selected for processing (2)
  • Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml (7 hunks)
  • Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-24T19:06:48.344Z
Learnt from: Koisu-unavailable
PR: Flow-Launcher/Flow.Launcher#3770
File: Flow.Launcher/ViewModel/MainViewModel.cs:0-0
Timestamp: 2025-06-24T19:06:48.344Z
Learning: In Flow.Launcher's Explorer plugin results, the SubTitle property always contains the directory containing the file. For file results, Title contains the filename and SubTitle contains the parent directory. For directory results, SubTitle contains the directory path itself.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
🧬 Code Graph Analysis (1)
Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs (1)
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs (1)
  • Settings (13-208)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: gitStream workflow automation
  • GitHub Check: gitStream.cm
  • GitHub Check: gitStream.cm
  • GitHub Check: gitStream.cm
  • GitHub Check: build
🔇 Additional comments (4)
Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml (4)

10-10: Good switch to DataContext=Self to simplify bindings

Binding to Self removes fragile ancestor bindings and matches the new code-behind property model.


34-36: Title now correctly binds to FileName (one-time)

One-time binding is appropriate since FileName is immutable per instance.


48-51: Subtitle binding to FilePath looks good (one-time)

Matches PR intent to surface the path and is stable for the control's lifetime.


63-66: Separator visibility trigger logic reads cleanly

Hiding the separator when all info sections are collapsed is correct and removes ancestor coupling.

@Jack251970 Jack251970 merged commit ebdea4f into dev Aug 17, 2025
17 checks passed
@Jack251970 Jack251970 deleted the explorer_preview_panel branch August 17, 2025 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working kind/ui related to UI, icons, themes, etc
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants