Skip to content
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

Add Blazor support to Consolonia. #164

Merged
merged 26 commits into from
Dec 8, 2024
Merged

Add Blazor support to Consolonia. #164

merged 26 commits into from
Dec 8, 2024

Conversation

tomlm
Copy link
Collaborator

@tomlm tomlm commented Dec 3, 2024

TLDR

Details

  • Added Consolonia.Blazor library which makes it so you can call **AppBuilder.UseConsoloniaBlazor() **
  • Added Example.Blazor project which is consolonia app hosting of blazor components
  • Added Example.Blazor.Components project which implements MainPage.razor and SubPage.razor

Example Razor file

Things to note:

  • Method binding to code behind
  • Conditional layout of elements
  • Full intellisense for renaming going to code behind autocomplete etc.
  • injection of INavigation so you can push and pop views off of the nav stack
  • injection of IClassicDesktopStyleApplicationLifetime so you can access Args and shutdown the app.
  • HOT RELOAD. simple save the file and your view gets rebuilt and rerendered!

blazor

@page "/"
@inject INavigation navigation
@inject IClassicDesktopStyleApplicationLifetime lifetime

@namespace Example.Blazor.Components

<Window Title="Blazor Bindings for Consolonia" Topmost="true">
     <StackPanel Orientation="Orientation.Vertical" VerticalAlignment="VerticalAlignment.Center">
        @if (showCounter)
        {
            <TextBlock HorizontalAlignment="HorizontalAlignment.Center">Counter: @CounterText</TextBlock>
        }
        <StackPanel Orientation="Orientation.Vertical" HorizontalAlignment="HorizontalAlignment.Center" Margin="@Thickness.Parse("4")">
            <Button OnClick="@OnIncrement">Increment counter support</Button>
            <Button OnClick="@OnToggleCounter">@ToggleText</Button>
            <Button OnClick="@OnMessageBox">Message Box</Button>
            <Button OnClick="@OnGotoSubPage">Go to SubPage</Button>
            <Button OnClick="@OnExit">Exit</Button>
        </StackPanel>
    </StackPanel> 
</Window>

@code {
    int counter = 0;
    bool showCounter = true;

    string CounterText => counter switch
    {
        0 => "Not clicked",
        1 => $"Clicked 1 time",
        _ => $"Clicked {counter} times"
    };

    string ToggleText => showCounter ? "Hide Counter" : "Show Counter";

    void OnIncrement()
        => counter++;

    void OnToggleCounter()
        => showCounter = !showCounter;

    void OnGotoSubPage()
        => navigation.PushAsync<SubPage>();

    async void OnMessageBox(RoutedEventArgs args)
    {
        await new MessageBox()
            .ShowDialogAsync((AC.Control)args.Source!, "Hello, Blazor!", "Blazor Bindings for Consolonia");
    }

    void OnExit()
       => lifetime.Shutdown();
}

tomlm added 6 commits December 2, 2024 12:08
* added example.blazor project
* added example.blazor.components project
* bumped .net version to 8.0 due to AvaloniaBlazorBindings projectdependency needing it
* cleaned up project package dependencies to prepare publishing package dependencies.
* tied consolonia package version to avalonia major/minor version since we depend on undocumented interfaces.
Copy link
Contributor

coderabbitai bot commented Dec 3, 2024

Warning

Rate limit exceeded

@tomlm has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 14 minutes and 38 seconds before requesting another review.

βŒ› How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between caf0951 and b4c31e6.

πŸ“ Walkthrough
πŸ“ Walkthrough
πŸ“ Walkthrough
πŸ“ Walkthrough
πŸ“ Walkthrough

Walkthrough

The pull request includes several updates across multiple files primarily focused on upgrading the .NET version and enhancing the integration of the Consolonia framework with Blazor. The .NET version in the workflow files .github/workflows/editorconfig.yml and .github/workflows/general_build.yml has been updated from 6.0.x to 8.0.x, reflecting a shift to a newer SDK. The Directory.Build.props file has been modified to target net8.0 and update version prefixes and Avalonia versions. A new project for a Blazor application has been added, along with a corresponding project file and several components for managing user interactions. Additionally, new methods for design mode support and improved error handling in native library bindings have been introduced. Other changes include the removal of certain project references and configuration files, indicating a restructuring of dependencies and settings. The overall changes aim to modernize the project setup and enhance functionality within the Consolonia framework.

Possibly related PRs

Suggested reviewers

  • jinek
  • goe5mu

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❀️ 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.
    • Generate unit testing code for this file.
    • 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. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

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

Documentation and Community

  • 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: 6

🧹 Outside diff range and nitpick comments (12)
src/Example.Blazor/App.axaml.cs (1)

6-8: Consider adding XML documentation.

Adding XML documentation would improve IntelliSense support and make the purpose of this class clearer to other developers.

+    /// <summary>
+    /// Main application class for the Blazor example project.
+    /// Serves as the entry point and hosts the MainPage component.
+    /// </summary>
     public class App : ConsoloniaBlazorApplication<MainPage>
     {
     }
src/Example.Blazor/Program.cs (1)

11-11: Consider improving or removing the ReSharper comment.

The current comment doesn't clearly explain why the parameter needs to be kept. Consider either removing it (since args is a standard parameter for Main) or providing a more descriptive explanation.

-        // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local Exactly why we are keeping it here
+        // args parameter is required for console lifetime management and command-line argument processing
src/Example.Blazor.Components/SubPage.razor (1)

7-13: Consider simplifying the UI structure

A few suggestions for the UI:

  1. The ScrollViewer might be unnecessary for this simple content. Consider removing it unless you're expecting dynamic content growth.
  2. The blue text color seems arbitrary. Consider using theme colors or documenting the purpose of this specific styling.
-<ScrollViewer>
    <StackPanel HorizontalAlignment="HorizontalAlignment.Center"
                VerticalAlignment="VerticalAlignment.Center">
        <Button OnClick="Back">Back</Button>
-        <TextBlock Text="This a second page." Foreground="Brushes.Blue"></TextBlock>
+        <TextBlock Text="This a second page."></TextBlock>
    </StackPanel>
-</ScrollViewer>
Directory.Build.props (1)

11-11: Update the copyright year

The copyright notice shows "2021 - 2022" but should be updated to include 2024.

-        <Copyright>Copyright Β© Evgeny Gorbovoy 2021 - 2022</Copyright>
+        <Copyright>Copyright Β© Evgeny Gorbovoy 2021 - 2024</Copyright>
src/Consolonia.Themes.TurboVision/Themes/Material/MaterialTheme.cs (1)

10-12: Eliminate URI duplication

The same URI string is duplicated between the constructor and the Uri property. Consider using a private constant.

 public class MaterialTheme : ResourceIncludeBase
 {
+    private const string ThemeUri = "avares://Consolonia.Themes.TurboVision/Themes/Material/Material.axaml";
-    public MaterialTheme() : base(new Uri("avares://Consolonia.Themes.TurboVision/Themes/Material/Material.axaml"))
+    public MaterialTheme() : base(new Uri(ThemeUri))
     {
     }

     protected override Uri Uri =>
-        new("avares://Consolonia.Themes.TurboVision/Themes/Material/Material.axaml");
+        new(ThemeUri);
src/Consolonia.Blazor/ConsoloniaBlazorApplication.cs (1)

22-24: Consider using singleton for keyboard navigation handler

The ArrowsAndKeyboardNavigationHandler is registered with a transient lifetime, which means a new instance will be created each time it's requested. Since this handler typically maintains application-wide state and doesn't need to be recreated, consider using a singleton lifetime instead.

-            AvaloniaLocator.CurrentMutable.Bind<IKeyboardNavigationHandler>()
-                .ToTransient<ArrowsAndKeyboardNavigationHandler>();
+            AvaloniaLocator.CurrentMutable.Bind<IKeyboardNavigationHandler>()
+                .ToSingleton<ArrowsAndKeyboardNavigationHandler>();
src/Example.Blazor.Components/MainPage.razor (2)

42-44: Consider more flexible navigation approach

The navigation to SubPage is hardcoded, which makes the component less reusable and harder to test. Consider passing the target page type as a parameter or using a route-based approach.

+    [Parameter]
+    public Type? TargetPage { get; set; } = typeof(SubPage);
+
     void OnGotoSubPage()
-        => navigation.PushAsync<SubPage>();
+        => navigation.PushAsync(TargetPage ?? typeof(SubPage));

13-19: Add keyboard shortcuts for common actions

Consider adding keyboard shortcuts for frequently used actions to improve accessibility and user experience.

     <StackPanel Orientation="Orientation.Vertical" HorizontalAlignment="HorizontalAlignment.Center" Margin="@Thickness.Parse("4")">
-        <Button OnClick="@OnIncrement">Increment counter support</Button>
-        <Button OnClick="@OnToggleCounter">@ToggleText</Button>
-        <Button OnClick="@OnMessageBox">Message Box</Button>
-        <Button OnClick="@OnGotoSubPage">Go to SubPage</Button>
-        <Button OnClick="@OnExit">Exit</Button>
+        <Button OnClick="@OnIncrement" HotKey="Ctrl+I">Increment counter support (Ctrl+I)</Button>
+        <Button OnClick="@OnToggleCounter" HotKey="Ctrl+T">@ToggleText (Ctrl+T)</Button>
+        <Button OnClick="@OnMessageBox" HotKey="Ctrl+M">Message Box (Ctrl+M)</Button>
+        <Button OnClick="@OnGotoSubPage" HotKey="Ctrl+G">Go to SubPage (Ctrl+G)</Button>
+        <Button OnClick="@OnExit" HotKey="Alt+F4">Exit (Alt+F4)</Button>
     </StackPanel>
src/Consolonia.Blazor/BuilderExtensions.cs (2)

12-18: Enhance XML documentation

The XML documentation is incomplete. Consider adding:

  • Description for configureServices parameter
  • Return value documentation
  • Example usage
 /// <summary>
-/// Use Consolonize in Blazor mode
+/// Configures the application to use Consolonia in Blazor mode
 /// </summary>
 /// <param name="builder"></param>
-/// <param name="configureServices"></param>
+/// <param name="configureServices">Optional delegate to configure additional services</param>
+/// <returns>The configured AppBuilder instance</returns>
+/// <example>
+/// <code>
+/// var builder = AppBuilder.Configure<App>()
+///     .UseConsoloniaBlazor(services => 
+///     {
+///         services.AddSingleton<IMyService, MyService>();
+///     });
+/// </code>
+/// </example>

35-38: Consider using C# 8.0 null-coalescing assignment

The null check can be simplified using modern C# features.

-if (configureServices != null)
-{
-    configureServices(sc);
-}
+configureServices?.Invoke(sc);
src/Consolonia.Core/Helpers/Extensions.cs (2)

44-44: Consider extracting magic numbers as constants

The font size value (16.0) should be defined as a constant for better maintainability.

+private const double DefaultDesignModeFontSize = 16.0;
+
 // In the style setter
-new Setter(TemplatedControl.FontSizeProperty, 16.0),
+new Setter(TemplatedControl.FontSizeProperty, DefaultDesignModeFontSize),

51-63: Remove commented experimental code

The experimental code should be removed or moved to a separate branch/issue if it needs to be preserved for future reference.

-                // EXPERIMENTAL
-                // If you do RenderTRansform="scale(10.0,10.0) you can actually sort of see the UI get bigger
-                // but this doesn' seem to work when using these style setters. <sigh>
-                //this.Styles.Add(new Style(x => x.Is<Visual>())
-                //{
-                //    Setters =
-                //    {
-                //        //new Setter(Visual.RenderTransformOriginProperty, RelativePoint.TopLeft),
-                //        //new Setter(Visual.RenderTransformProperty, new ScaleTransform(2.0, 2.0)),
-                //        //new Setter(Visual.RenderTransformProperty, new ScaleTransform(2.0, 2.0)),
-                //    }
-                //});
πŸ“œ Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 64bbfce and ff0fb7d.

πŸ“’ Files selected for processing (25)
  • .github/workflows/editorconfig.yml (1 hunks)
  • .github/workflows/general_build.yml (1 hunks)
  • Directory.Build.props (1 hunks)
  • src/Consolonia.Blazor/BuilderExtensions.cs (1 hunks)
  • src/Consolonia.Blazor/Consolonia.Blazor.csproj (1 hunks)
  • src/Consolonia.Blazor/ConsoloniaBlazorApplication.cs (1 hunks)
  • src/Consolonia.Core/Helpers/Extensions.cs (2 hunks)
  • src/Consolonia.Core/Infrastructure/ConsoloniaApplication.cs (2 hunks)
  • src/Consolonia.Core/Infrastructure/ConsoloniaException.cs (0 hunks)
  • src/Consolonia.Core/Infrastructure/ConsoloniaNotSupportedException.cs (0 hunks)
  • src/Consolonia.Designer/Consolonia.Designer.csproj (1 hunks)
  • src/Consolonia.GuiCS/binding.cs (2 hunks)
  • src/Consolonia.NUnit/Consolonia.NUnit.csproj (1 hunks)
  • src/Consolonia.PlatformSupport/Consolonia.PlatformSupport.csproj (1 hunks)
  • src/Consolonia.Themes.TurboVision/Consolonia.Themes.TurboVision.csproj (1 hunks)
  • src/Consolonia.Themes.TurboVision/Themes/Material/MaterialTheme.cs (1 hunks)
  • src/Consolonia.sln (2 hunks)
  • src/Example.Blazor.Components/Example.Blazor.Components.csproj (1 hunks)
  • src/Example.Blazor.Components/MainPage.razor (1 hunks)
  • src/Example.Blazor.Components/SubPage.razor (1 hunks)
  • src/Example.Blazor.Components/_Imports.razor (1 hunks)
  • src/Example.Blazor/App.axaml (1 hunks)
  • src/Example.Blazor/App.axaml.cs (1 hunks)
  • src/Example.Blazor/Example.Blazor.csproj (1 hunks)
  • src/Example.Blazor/Program.cs (1 hunks)
πŸ’€ Files with no reviewable changes (2)
  • src/Consolonia.Core/Infrastructure/ConsoloniaException.cs
  • src/Consolonia.Core/Infrastructure/ConsoloniaNotSupportedException.cs
βœ… Files skipped from review due to trivial changes (4)
  • src/Example.Blazor.Components/Example.Blazor.Components.csproj
  • src/Example.Blazor/Example.Blazor.csproj
  • src/Example.Blazor/App.axaml
  • src/Example.Blazor.Components/_Imports.razor
🧰 Additional context used
πŸ““ Learnings (1)
src/Consolonia.Designer/Consolonia.Designer.csproj (1)
Learnt from: tomlm
PR: jinek/Consolonia#150
File: src/Consolonia.Designer/Consolonia.Designer.csproj:14-15
Timestamp: 2024-11-19T07:19:33.261Z
Learning: In the Consolonia project, circular dependencies between `Consolonia.Designer` and `Consolonia.PreviewHost` are intentional and by design. The `ConsolePreview` control consumes `Consolonia.PreviewHost`, and `Avalonia.PreviewHost` consumes `ConsolePreview` control in the designer.
πŸ”‡ Additional comments (18)
src/Example.Blazor/App.axaml.cs (1)

1-9: LGTM! Clean and focused implementation.

The class follows good practices by inheriting from ConsoloniaBlazorApplication<MainPage> and maintains a minimal, focused implementation that serves as the application entry point.

src/Example.Blazor/Program.cs (3)

1-6: LGTM! Imports are well-organized and necessary.

The imports provide all required dependencies for Avalonia UI framework and Consolonia's Blazor integration.


9-17: LGTM! Proper setup for a Consolonia Blazor application.

The Main method correctly implements the standard Avalonia application startup pattern with console lifetime management. The [STAThread] attribute is appropriately used for Windows compatibility.


19-24: Verify exception logging configuration for production use.

The LogToException() call might expose sensitive information in production environments. Consider making this configurable based on the environment.

Consider implementing environment-specific logging configuration:

#if DEBUG
            .LogToException()
#else
            .LogToCustomProvider() // Production logging configuration
#endif
src/Consolonia.NUnit/Consolonia.NUnit.csproj (1)

10-10: ⚠️ Potential issue

Remove circular dependency between package and project references

Same issue as in Consolonia.Themes.TurboVision.csproj - circular dependency between package and project references.

src/Example.Blazor.Components/SubPage.razor (1)

16-19: LGTM! Navigation implementation looks good

The Back method correctly implements async/await pattern and uses the injected navigation service appropriately.

src/Consolonia.Core/Infrastructure/ConsoloniaApplication.cs (2)

3-3: LGTM: Clean dependency management

Good job removing unnecessary Avalonia-specific imports and adding only the required helper namespace.


21-21: Verify the AddConsoloniaDesignMode implementation

The design mode initialization has been nicely encapsulated into an extension method. However, we should verify its implementation to ensure it handles all the previous functionality.

βœ… Verification successful

Design mode implementation is properly handled

The AddConsoloniaDesignMode implementation in src/Consolonia.Core/Helpers/Extensions.cs correctly handles the design mode functionality by:

  • Setting up default theme colors (foreground/background) for Visual Studio designer preview
  • Using theme-aware brushes when available through resource lookup
  • Working in conjunction with other design mode checks in the codebase:
    • Using a dummy console in platform support
    • Configuring appropriate platform detection in designer mode
    • Handling preview buffer rendering

The implementation maintains all necessary design mode functionality while being properly encapsulated in an extension method.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the implementation of AddConsoloniaDesignMode
ast-grep --pattern 'public static void AddConsoloniaDesignMode(this Application $_) {
  $$$
}'

# Look for any design mode related code that might have been missed
rg -l "Design.IsDesignMode"

Length of output: 306


Script:

#!/bin/bash
# Let's check the implementation in PlatformSupportExtensions.cs
ast-grep --pattern 'AddConsoloniaDesignMode' src/Consolonia.PlatformSupport/PlatformSupportExtensions.cs

# Check design mode related code in all files
rg "Design.IsDesignMode" -A 5 src/Consolonia.PlatformSupport/PlatformSupportExtensions.cs
rg "Design.IsDesignMode" -A 5 src/Consolonia.Core/Helpers/Extensions.cs
rg "Design.IsDesignMode" -A 5 src/Consolonia.Designer/Extensions.cs
rg "Design.IsDesignMode" -A 5 src/Consolonia.Designer/ConsolePreview.cs

Length of output: 1668


Script:

#!/bin/bash
# Let's check the actual implementation of AddConsoloniaDesignMode method
rg -A 10 "public static.*AddConsoloniaDesignMode" src/Consolonia.PlatformSupport/PlatformSupportExtensions.cs

# Also check if there are any other design mode related methods that might be relevant
ast-grep --pattern 'public static $_ $_DesignMode($_) {
  $$$
}'

Length of output: 178


Script:

#!/bin/bash
# Let's try a different approach to find the AddConsoloniaDesignMode implementation
rg -A 15 "AddConsoloniaDesignMode" --type cs

# Also check for any design mode setup methods
rg -A 10 "DesignMode" --type cs

Length of output: 8216

Directory.Build.props (1)

4-4: Verify .NET 8 compatibility across the solution

The upgrade from .NET 6 to .NET 8 is a major change. Ensure all dependencies and features are compatible with .NET 8.

βœ… Verification successful

No .NET 6 references found, upgrade to .NET 8 appears clean

The verification shows that:

  • No files contain references to net6.0 or netcoreapp6.0
  • All project files consistently use .NET 8 target framework
  • All dependencies appear to be compatible with .NET 8:
    • Avalonia packages are using version 11.2.1 (via AvaloniaVersion property)
    • Consolonia packages are at version 11.2
    • Other packages (CommunityToolkit.Mvvm, Newtonsoft.Json) are at recent versions known to work with .NET 8
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any .NET version references that might need updating
rg -l "net6\.0|netcoreapp6\.0"

# Look for potential compatibility issues in project files
fd -e csproj -x cat {} \; | grep -i "TargetFramework\|RuntimeIdentifier\|Version"

Length of output: 4945

src/Consolonia.Blazor/Consolonia.Blazor.csproj (2)

12-12: Verify the stability of BlazorBindingsAvalonia version 0.1.2

The version 0.1.2 appears to be an early release. This could pose stability risks in a production environment.

Consider:

  1. Documenting any known limitations or issues
  2. Adding fallback mechanisms for potential instability
  3. Setting up monitoring for Blazor-related issues
βœ… Verification successful

BlazorBindingsAvalonia 0.1.2 is appropriately integrated and actively used

The package is properly integrated into the project with consistent usage patterns:

  • Used in Example.Blazor.Components for UI components
  • Integrated in ConsoloniaBlazorApplication.cs and BuilderExtensions.cs
  • Released recently (November 2024) which aligns with the project's timeline
  • The version is consistent with the project's "proof of concept" state mentioned in README.md
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check package info and release history
curl -s https://api.nuget.org/v3/registration5-semver1/blazorbindingsavalonia/index.json | jq '.items[0].items[].catalogEntry | {version, published}'

# Check GitHub issues/discussions for known stability issues
gh api graphql -f query='
{
  repository(owner: "jinek", name: "Consolonia") {
    discussions(first: 10, categoryId: "DIC_kwDOGM5jE84COYYl") {
      nodes {
        title
        body
      }
    }
  }
}'

Length of output: 728


Script:

#!/bin/bash
# Let's check for any direct dependencies on BlazorBindingsAvalonia in the codebase
rg -l "BlazorBindingsAvalonia" --type-add 'proj:*.{csproj,props,targets}' -t proj

# Check if there are any usage patterns or configurations
rg "BlazorBindingsAvalonia" -A 3 -B 3

# Look for any Blazor-related configurations or setups
ast-grep --pattern 'services.AddBlazor$$$'

# Check for any documentation about Blazor integration
fd README.md --exec cat {}

Length of output: 3142


10-13: Verify version compatibility between Avalonia and BlazorBindingsAvalonia

Ensure that the Avalonia version (referenced via variable) is compatible with BlazorBindingsAvalonia 0.1.2.

src/Consolonia.Themes.TurboVision/Themes/Material/MaterialTheme.cs (1)

10-12: Verify theme resource loading in Blazor context

The new parameterless constructor suggests Blazor integration. Ensure the theme resources load correctly in a Blazor environment.

βœ… Verification successful

Let me gather more information about the theme handling and Blazor integration.


Let me check one more aspect about theme loading and resource handling.


Theme resource loading appears standard and compatible with both Blazor and non-Blazor contexts

The parameterless constructor follows the standard Avalonia theme initialization pattern using avares:// URI scheme, which is compatible across different hosting scenarios including Blazor. The Material.axaml file exists at the correct location and follows the standard Avalonia styling structure with proper resource inclusions. No Blazor-specific theme handling is required as the resource loading mechanism is uniform across platforms.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the theme AXAML file exists and is accessible
fd -t f "Material.axaml$"

# Look for any Blazor-specific theme handling
ast-grep --pattern 'class $_ : ResourceIncludeBase {
  $$$
  public $_() {
    $$$
  }
}'

Length of output: 184


Script:

#!/bin/bash
# Check for Blazor-specific configurations or theme handling
rg -l "blazor|Blazor" --type cs

# Check the content of Material.axaml to understand resource structure
cat src/Consolonia.Themes.TurboVision/Themes/Material/Material.axaml

# Look for other theme implementations for comparison
ast-grep --pattern 'class $_ : Theme {
  $$$
}'

Length of output: 913


Script:

#!/bin/bash
# Check how themes are loaded in Blazor context
rg -A 5 "ConsoloniaBlazorApplication" src/Consolonia.Blazor/ConsoloniaBlazorApplication.cs

# Check if there are any special theme loading mechanisms
rg -l "Uri.*avares://" --type cs

# Look for theme registration or initialization
ast-grep --pattern 'UseTheme<$_>($$$)'

Length of output: 563

.github/workflows/general_build.yml (1)

25-25: Verify comprehensive .NET 8 upgrade across the solution

The workflow now uses .NET 8, which requires verification of:

  1. All project files targeting .NET 8
  2. Package compatibility with .NET 8
  3. Breaking changes impact

Consider:

  1. Documenting any breaking changes
  2. Adding migration guides if needed
  3. Updating development environment requirements
βœ… Verification successful

The previous results show that there are multiple project files but we need to verify their target frameworks. Let's check if all projects are properly configured for .NET 8 and if there are any legacy framework references remaining.


βœ… .NET 8 upgrade appears to be properly implemented

The verification shows that:

  • All detected project files are targeting .NET 8.0
  • No references to older .NET versions (6.0 or 7.0) were found
  • No compatibility issues or obsolete API usage were detected
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check target framework in all project files
fd -e csproj | xargs grep -l "TargetFramework"

# Look for potential compatibility issues in package references
fd -e csproj | xargs grep -l "PackageReference"

# Check for obsolete API usage
ast-grep --pattern '[Obsolete]
$$$'

Length of output: 988


Script:

#!/bin/bash
# Check target framework versions in project files
fd -e csproj | xargs cat | grep -A 1 "TargetFramework"

# Check .NET SDK version in global.json if exists
fd global.json | xargs cat

# Look for any direct references to net6.0 or net7.0
rg "net[67]\.0" -A 2 -B 2

Length of output: 298

src/Consolonia.Blazor/ConsoloniaBlazorApplication.cs (1)

11-32: LGTM! Well-structured Blazor integration

The implementation provides a clean base class for Blazor integration with proper inheritance, service registration, and framework initialization. The XML documentation clearly explains the purpose of the class.

.github/workflows/editorconfig.yml (1)

30-30: Verify tool compatibility with .NET 8.0

The upgrade to .NET 8.0 looks good. However, ensure that all tools in the workflow, particularly the ReSharper CLI tools, are compatible with .NET 8.0.

βœ… Verification successful

Tools are compatible with .NET 8.0

Based on the documentation and workflow files, the tools being used are fully compatible with .NET 8.0:

  • The ReSharper CLI action (muno92/[email protected]) explicitly lists .NET 8.0.x as a supported version in its documentation
  • The workflow is using ReSharper version 2024.2.6, which is a recent version that supports .NET 8
  • The JetBrains.ReSharper.GlobalTools package being installed is compatible with all supported .NET versions
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if workflow tools support .NET 8

# Check if ReSharper version supports .NET 8
gh api graphql -f query='
{
  repository(owner: "JetBrains", name: "resharper-dotnet") {
    releases(first: 1, orderBy: {field: CREATED_AT, direction: DESC}) {
      nodes {
        name
        description
      }
    }
  }
}'

Length of output: 520


Script:

#!/bin/bash
# Let's check the workflow file to see what ReSharper tools are being used
cat .github/workflows/editorconfig.yml

# Also check if there are any other .NET-related workflows that might provide context
fd -e yml -e yaml . .github/workflows --exec cat {}

Length of output: 5646


Script:

#!/bin/bash
# Let's check the specific ReSharper tool version being used
curl -s https://api.github.com/repos/muno92/resharper_inspectcode/releases/tags/1.12.0 | jq -r '.body'

# Also check the marketplace page for this action
curl -s https://raw.githubusercontent.com/muno92/resharper_inspectcode/1.12.0/README.md

Length of output: 4689

src/Consolonia.sln (2)

64-68: LGTM: New Blazor projects follow a clean architecture.

The addition of three new projects demonstrates a well-structured approach:

  • Consolonia.Blazor: Core library for Blazor integration
  • Example.Blazor: Demo application
  • Example.Blazor.Components: Reusable components library

62-63: Verify SDK-style project upgrade for Consolonia.Designer.

The project type GUID has been changed from FAE04EC0-301F-11D3-BF4B-00C04F79EFBC to 9A19103F-16F7-4668-BE54-9A1E7A4F7556, indicating an upgrade to the SDK-style project format.

Run the following script to verify the project file format:

βœ… Verification successful

Project successfully upgraded to SDK-style format

The verification confirms that Consolonia.Designer.csproj is using the modern SDK-style project format with <Project Sdk="Microsoft.NET.Sdk"> declaration, which aligns with the project type GUID change in the solution file.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that Consolonia.Designer.csproj uses the SDK-style format

# Check if the project file uses SDK-style format
cat src/Consolonia.Designer/Consolonia.Designer.csproj | grep -E '<Project Sdk="Microsoft\.NET\.Sdk'

Length of output: 136

src/Consolonia.GuiCS/binding.cs (1)

332-333: LGTM: Improved delegate declaration formatting.

The formatting changes to endwin and isendwin delegate declarations improve code readability while maintaining functionality.

src/Consolonia.Designer/Consolonia.Designer.csproj Outdated Show resolved Hide resolved
src/Example.Blazor.Components/MainPage.razor Show resolved Hide resolved
src/Consolonia.Blazor/BuilderExtensions.cs Outdated Show resolved Hide resolved
src/Consolonia.Core/Helpers/Extensions.cs Show resolved Hide resolved
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.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (3)
src/Consolonia.Blazor/BuilderExtensions.cs (3)

12-18: Enhance XML documentation for better developer experience

The current documentation could be more comprehensive. Consider adding:

  • Detailed description of the method's purpose and behavior
  • Parameter descriptions explaining the role of configureServices
  • Return value documentation
  • Example usage
 /// <summary>
-/// Use Consolonize in Blazor mode
+/// Configures the application to use Consolonia with Blazor integration.
+/// This sets up necessary services and bindings for Blazor functionality.
 /// </summary>
 /// <param name="builder"></param>
 /// <param name="configureServices"></param>
+/// <param name="builder">The application builder to configure</param>
+/// <param name="configureServices">Optional callback to configure additional services in the DI container</param>
 /// <returns></returns>
+/// <returns>The configured application builder</returns>
+/// <example>
+/// <code>
+/// var builder = AppBuilder.Configure<App>()
+///     .UseConsoloniaBlazor(services => 
+///     {
+///         services.AddSingleton<IMyService, MyService>();
+///     });
+/// </code>
+/// </example>

25-30: Consider documenting lifetime requirements

The lifetime registration assumes the application lifetime will be available, but this might not always be true during the application startup sequence.

Consider:

  1. Documenting when this method should be called in the application lifecycle
  2. Adding validation for the Application.Current state
  3. Including more descriptive error messages in the ArgumentNullException

31-38: Review service registration lifetimes

All window-related services are registered as transient, which might not be optimal for all cases.

Consider:

  1. Using singleton for services that don't change during the application lifetime (e.g., PlatformSettings)
  2. Using scoped registration for services that should be shared within a context
  3. Documenting the rationale for choosing transient lifetime for these services
πŸ›‘ Comments failed to post (0)

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: 0

🧹 Outside diff range and nitpick comments (4)
src/Consolonia.Blazor/BuilderExtensions.cs (4)

12-17: Enhance XML documentation for better developer experience.

The current documentation could be more comprehensive. Consider adding:

  • Detailed description of what "Blazor mode" enables
  • Parameter documentation explaining the purpose of configureServices
  • Return value documentation
 /// <summary>
-    Use Consolonize in Blazor mode
+    Enables Blazor support in Consolonia, allowing the use of Razor components
+    and providing integration with Avalonia's desktop features.
 /// </summary>
 /// <param name="builder"></param>
+/// <param name="configureServices">Optional delegate to configure additional services
+/// in the dependency injection container.</param>
 /// <returns></returns>
+/// <returns>The configured AppBuilder instance for method chaining.</returns>

21-23: Document method call order dependency.

The order of UseConsolonia() before UseAvaloniaBlazorBindings() appears intentional. Consider adding a code comment explaining why this order is necessary to prevent future maintenance issues.

 return builder
+    // UseConsolonia must be called before UseAvaloniaBlazorBindings to ensure proper initialization
     .UseConsolonia()
     .UseAvaloniaBlazorBindings(sc =>

25-25: Fix typo in comment.

The comment contains a typo: "injectoin" should be "injection".

-    // Register services for injectoin
+    // Register services for injection

26-32: Improve lifetime service registration.

The current implementation of lifetime registration could be more robust.

Consider these improvements:

  1. Move the registration to a separate method for better readability
  2. Add more context in the exception message
-sc.AddSingleton(_ =>
-{
-    var lifetime =
-        (IClassicDesktopStyleApplicationLifetime)Application.Current?.ApplicationLifetime;
-    ArgumentNullException.ThrowIfNull(lifetime);
-    return lifetime;
-});
+sc.AddSingleton<IClassicDesktopStyleApplicationLifetime>(sp =>
+{
+    var app = Application.Current ?? 
+        throw new InvalidOperationException("Application.Current is null. Ensure this is called after application initialization.");
+    
+    if (app.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime lifetime)
+        throw new InvalidOperationException(
+            $"Expected IClassicDesktopStyleApplicationLifetime but got {app.ApplicationLifetime?.GetType().Name ?? "null"}");
+    
+    return lifetime;
+});
πŸ“œ Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 17ecbdd and 03f04b4.

πŸ“’ Files selected for processing (8)
  • src/Consolonia.Blazor/BuilderExtensions.cs (1 hunks)
  • src/Consolonia.Blazor/ConsoloniaBlazorApplication.cs (1 hunks)
  • src/Consolonia.Core/Helpers/Extensions.cs (2 hunks)
  • src/Example.Blazor.Components/MainPage.razor (1 hunks)
  • src/Example.Blazor.Components/SubPage.razor (1 hunks)
  • src/Example.Blazor.Components/_Imports.razor (1 hunks)
  • src/Example.Blazor/App.axaml (1 hunks)
  • src/Example.Blazor/Program.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/Example.Blazor/App.axaml
  • src/Example.Blazor.Components/SubPage.razor
  • src/Example.Blazor/Program.cs
  • src/Consolonia.Core/Helpers/Extensions.cs
  • src/Consolonia.Blazor/ConsoloniaBlazorApplication.cs
  • src/Example.Blazor.Components/MainPage.razor
  • src/Example.Blazor.Components/_Imports.razor
πŸ”‡ Additional comments (1)
src/Consolonia.Blazor/BuilderExtensions.cs (1)

33-48: ⚠️ Potential issue

Handle potential null reference exceptions for MainWindow access.

Multiple service registrations access MainWindow without proper null checking, which could lead to runtime issues.

Consider implementing a helper method to safely access window services:

+private static T GetWindowService<T>(IClassicDesktopStyleApplicationLifetime lifetime, Func<Window, T> serviceAccessor)
+    where T : class
+{
+    var window = lifetime.MainWindow ?? 
+        throw new InvalidOperationException("MainWindow is not available. Ensure the application is properly initialized.");
+    return serviceAccessor(window);
+}

 sc.AddTransient(sp =>
-    sp.GetRequiredService<IClassicDesktopStyleApplicationLifetime>().MainWindow?.StorageProvider);
+    GetWindowService(
+        sp.GetRequiredService<IClassicDesktopStyleApplicationLifetime>(),
+        window => window.StorageProvider));

@tomlm tomlm enabled auto-merge (squash) December 5, 2024 01:27
@tomlm tomlm requested a review from jinek December 5, 2024 19:27
Rest of package cleanup is in the Packages PR
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 and nitpick comments (2)
src/Consolonia.Designer/Extensions.cs (1)

22-27: LGTM: Clean separation of design mode and runtime behavior

The simplified logic improves maintainability by:

  • Removing conditional compilation
  • Providing clear separation between design-time and runtime behavior
  • Using proper method chaining for builder configuration

This change aligns well with the Blazor integration objectives while maintaining clean architecture.

Consider documenting the design mode behavior in the XML comments above the method, as it's a crucial architectural decision that affects both development and runtime behavior.

src/Tools/Consolonia.PreviewHost/App.axaml.cs (1)

Line range hint 103-134: Remove commented-out code

There's a significant block of commented-out code at the bottom of the file that appears to be unused. Since this PR introduces Blazor support and modernizes the codebase, this is a good opportunity to clean up technical debt.

Consider removing this commented-out code block. If this functionality needs to be preserved for reference, consider moving it to the PR or commit description instead.

πŸ“œ Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 03f04b4 and e965957.

πŸ“’ Files selected for processing (14)
  • .gitignore (1 hunks)
  • Directory.Build.props (1 hunks)
  • src/Consolonia.Blazor/Consolonia.Blazor.csproj (1 hunks)
  • src/Consolonia.Core/Infrastructure/ConsoloniaNotSupportedException.cs (0 hunks)
  • src/Consolonia.Designer/ConsolePreview.cs (0 hunks)
  • src/Consolonia.Designer/Consolonia.Designer.csproj (1 hunks)
  • src/Consolonia.Designer/Extensions.cs (1 hunks)
  • src/Consolonia.Gallery/Consolonia.Gallery.csproj (0 hunks)
  • src/Consolonia.Gallery/Program.cs (0 hunks)
  • src/Consolonia.PlatformSupport/Consolonia.PlatformSupport.csproj (1 hunks)
  • src/Example.Blazor.Components/Example.Blazor.Components.csproj (1 hunks)
  • src/Example.Blazor/Example.Blazor.csproj (1 hunks)
  • src/Tools/Consolonia.PreviewHost/App.axaml.cs (1 hunks)
  • src/Tools/Consolonia.PreviewHost/Properties/launchSettings.json (0 hunks)
πŸ’€ Files with no reviewable changes (5)
  • src/Tools/Consolonia.PreviewHost/Properties/launchSettings.json
  • src/Consolonia.Gallery/Consolonia.Gallery.csproj
  • src/Consolonia.Core/Infrastructure/ConsoloniaNotSupportedException.cs
  • src/Consolonia.Gallery/Program.cs
  • src/Consolonia.Designer/ConsolePreview.cs
βœ… Files skipped from review due to trivial changes (1)
  • .gitignore
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/Example.Blazor.Components/Example.Blazor.Components.csproj
  • src/Example.Blazor/Example.Blazor.csproj
  • Directory.Build.props
  • src/Consolonia.Blazor/Consolonia.Blazor.csproj
πŸ”‡ Additional comments (4)
src/Consolonia.Designer/Consolonia.Designer.csproj (2)

8-9: LGTM: Package references properly unconditional

The removal of conditional compilation for these Avalonia packages aligns with the modernization efforts and supports the new Blazor integration. This change simplifies the project structure and ensures consistent behavior across configurations.


15-15: LGTM: Project reference properly unconditional

The removal of the conditional project reference to Consolonia.PreviewHost aligns with the previous discussions and modern NuGet practices.

src/Consolonia.PlatformSupport/Consolonia.PlatformSupport.csproj (1)

Line range hint 4-7: Critical: Verify removal of core project references

The removal of references to Consolonia.Core and Consolonia.GuiCS projects seems concerning as these appear to be essential dependencies for the platform support project. This change could potentially break the build and functionality.

Let's verify if these dependencies are being provided through other means:

Please ensure that:

  1. The platform support functionality doesn't depend on these projects anymore, or
  2. These dependencies are being provided through an alternative mechanism, or
  3. This is an intentional change as part of the Blazor support addition (though this seems unlikely given the nature of these core dependencies)
src/Tools/Consolonia.PreviewHost/App.axaml.cs (1)

Line range hint 55-65: Consider adding Blazor file support

The current code only handles .axaml files explicitly. Since this PR adds Blazor support, consider extending the file type handling to include .razor files as well.

Let's verify if there are any Blazor-specific file handling requirements:

src/Tools/Consolonia.PreviewHost/App.axaml.cs Outdated Show resolved Hide resolved
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: 0

🧹 Outside diff range and nitpick comments (8)
src/Consolonia.Designer/ConsolePreview.cs (8)

Line range hint 69-69: Remove outdated TODO comment in Dispose method

The Dispose method already disposes of managed objects. The TODO comment is no longer necessary and can be removed to clean up the code.

Apply this diff to remove the outdated comment:

- // TODO: dispose managed state (managed objects)

Line range hint 72-76: Check if the process has exited before calling _process.Kill()

In the Dispose method, check whether _process.HasExited is false before calling _process.Kill() to avoid exceptions when the process has already exited.

Apply this diff to add the check:

if (_process != null)
{
+   if (!_process.HasExited)
+   {
        _process.Kill();
+   }
    _process.Dispose();
    _process = null;
}

Line range hint 192-196: Add check for process availability before writing to _process.StandardInput

In the LoadXaml() method, ensure the process is still running before writing to StandardInput to prevent exceptions if the process has exited.

Apply this diff to add the check:

else
{
+   if (!_process.HasExited)
+   {
        // send request to previewHost to load the new xaml file.
        _process.StandardInput.WriteLine(xamlPath);
+   }
+   else
+   {
+       // Handle process exit
+       _process.Dispose();
+       _process = null;
+       LoadXaml();
+   }
}

Line range hint 246-252: Avoid hardcoded default values for character dimensions

The method ComputeCharWidth() uses hardcoded default values for _charWidth and _charHeight. Consider calculating these values dynamically or making them configurable to accommodate different font sizes and styles.


Line range hint 283-313: Improve robustness of XAML attribute parsing

The method GetDesignWidthAndHeight() uses string manipulation to extract d:DesignWidth and d:DesignHeight from the XAML content. Consider using an XML parser to reliably parse these attributes, enhancing robustness and maintainability.


Line range hint 294-352: Extract TextBlockComposer into a separate class

To improve code modularity and readability, consider moving the TextBlockComposer class into its own file. This aligns with the existing TODO comment and follows best practices for class organization.


42-42: Consolidate font settings to ensure consistency

The font is set in both _typeface and FontFamily using "Cascadia Mono". To avoid potential inconsistencies, consider consolidating font settings by defining a single source of truth or using a shared constant.

Also applies to: 54-54


Line range hint 65-82: Encapsulate process management into a separate helper class

The logic for starting, communicating with, and disposing the _process is spread across multiple methods. Consider encapsulating the process management into a separate helper class to improve code maintainability and readability.

Also applies to: 106-196, 199-219

πŸ“œ Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 9cce291 and 9328751.

πŸ“’ Files selected for processing (4)
  • src/Consolonia.Core/Infrastructure/ConsoloniaNotSupportedException.cs (1 hunks)
  • src/Consolonia.Designer/ConsolePreview.cs (2 hunks)
  • src/Consolonia.Designer/Extensions.cs (1 hunks)
  • src/Tools/Consolonia.PreviewHost/App.axaml.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/Consolonia.Core/Infrastructure/ConsoloniaNotSupportedException.cs
  • src/Consolonia.Designer/Extensions.cs
  • src/Tools/Consolonia.PreviewHost/App.axaml.cs
🧰 Additional context used
πŸ““ Learnings (1)
src/Consolonia.Designer/ConsolePreview.cs (1)
Learnt from: tomlm
PR: jinek/Consolonia#150
File: src/Consolonia.Designer/Consolonia.Designer.csproj:14-15
Timestamp: 2024-11-19T07:19:33.261Z
Learning: In the Consolonia project, circular dependencies between `Consolonia.Designer` and `Consolonia.PreviewHost` are intentional and by design. The `ConsolePreview` control consumes `Consolonia.PreviewHost`, and `Avalonia.PreviewHost` consumes `ConsolePreview` control in the designer.

jinek
jinek previously approved these changes Dec 7, 2024
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 and nitpick comments (4)
src/Tools/Consolonia.PreviewHost/App.cs (2)

34-44: LGTM! Consider adding path validation logging.

The improved path handling logic is more robust with explicit directory checks and proper separation of fully qualified vs relative paths. The addition of null checks enhances safety.

Consider adding debug logging to help troubleshoot path resolution issues. For example:

 if (Path.IsPathFullyQualified(path))
 {
+    Debug.WriteLine($"Resolving fully qualified path: {path}");
     if (Directory.Exists(path))
+    {
         folder = path;
+        Debug.WriteLine($"Using directory path: {folder}");
+    }
     else
     {
         folder = Path.GetDirectoryName(path)!;
+        Debug.WriteLine($"Using parent directory: {folder}");
     }
 }
 else
 {
     folder = Environment.CurrentDirectory;
+    Debug.WriteLine($"Using current directory: {folder}");
 }

Line range hint 102-139: Remove commented-out code.

The file contains a large block of commented-out code related to file watching. If this functionality has been moved elsewhere or is no longer needed, consider removing it to maintain code cleanliness.

src/Consolonia.Blazor/BuilderExtensions.cs (2)

12-14: Correct the typographical error in the summary comment

The word "Consolonize" in the summary comment should be corrected to "Consolonia" to match the method's intent and naming.


24-24: Fix the typo in the inline comment

The comment on line 24 contains a typo. Replace "injectoin" with "injection" for clarity.

πŸ“œ Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 9328751 and caf0951.

πŸ“’ Files selected for processing (13)
  • Directory.Build.props (1 hunks)
  • src/Consolonia.Blazor/BuilderExtensions.cs (1 hunks)
  • src/Consolonia.Blazor/Consolonia.Blazor.csproj (1 hunks)
  • src/Consolonia.Core/Infrastructure/ConsoloniaApplication.cs (2 hunks)
  • src/Consolonia.Gallery/App.cs (0 hunks)
  • src/Consolonia.PlatformSupport/Consolonia.PlatformSupport.csproj (1 hunks)
  • src/Consolonia.sln (2 hunks)
  • src/Example.Blazor.Components/Example.Blazor.Components.csproj (1 hunks)
  • src/Example.Blazor/App.axaml (1 hunks)
  • src/Example.Blazor/Example.Blazor.csproj (1 hunks)
  • src/Example.Blazor/Program.cs (1 hunks)
  • src/Example/App.cs (1 hunks)
  • src/Tools/Consolonia.PreviewHost/App.cs (1 hunks)
πŸ’€ Files with no reviewable changes (1)
  • src/Consolonia.Gallery/App.cs
βœ… Files skipped from review due to trivial changes (1)
  • src/Example/App.cs
🚧 Files skipped from review as they are similar to previous changes (8)
  • src/Example.Blazor/Example.Blazor.csproj
  • src/Consolonia.Blazor/Consolonia.Blazor.csproj
  • src/Example.Blazor/App.axaml
  • src/Example.Blazor/Program.cs
  • src/Example.Blazor.Components/Example.Blazor.Components.csproj
  • src/Consolonia.PlatformSupport/Consolonia.PlatformSupport.csproj
  • Directory.Build.props
  • src/Consolonia.Core/Infrastructure/ConsoloniaApplication.cs
πŸ”‡ Additional comments (5)
src/Tools/Consolonia.PreviewHost/App.cs (1)

34-44: Verify impact on hot reload functionality.

Since this path resolution logic is crucial for file watching and hot reload (as indicated by the commented code at the bottom), ensure these changes don't affect the new Blazor hot reload functionality mentioned in the PR objectives.

Let's check for any file watcher implementations that might depend on this path resolution:

βœ… Verification successful

Path resolution changes are safe for hot reload functionality

The path resolution changes in App.cs do not impact hot reload functionality. The file watching implementation is actually handled in XamlFileViewModel.cs where the WatchFileChanges() method correctly uses the full path from the FullName property to set up the FileSystemWatcher. The commented-out watcher code in App.cs is legacy code that's no longer in use.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for file watcher implementations
rg -l "FileSystemWatcher|EnableRaisingEvents" 

# Search for hot reload related code
rg -l "HotReload|LiveReload|Watch"

Length of output: 294


Script:

#!/bin/bash
# Let's examine the implementation details in both files
echo "=== App.cs ==="
rg -C 5 "FileSystemWatcher|EnableRaisingEvents|HotReload|LiveReload|Watch" "src/Tools/Consolonia.PreviewHost/App.cs"

echo -e "\n=== XamlFileViewModel.cs ==="
rg -C 5 "FileSystemWatcher|EnableRaisingEvents|HotReload|LiveReload|Watch" "src/Tools/Consolonia.PreviewHost/ViewModels/XamlFileViewModel.cs"

Length of output: 4165

src/Consolonia.Blazor/BuilderExtensions.cs (2)

17-51: Overall implementation is well-structured

The UseConsoloniaBlazor extension method is effectively integrating Consolonia with Blazor and setting up the necessary services. The use of optional configureServices allows for flexible service customization.


32-47: ⚠️ Potential issue

Handle potential null references when accessing MainWindow services

The services registered are accessing MainWindow using the null-conditional operator. If MainWindow is null, the registered services will be null, which could lead to NullReferenceException when these services are consumed. Consider throwing an exception if MainWindow is null during service resolution.

Apply this diff to enforce non-null MainWindow:

-sc.AddTransient(sp =>
-    sp.GetRequiredService<IClassicDesktopStyleApplicationLifetime>().MainWindow?.StorageProvider);
+sc.AddTransient(sp =>
+{
+    var mainWindow = sp.GetRequiredService<IClassicDesktopStyleApplicationLifetime>().MainWindow
+        ?? throw new InvalidOperationException("MainWindow is not available");
+    return mainWindow.StorageProvider;
+});

Repeat similar changes for the other services accessing MainWindow.

src/Consolonia.sln (2)

68-73: New projects added correctly to the solution

The projects Consolonia.Blazor, Example.Blazor, and Example.Blazor.Components are properly included in the solution file with correct paths and GUIDs.


132-151: Project configurations updated appropriately

The build configurations for the newly added projects are correctly defined for both Debug and Release modes, ensuring they are included in the solution build process.

src/Consolonia.Blazor/BuilderExtensions.cs Show resolved Hide resolved
@tomlm tomlm requested review from goe5mu and jinek December 8, 2024 04:45
@tomlm
Copy link
Collaborator Author

tomlm commented Dec 8, 2024

sorry I had merge conflicts I had to resolve.

@tomlm tomlm merged commit 62b0f1b into main Dec 8, 2024
3 checks passed
@tomlm tomlm deleted the tomlm/blazor branch December 8, 2024 13:26
@tomlm tomlm restored the tomlm/blazor branch December 13, 2024 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants