Skip to content

Release v3.7.3: LSPDFR UI redesign - #15

Merged
rolling-codes merged 3 commits into
masterfrom
release/v3.7.0-ui-redesign
May 13, 2026
Merged

Release v3.7.3: LSPDFR UI redesign#15
rolling-codes merged 3 commits into
masterfrom
release/v3.7.0-ui-redesign

Conversation

@rolling-codes

Copy link
Copy Markdown
Owner

LSPDFR Manager v3.7.3

This release delivers a major UI refresh with an LSPDFR-aligned command-center visual system.

Highlights

  • New app shell styling with a stronger sidebar hierarchy, active-state navigation treatment, and elevated content framing.
  • Redesigned Dashboard (Command Center) with clearer telemetry, metric cards, and action grouping.
  • Redesigned Library layout with improved top toolbar framing, risk-filter presentation, and panel readability.

Visual System

  • Adopted the police-blue LSPDFR color scheme as the canonical theme token source in Resources/Colors.xaml.
  • Added richer token usage and shared reusable styles in Resources/Styles.xaml:
    • ShellSidebar, ShellContentPanel
    • MetricCard, ActionGroupCard, TelemetryCard
    • StatusChip, LibraryToolbarCard, LibraryRowCard
  • Improved button templates (primary/ghost/nav) with consistent radius, hover, and active semantics.

Version Consistency

  • Updated project versioning to 3.7.3 in LSPDFRManager.csproj.
  • Updated the in-app shell version label to v3.7.3.

Known Scope Boundaries

  • This release redesigns the shell, Dashboard, and Library views only.
  • Remaining views retain current layout structure and will be addressed in later UI phases.

Validation

  • dotnet restore
  • dotnet build -c Release
  • dotnet test

Download

  • LSPDFRManager-v3.7.3-win-x64.zip

@coderabbitai

coderabbitai Bot commented May 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

Release v3.7.3

  • New Features

    • Added Mod Config navigation
    • Operational status indicator on the dashboard
    • New Telemetry section showing backup/diagnostics/crash activity
  • UI/Design Improvements

    • Major visual refresh: new color palette, gradients, and typography
    • Redesigned Command Center with metric cards and grouped actions
    • Improved Library layout, search/filters and tighter spacing
    • Updated navigation and button visuals/active states
  • Documentation

    • Added release notes for v3.7.3 and updated in-app version label
  • Tests

    • Added contract-style UI checks for redesigned resources and shell visuals

Walkthrough

PR #15 implements a v3.7.3 UI redesign: refreshed color palette and gradients, new control templates and card styles, shell layout restructuring with styled sidebar/content, Dashboard and Library view redesigns, XAML contract tests, release notes, and a project version bump.

Changes

UI/UX Redesign and Design System

Layer / File(s) Summary
Color Palette & Theme Foundation
Resources/Colors.xaml
New color palette and updated hex values for surfaces, borders, accents, and semantic brushes; added gradient brushes (SidebarGradient, CardGradient, AccentGradient*), SidebarGlowEdge, and warning/status resource keys.
ResourceDictionary Namespace & Base Styles
Resources/Styles.xaml
Added effects XML namespace; adjusted base control defaults (TextBox padding), added a ComboBox base style, and updated ListBox/ListBoxItem/ProgressBar/EmptyState defaults.
Buttons & Interactive Templates
Resources/Styles.xaml
Replaced PrimaryButton, GhostButton, and NavButton with template-based rounded controls and trigger-driven visual states for hover/pressed/focus/disabled; updated SectionHeader typography.
Card & Component Styles
Resources/Styles.xaml
Updated CardPanel and SectionCard; added ShellSidebar, ShellContentPanel, MetricCard, TelemetryCard, ActionGroupCard, StatusChip, LibraryToolbarCard, and LibraryRowCard.
Shell Layout Restructuring & Version Bump
MainWindow.xaml, LSPDFRManager.csproj
Window geometry updated; sidebar and content regions restructured to use styled containers; branding simplified to title + version; navigation restyled and "Mod Config" added; global error banner uses WarningBanner; project <Version>, <AssemblyVersion>, and <FileVersion> bumped to 3.7.3.*.
Dashboard View — Command Center
Views/DashboardView.xaml
Header rebuilt with right-aligned "Operational" StatusChip; environment status replaced with four MetricCard tiles and a DataTrigger-based GTA path indicator; quick actions spacing tightened; added TelemetryCard for backup/diagnostics/crash telemetry.
Library View — Toolbar & Layout
Views/LibraryView.xaml
Header converted to a gradient Library card with aggregated mod counts; search/filter controls moved into LibraryToolbarCard-styled borders; risk filter buttons moved to a dedicated card with DataTrigger active styling; main list/details grid adjusted and closing tag nesting fixed.
XAML Contract Tests & Release Notes
LSPDFRManager.Tests/UiRedesignXamlContractTests.cs, RELEASE_v3.7.3.md
Added XUnit text-level contract tests asserting presence of color/style keys and markup fragments in XAML; added release notes documenting the UI refresh, visual-system changes, validation steps, and download artifact.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • rolling-codes/LSPDFRManager#4: Overlapping UI/resource changes to MainWindow.xaml, Resources/Colors.xaml, and Resources/Styles.xaml related to the redesign.
  • rolling-codes/LSPDFRManager#1: Related Library view and toolbar/filter work; intersects on LibraryView.xaml layout and ViewModel wiring.

Suggested labels

codex

Poem

🐰 I hopped through colors, gradients, and cheer,

Polished the shell so the views shine clear,
Cards and chips now glow in blue,
Toolbars tidy, navigation true,
v3.7.3 — a rabbit's cheer for the new frontier!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the primary change: a major UI redesign for LSPDFR Manager v3.7.3, which aligns with the extensive XAML updates across shell, Dashboard, Library, colors, and styles throughout the changeset.
Description check ✅ Passed The description is well-structured and directly related to the changeset, covering the UI redesign highlights, visual system updates, version consistency, scope boundaries, and validation steps that correspond to the actual file changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/v3.7.0-ui-redesign

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review

Copy link
Copy Markdown

Review Summary by Qodo

Release v3.7.3: LSPDFR UI redesign with police-blue theme

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Bumped version from 3.7.2 to 3.7.3 across project files
• Redesigned shell UI with police-blue LSPDFR color scheme and gradient accents
• Refactored Dashboard with metric cards, action groups, and telemetry sections
• Streamlined Library layout with improved toolbar framing and risk-filter presentation
• Enhanced color palette with new gradients, borders, and semantic status indicators
• Introduced reusable card styles (MetricCard, ActionGroupCard, TelemetryCard, StatusChip)
• Updated button templates with consistent radius, hover states, and active semantics
Diagram
flowchart LR
  A["Version Update<br/>3.7.2 → 3.7.3"] --> B["Color System<br/>Police Blue Theme"]
  B --> C["Shell Redesign<br/>Sidebar + Content Panel"]
  C --> D["Dashboard Refresh<br/>Metrics + Actions"]
  D --> E["Library Overhaul<br/>Toolbar + Risk Filter"]
  B --> F["Gradient Brushes<br/>Accent + Card Fills"]
  F --> G["Button Styles<br/>Primary/Ghost/Nav"]
  G --> H["Card Styles<br/>Metric/Action/Telemetry"]
Loading

Grey Divider

File Changes

1. LSPDFRManager.csproj ⚙️ Configuration changes +4/-3

Bump project version to 3.7.3

• Updated Version, AssemblyVersion, and FileVersion from 3.5.2 to 3.7.3
• Maintains all existing project configuration and dependencies

LSPDFRManager.csproj


2. MainWindow.xaml ✨ Enhancement +40/-194

Redesign shell layout with styled sidebar and content panel

• Increased window dimensions from 820×1220 to 840×1320 for better layout
• Refactored sidebar to use ShellSidebar style with gradient background
• Updated version label from v3.5.1 to v3.7.3
• Simplified navigation button styling with inline DataTriggers using AccentActiveBg
• Added new "Mod Config" navigation button
• Wrapped content area in ShellContentPanel style with border and corner radius
• Replaced inline error banner styling with WarningBanner style reference

MainWindow.xaml


3. RELEASE_v3.7.3.md 📝 Documentation +39/-0

Add release notes for v3.7.3

• Created comprehensive release notes documenting v3.7.3 highlights
• Details UI redesign scope: shell, Dashboard, and Library views
• Documents visual system changes including color scheme and reusable styles
• Lists validation steps and download information

RELEASE_v3.7.3.md


View more (4)
4. Resources/Colors.xaml ✨ Enhancement +72/-33

Implement police-blue LSPDFR color system with gradients

• Shifted base surface colors to darker, more refined palette (#0A0D12, #11161E, #0D1219)
• Replaced accent colors with police-blue theme (#2B7FFF primary, #4D97FF secondary)
• Added gradient brushes: SidebarGradient, CardGradient, AccentGradient, AccentGradientH,
 SidebarGlowEdge
• Updated semantic status colors (green #2ECC71, amber #F7B733, red #EF4438)
• Refined text colors with improved contrast (TextStrong #E8EBF1, TextMuted #AAB3C2)
• Updated all compatibility aliases to match new color scheme

Resources/Colors.xaml


5. Resources/Styles.xaml ✨ Enhancement +191/-147

Add comprehensive card and button style system

• Added ComboBox style with consistent Surface background and Border styling
• Redesigned PrimaryButton with AccentGradient, rounded corners (10px), and opacity-based
 hover/press states
• Redesigned GhostButton with custom ControlTemplate, rounded corners (9px), and accent border on
 hover
• Redesigned NavButton with ControlTemplate, rounded corners (10px), and improved active state
 handling
• Added new card styles: CardPanel, SectionCard, MetricCard, ActionGroupCard, TelemetryCard,
 StatusChip, LibraryToolbarCard, LibraryRowCard
• Added ShellSidebar and ShellContentPanel styles for main layout
• Updated WarningBanner and ErrorPill styles with new corner radius and padding
• Removed obsolete IconButton and FilterPill styles
• Consolidated text styles (SectionHeader, SectionLabel, DetailLabel, DetailValue, ConsoleText,
 PlaceholderText)

Resources/Styles.xaml


6. Views/DashboardView.xaml ✨ Enhancement +82/-91

Redesign Dashboard with metric cards and telemetry

• Redesigned header with status chip showing "Operational" indicator
• Replaced 4-column status card layout with MetricCard-styled grid showing Game Path, LSPDFR Core,
 Mods, and Plugin Storage
• Reorganized quick actions into ActionGroupCard with improved button spacing
• Added new Telemetry section with TelemetryCard displaying Last Backup, Last Diagnostics, and Crash
 Log Activity
• Updated all margins and spacing for better visual hierarchy
• Simplified inline styles by referencing predefined card styles

Views/DashboardView.xaml


7. Views/LibraryView.xaml ✨ Enhancement +97/-257

Refactor Library layout with toolbar cards and improved spacing

• Moved bulk action buttons (Enable/Disable/Undo/Export) to top header area
• Wrapped search and filter controls in LibraryToolbarCard style
• Wrapped risk filter pills in separate LibraryToolbarCard for improved visual separation
• Increased detail panel width from 270 to 288 pixels
• Wrapped mod list in LibraryRowCard style with padding
• Consolidated inline styles and removed verbose formatting
• Updated button spacing and padding for consistency

Views/LibraryView.xaml


Grey Divider

ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented May 12, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0)

Grey Divider


Action required

1. Missing XAML style keys 🐞 Bug ≡ Correctness
Description
Resources/Styles.xaml no longer defines the InlineWarnPill, ToggleSwitch, and IconButton styles, but
several views still reference them via StaticResource. Loading those views will fail with a
XamlParseException (“cannot find resource”), breaking navigation/UI rendering.
Code

Resources/Styles.xaml[R186-209]

    <Style x:Key="WarningBanner" TargetType="Border">
-        <Setter Property="Background"       Value="{StaticResource WarningBackground}"/>
-        <Setter Property="BorderBrush"      Value="{StaticResource WarningBorder}"/>
-        <Setter Property="BorderThickness"  Value="1"/>
-        <Setter Property="CornerRadius"     Value="8"/>
-        <Setter Property="Padding"          Value="14,10"/>
+        <Setter Property="Background" Value="{StaticResource WarningBackground}"/>
+        <Setter Property="BorderBrush" Value="{StaticResource WarningBorder}"/>
+        <Setter Property="BorderThickness" Value="1"/>
+        <Setter Property="CornerRadius" Value="10"/>
+        <Setter Property="Padding" Value="14,10"/>
    </Style>

-    <!-- Inline warning pill (inside detection results) -->
-    <Style x:Key="InlineWarnPill" TargetType="Border">
-        <Setter Property="Background"       Value="{StaticResource InlineWarnBg}"/>
-        <Setter Property="CornerRadius"     Value="6"/>
-        <Setter Property="Padding"          Value="10,6"/>
-        <Setter Property="Margin"           Value="0,2"/>
+    <Style x:Key="ErrorPill" TargetType="Border">
+        <Setter Property="Background" Value="{StaticResource ErrorBackground}"/>
+        <Setter Property="BorderBrush" Value="{StaticResource DangerBrush}"/>
+        <Setter Property="BorderThickness" Value="1"/>
+        <Setter Property="CornerRadius" Value="6"/>
+        <Setter Property="Padding" Value="8,4"/>
+        <Setter Property="Margin" Value="0,0,0,4"/>
    </Style>

-    <!-- Error inline (conflict / install error) -->
-    <Style x:Key="ErrorPill" TargetType="Border">
-        <Setter Property="Background"       Value="{StaticResource ErrorBackground}"/>
-        <Setter Property="BorderBrush"      Value="{StaticResource DangerBrush}"/>
-        <Setter Property="BorderThickness"  Value="1"/>
-        <Setter Property="CornerRadius"     Value="6"/>
-        <Setter Property="Padding"          Value="8,4"/>
-        <Setter Property="Margin"           Value="0,0,0,4"/>
+    <Style x:Key="CardPanel" TargetType="Border">
+        <Setter Property="Background" Value="{StaticResource Surface}"/>
+        <Setter Property="BorderBrush" Value="{StaticResource BorderMid}"/>
+        <Setter Property="BorderThickness" Value="1"/>
+        <Setter Property="CornerRadius" Value="12"/>
+        <Setter Property="Padding" Value="16"/>
    </Style>
Evidence
The styles are absent from the shared dictionary, while multiple views still reference them by key;
this combination deterministically causes WPF StaticResource resolution failures when the views
load.

Resources/Styles.xaml[52-210]
Views/BrowseView.xaml[24-48]
Views/Components/ModCard.xaml[100-113]
Views/InstallView.xaml[210-221]
Views/SettingsView.xaml[116-166]
Views/ConfigView.xaml[64-76]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`InlineWarnPill`, `ToggleSwitch`, and `IconButton` style resources were removed from `Resources/Styles.xaml` but are still referenced by other XAML views. This will cause runtime `XamlParseException` when the affected views are instantiated.

### Issue Context
The repo still contains `Style="{StaticResource IconButton}"`, `Style="{StaticResource ToggleSwitch}"`, and `Style="{StaticResource InlineWarnPill}"` usages. WPF resolves `StaticResource` at load time; missing keys are fatal.

### Fix
Either:
1) Re-introduce compatibility styles with the same keys (`IconButton`, `ToggleSwitch`, `InlineWarnPill`) in `Resources/Styles.xaml` (can be BasedOn your new button/card styles), **or**
2) Update all referencing views to use existing styles (e.g., `GhostButton`) and remove/replace the missing keys.

### Fix Focus Areas
- Resources/Styles.xaml[52-215]
- Views/BrowseView.xaml[24-48]
- Views/Components/ModCard.xaml[100-113]
- Views/InstallView.xaml[210-221]
- Views/SettingsView.xaml[116-166]
- Views/ConfigView.xaml[64-76]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. ModConfig navigation mismatch 🐞 Bug ≡ Correctness
Description
MainWindow’s new “Mod Config” button uses CommandParameter="ModConfig" and binds IsModConfigActive,
but MainViewModel.Navigate only routes "Config" to ConfigVM and has no IsModConfigActive flag.
Clicking “Mod Config” will fall back to DashboardVM and the active-state trigger will produce
binding errors.
Code

MainWindow.xaml[R55-57]

+                    <Button Content="Mod Config" Command="{Binding NavigateCommand}" CommandParameter="ModConfig">
+                        <Button.Style><Style TargetType="Button" BasedOn="{StaticResource NavButton}"><Style.Triggers><DataTrigger Binding="{Binding IsModConfigActive}" Value="True"><Setter Property="Background" Value="{StaticResource AccentActiveBg}"/><Setter Property="BorderBrush" Value="{StaticResource AccentBorder}"/><Setter Property="Foreground" Value="{StaticResource TextStrong}"/></DataTrigger></Style.Triggers></Style></Button.Style>
+                    </Button>
Evidence
The XAML expects a "ModConfig" route and an IsModConfigActive property, but MainViewModel only
recognizes "Config" and does not define the active flag used by the DataTrigger, so
navigation/active highlighting cannot work as written.

MainWindow.xaml[24-60]
ViewModels/MainViewModel.cs[80-126]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The new sidebar entry uses `CommandParameter="ModConfig"` and `IsModConfigActive`, but `MainViewModel` only supports the page key `"Config"` and exposes no `IsModConfigActive` property.

### Issue Context
`MainViewModel.Navigate` sets `_activePage = page?.ToString()` and selects the view via a switch. Unrecognized page keys default to `DashboardVM`.

### Fix
Pick one approach:
- **Recommended**: change the button to `CommandParameter="Config"` and add an `IsConfigActive` property in `MainViewModel`, updating the XAML trigger to bind that property.
- Alternative: update `MainViewModel` to handle `"ModConfig" => ConfigVM`, add `IsModConfigActive`, and raise `OnPropertyChanged(nameof(IsModConfigActive))` in `Navigate`.

### Fix Focus Areas
- MainWindow.xaml[24-60]
- ViewModels/MainViewModel.cs[80-126]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan

Qodo Logo

Comment thread Resources/Styles.xaml
Comment on lines 186 to 209
<Style x:Key="WarningBanner" TargetType="Border">
<Setter Property="Background" Value="{StaticResource WarningBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource WarningBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="CornerRadius" Value="8"/>
<Setter Property="Padding" Value="14,10"/>
<Setter Property="Background" Value="{StaticResource WarningBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource WarningBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="CornerRadius" Value="10"/>
<Setter Property="Padding" Value="14,10"/>
</Style>

<!-- Inline warning pill (inside detection results) -->
<Style x:Key="InlineWarnPill" TargetType="Border">
<Setter Property="Background" Value="{StaticResource InlineWarnBg}"/>
<Setter Property="CornerRadius" Value="6"/>
<Setter Property="Padding" Value="10,6"/>
<Setter Property="Margin" Value="0,2"/>
<Style x:Key="ErrorPill" TargetType="Border">
<Setter Property="Background" Value="{StaticResource ErrorBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource DangerBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="CornerRadius" Value="6"/>
<Setter Property="Padding" Value="8,4"/>
<Setter Property="Margin" Value="0,0,0,4"/>
</Style>

<!-- Error inline (conflict / install error) -->
<Style x:Key="ErrorPill" TargetType="Border">
<Setter Property="Background" Value="{StaticResource ErrorBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource DangerBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="CornerRadius" Value="6"/>
<Setter Property="Padding" Value="8,4"/>
<Setter Property="Margin" Value="0,0,0,4"/>
<Style x:Key="CardPanel" TargetType="Border">
<Setter Property="Background" Value="{StaticResource Surface}"/>
<Setter Property="BorderBrush" Value="{StaticResource BorderMid}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="CornerRadius" Value="12"/>
<Setter Property="Padding" Value="16"/>
</Style>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Missing xaml style keys 🐞 Bug ≡ Correctness

Resources/Styles.xaml no longer defines the InlineWarnPill, ToggleSwitch, and IconButton styles, but
several views still reference them via StaticResource. Loading those views will fail with a
XamlParseException (“cannot find resource”), breaking navigation/UI rendering.
Agent Prompt
### Issue description
`InlineWarnPill`, `ToggleSwitch`, and `IconButton` style resources were removed from `Resources/Styles.xaml` but are still referenced by other XAML views. This will cause runtime `XamlParseException` when the affected views are instantiated.

### Issue Context
The repo still contains `Style="{StaticResource IconButton}"`, `Style="{StaticResource ToggleSwitch}"`, and `Style="{StaticResource InlineWarnPill}"` usages. WPF resolves `StaticResource` at load time; missing keys are fatal.

### Fix
Either:
1) Re-introduce compatibility styles with the same keys (`IconButton`, `ToggleSwitch`, `InlineWarnPill`) in `Resources/Styles.xaml` (can be BasedOn your new button/card styles), **or**
2) Update all referencing views to use existing styles (e.g., `GhostButton`) and remove/replace the missing keys.

### Fix Focus Areas
- Resources/Styles.xaml[52-215]
- Views/BrowseView.xaml[24-48]
- Views/Components/ModCard.xaml[100-113]
- Views/InstallView.xaml[210-221]
- Views/SettingsView.xaml[116-166]
- Views/ConfigView.xaml[64-76]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread MainWindow.xaml
Comment on lines +55 to +57
<Button Content="Mod Config" Command="{Binding NavigateCommand}" CommandParameter="ModConfig">
<Button.Style><Style TargetType="Button" BasedOn="{StaticResource NavButton}"><Style.Triggers><DataTrigger Binding="{Binding IsModConfigActive}" Value="True"><Setter Property="Background" Value="{StaticResource AccentActiveBg}"/><Setter Property="BorderBrush" Value="{StaticResource AccentBorder}"/><Setter Property="Foreground" Value="{StaticResource TextStrong}"/></DataTrigger></Style.Triggers></Style></Button.Style>
</Button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Modconfig navigation mismatch 🐞 Bug ≡ Correctness

MainWindow’s new “Mod Config” button uses CommandParameter="ModConfig" and binds IsModConfigActive,
but MainViewModel.Navigate only routes "Config" to ConfigVM and has no IsModConfigActive flag.
Clicking “Mod Config” will fall back to DashboardVM and the active-state trigger will produce
binding errors.
Agent Prompt
### Issue description
The new sidebar entry uses `CommandParameter="ModConfig"` and `IsModConfigActive`, but `MainViewModel` only supports the page key `"Config"` and exposes no `IsModConfigActive` property.

### Issue Context
`MainViewModel.Navigate` sets `_activePage = page?.ToString()` and selects the view via a switch. Unrecognized page keys default to `DashboardVM`.

### Fix
Pick one approach:
- **Recommended**: change the button to `CommandParameter="Config"` and add an `IsConfigActive` property in `MainViewModel`, updating the XAML trigger to bind that property.
- Alternative: update `MainViewModel` to handle `"ModConfig" => ConfigVM`, add `IsModConfigActive`, and raise `OnPropertyChanged(nameof(IsModConfigActive))` in `Navigate`.

### Fix Focus Areas
- MainWindow.xaml[24-60]
- ViewModels/MainViewModel.cs[80-126]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@MainWindow.xaml`:
- Around line 55-57: The Mod Config button uses CommandParameter="ModConfig" and
binds to IsModConfigActive which don't match MainViewModel's navigation logic;
update the Button to send CommandParameter="Config" so
NavigateCommand/Navigate() in MainViewModel will hit the "Config" case, and
change the binding from IsModConfigActive to IsConfigActive (or alternatively
add an IsModConfigActive property that mirrors IsConfigActive) so the
DataTrigger correctly reflects the active state.

In `@Resources/Styles.xaml`:
- Around line 52-81: The PrimaryButton Style's ControlTemplate removes default
focus visuals so keyboard users lack visible focus; update the PrimaryButton
(and other custom button styles at the other ranges) to add keyboard-focus
states by including a focus visual element inside the ControlTemplate (e.g., an
inner Border or Rectangle) and bind its visibility/appearance to
IsKeyboardFocused and/or IsFocused using TemplateBinding or triggers; add
Trigger(s) for IsKeyboardFocused (and IsFocused if needed) on the
Style/ControlTemplate to set a distinct BorderBrush, BorderThickness, Opacity or
a glow (CornerRadius 10 to match) to make focus clearly visible while preserving
existing pressed/hover states (reference ControlTemplate, PrimaryButton, and the
Style.Triggers for IsMouseOver/IsPressed/IsEnabled).

In `@Views/DashboardView.xaml`:
- Around line 49-50: The TextBlock is binding raw boolean
Status.IsLspdfrInstalled which renders True/False; update the UI to show
user-friendly text (e.g., "Installed"/"Not installed") by either (a) adding a
read-only string property on the ViewModel like IsLspdfrInstalledText that
returns the display text and bind Text to that property, or (b) use a
BooleanToVisibility/BooleanToString converter (e.g., create an IValueConverter
named BooleanToInstalledStringConverter) and change the binding on the TextBlock
to use that converter for Status.IsLspdfrInstalled; reference the TextBlock with
Text="{Binding Status.IsLspdfrInstalled,...}" or the ViewModel property
IsLspdfrInstalledText to locate where to change the binding.
- Around line 31-42: The TextBlock always displays the literal "Validated" even
when Status.IsGtaPathValid is false; update the TextBlock so its Text reflects
the binding Status.IsGtaPathValid (e.g., use a DataTrigger or a
BooleanToString/Converter) instead of a hardcoded string: modify the TextBlock
next to the Ellipse (the one currently Text="Validated") to set Text to
"Validated" when Status.IsGtaPathValid==True and to an appropriate alternative
(e.g., "Invalid" or "Not validated") when False, using a DataTrigger or a
converter bound to Status.IsGtaPathValid so the label matches the Ellipse state.

In `@Views/LibraryView.xaml`:
- Around line 48-49: The DataTrigger only checks for an empty string so a null
SearchQuery keeps the placeholder hidden; update the trigger logic to handle
nulls by either adding a second DataTrigger with Binding="{Binding SearchQuery}"
and Value="{x:Null}" that sets Visibility=Visible, or set the Binding on the
existing DataTrigger to include TargetNullValue="" so nulls are treated as
empty; target the existing DataTrigger/Binding referencing SearchQuery in the
Style.Triggers to apply one of these fixes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 379253ad-0f8e-4abd-9545-3aa11368901c

📥 Commits

Reviewing files that changed from the base of the PR and between 5bed757 and d3373f3.

📒 Files selected for processing (7)
  • LSPDFRManager.csproj
  • MainWindow.xaml
  • RELEASE_v3.7.3.md
  • Resources/Colors.xaml
  • Resources/Styles.xaml
  • Views/DashboardView.xaml
  • Views/LibraryView.xaml

Comment thread MainWindow.xaml
Comment on lines +55 to +57
<Button Content="Mod Config" Command="{Binding NavigateCommand}" CommandParameter="ModConfig">
<Button.Style><Style TargetType="Button" BasedOn="{StaticResource NavButton}"><Style.Triggers><DataTrigger Binding="{Binding IsModConfigActive}" Value="True"><Setter Property="Background" Value="{StaticResource AccentActiveBg}"/><Setter Property="BorderBrush" Value="{StaticResource AccentBorder}"/><Setter Property="Foreground" Value="{StaticResource TextStrong}"/></DataTrigger></Style.Triggers></Style></Button.Style>
</Button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check binding/property symbol existence =="
rg -n -C2 '\bIsModConfigActive\b|\bCommandParameter="ModConfig"\b|\bNavigateCommand\b'

echo "== Check navigation switch/route handling for ModConfig =="
rg -n -C4 'ModConfig|Navigate|CurrentView|SetActive|Is[A-Za-z]+Active'

echo "== Check Mod Config view UserControl presence =="
fd -i 'Mod*Config*.xaml' .
rg -n -C2 '<UserControl\s+x:Class=.*Mod.*Config' --iglob '*.xaml'

Repository: rolling-codes/LSPDFRManager

Length of output: 32848


🏁 Script executed:

# Read complete MainViewModel.cs to check all properties
wc -l ViewModels/MainViewModel.cs && sed -n '80,130p' ViewModels/MainViewModel.cs

Repository: rolling-codes/LSPDFRManager

Length of output: 2253


🏁 Script executed:

# Search for ModConfigView with broader patterns
fd -type f -name '*odConfig*' .
find . -type f \( -name '*ModConfig*' -o -name '*modconfig*' \)

Repository: rolling-codes/LSPDFRManager

Length of output: 242


🏁 Script executed:

# Verify the Navigate method completely
sed -n '95,126p' ViewModels/MainViewModel.cs

Repository: rolling-codes/LSPDFRManager

Length of output: 1293


🏁 Script executed:

# Search for ModConfigView or Config view directly
find . -name '*View.xaml*' | grep -i config

Repository: rolling-codes/LSPDFRManager

Length of output: 122


🏁 Script executed:

# Check what ConfigVM references - should find ModConfigViewModel
rg -n 'ConfigVM|ModConfigViewModel' ViewModels/MainViewModel.cs

Repository: rolling-codes/LSPDFRManager

Length of output: 171


🏁 Script executed:

# Verify if there's any IsModConfigActive defined anywhere
rg -n 'IsModConfigActive' .

Repository: rolling-codes/LSPDFRManager

Length of output: 537


Fix ModConfig navigation parameter mismatch — button will not navigate correctly.

The button sends CommandParameter="ModConfig" but the Navigate() switch expects "Config" (line 103, ViewModels/MainViewModel.cs). This causes the button click to fall through to the default case and display Dashboard instead of Config. Additionally, the binding to IsModConfigActive fails because this property does not exist in MainViewModel — the existing active-state property would be derived from matching the "Config" case.

Change CommandParameter="ModConfig" to CommandParameter="Config" and the binding from IsModConfigActive to IsConfigActive (or add IsModConfigActive property that mirrors the Config page state if a renamed property is preferred).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@MainWindow.xaml` around lines 55 - 57, The Mod Config button uses
CommandParameter="ModConfig" and binds to IsModConfigActive which don't match
MainViewModel's navigation logic; update the Button to send
CommandParameter="Config" so NavigateCommand/Navigate() in MainViewModel will
hit the "Config" case, and change the binding from IsModConfigActive to
IsConfigActive (or alternatively add an IsModConfigActive property that mirrors
IsConfigActive) so the DataTrigger correctly reflects the active state.

Comment thread Resources/Styles.xaml
Comment thread Views/DashboardView.xaml
Comment on lines +31 to 42
<Ellipse Width="7" Height="7" Margin="0,0,6,0" VerticalAlignment="Center">
<Ellipse.Style>
<Style TargetType="Ellipse">
<Setter Property="Fill" Value="{StaticResource StatusError}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Status.IsLspdfrInstalled}" Value="True">
<Setter Property="Fill" Value="{StaticResource StatusOk}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Status.IsGtaPathValid}" Value="True"><Setter Property="Fill" Value="{StaticResource StatusOk}"/></DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<TextBlock Text="LSPDFR" Foreground="{StaticResource TextPrimary}" FontSize="13" FontWeight="SemiBold"/>
<TextBlock Text="Validated" Foreground="{StaticResource TextMuted}" FontSize="12"/>
</StackPanel>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Status label is incorrect when GTA path is invalid.

The indicator color changes, but text always says “Validated,” which reports the wrong state when Status.IsGtaPathValid == false.

Suggested patch
-                            <TextBlock Text="Validated" Foreground="{StaticResource TextMuted}" FontSize="12"/>
+                            <TextBlock Foreground="{StaticResource TextMuted}" FontSize="12">
+                                <TextBlock.Style>
+                                    <Style TargetType="TextBlock">
+                                        <Setter Property="Text" Value="Invalid path"/>
+                                        <Style.Triggers>
+                                            <DataTrigger Binding="{Binding Status.IsGtaPathValid}" Value="True">
+                                                <Setter Property="Text" Value="Validated"/>
+                                            </DataTrigger>
+                                        </Style.Triggers>
+                                    </Style>
+                                </TextBlock.Style>
+                            </TextBlock>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Views/DashboardView.xaml` around lines 31 - 42, The TextBlock always displays
the literal "Validated" even when Status.IsGtaPathValid is false; update the
TextBlock so its Text reflects the binding Status.IsGtaPathValid (e.g., use a
DataTrigger or a BooleanToString/Converter) instead of a hardcoded string:
modify the TextBlock next to the Ellipse (the one currently Text="Validated") to
set Text to "Validated" when Status.IsGtaPathValid==True and to an appropriate
alternative (e.g., "Invalid" or "Not validated") when False, using a DataTrigger
or a converter bound to Status.IsGtaPathValid so the label matches the Ellipse
state.

Comment thread Views/DashboardView.xaml
Comment on lines +49 to +50
<TextBlock Text="{Binding Status.IsLspdfrInstalled, StringFormat='{}{0}'}" Foreground="{StaticResource TextStrong}" FontSize="22" FontWeight="Bold" Margin="0,7,0,0"/>
<TextBlock Text="Core install state" Foreground="{StaticResource TextSubtle}" FontSize="12" Margin="0,8,0,0"/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid displaying raw booleans in the LSPDFR CORE metric.

{Binding Status.IsLspdfrInstalled} renders True/False; use user-facing text like “Installed/Not installed”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Views/DashboardView.xaml` around lines 49 - 50, The TextBlock is binding raw
boolean Status.IsLspdfrInstalled which renders True/False; update the UI to show
user-friendly text (e.g., "Installed"/"Not installed") by either (a) adding a
read-only string property on the ViewModel like IsLspdfrInstalledText that
returns the display text and bind Text to that property, or (b) use a
BooleanToVisibility/BooleanToString converter (e.g., create an IValueConverter
named BooleanToInstalledStringConverter) and change the binding on the TextBlock
to use that converter for Status.IsLspdfrInstalled; reference the TextBlock with
Text="{Binding Status.IsLspdfrInstalled,...}" or the ViewModel property
IsLspdfrInstalledText to locate where to change the binding.

Comment thread Views/LibraryView.xaml

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (3)
Views/DashboardView.xaml (2)

57-58: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid rendering raw boolean values in the LSPDFR CORE metric.

True/False is not user-friendly here; use display text like “Installed” / “Not installed”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Views/DashboardView.xaml` around lines 57 - 58, The TextBlock is rendering
the raw boolean bound to Status.IsLspdfrInstalled; change it to display friendly
text (e.g., "Installed"/"Not installed") by replacing the direct binding on the
TextBlock with a presentation layer conversion — either use an IValueConverter
(e.g., BoolToInstalledConverter) and set Text="{Binding
Status.IsLspdfrInstalled, Converter={StaticResource BoolToInstalledConverter}}",
or implement a DataTrigger/Style on the TextBlock that sets Text to "Installed"
when IsLspdfrInstalled is true and "Not installed" when false; update the
resource dictionary to register the converter (or add the style) and reference
the TextBlock in Views/DashboardView.xaml instead of showing raw True/False.

39-50: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Status label contradicts invalid GTA path state.

The indicator color changes with Status.IsGtaPathValid, but the label remains hardcoded to “Validated,” which misreports invalid paths.

Suggested fix
-                            <TextBlock Text="Validated" Foreground="{StaticResource TextMuted}" FontSize="12"/>
+                            <TextBlock Foreground="{StaticResource TextMuted}" FontSize="12">
+                                <TextBlock.Style>
+                                    <Style TargetType="TextBlock">
+                                        <Setter Property="Text" Value="Invalid path"/>
+                                        <Style.Triggers>
+                                            <DataTrigger Binding="{Binding Status.IsGtaPathValid}" Value="True">
+                                                <Setter Property="Text" Value="Validated"/>
+                                            </DataTrigger>
+                                        </Style.Triggers>
+                                    </Style>
+                                </TextBlock.Style>
+                            </TextBlock>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Views/DashboardView.xaml` around lines 39 - 50, The label "Validated" is
hardcoded while the ellipse uses Status.IsGtaPathValid, causing contradictory
UI; update the TextBlock (the Text property on the TextBlock next to the
Ellipse) to reflect Status.IsGtaPathValid by binding its Text or adding a
Style/DataTrigger that sets Text to "Validated" when Status.IsGtaPathValid ==
True and to a fallback like "Invalid" when False (keep the Ellipse and its
DataTrigger unchanged).
MainWindow.xaml (1)

76-77: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Mod Config navigation contract likely mismatches ViewModel route/property names.

If the ViewModel still routes Config/IsConfigActive, this button won’t navigate/activate correctly.

#!/bin/bash
set -euo pipefail

# Verify command parameters and active-state bindings in XAML and VM route/property symbols
rg -n -C3 --iglob '*.xaml' --iglob '*.cs' \
'CommandParameter="ModConfig"|CommandParameter="Config"|IsModConfigActive|IsConfigActive|case\s*"ModConfig"|case\s*"Config"|Navigate\s*\('

Expected: command parameter and active-state property used in MainWindow.xaml should match the route key/property implemented in the ViewModel.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@MainWindow.xaml` around lines 76 - 77, The Mod Config Button uses
CommandParameter="ModConfig" and DataTrigger binding IsModConfigActive but the
ViewModel appears to expose Config/IsConfigActive (or vice versa), so update
either the XAML or the ViewModel to use the same route/property names: ensure
the Button's CommandParameter passed to NavigateCommand (symbol:
NavigateCommand) matches the route key handled in the ViewModel (e.g., "Config"
vs "ModConfig"), and make the active-state binding (IsModConfigActive) use the
exact boolean property implemented in the VM (e.g., rename to IsConfigActive or
add IsModConfigActive forwarding property) so the DataTrigger and navigation
logic align.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@LSPDFRManager.Tests/UiRedesignXamlContractTests.cs`:
- Around line 14-53: Replace implicit var locals with explicit nullable-aware
string types: change the local declarations named text (in tests like
StylesXaml_UsesDropShadowEffectForPrimaryButtonCardPanelAndStatusChip,
MainWindowXaml_ContainsShellGlowAccentAndBoldActiveNavigationSetters, etc.) from
var text = ReadRepoFile(...) to string text = ReadRepoFile(...), and change the
local path in ReadRepoFile from var path = Path.GetFullPath(...) to string path
= Path.GetFullPath(...). Ensure you use string (not string?) because
ReadRepoFile and Path.GetFullPath return non-null strings and update any other
var string-like locals in this file similarly.

In `@MainWindow.xaml`:
- Line 41: Update the hardcoded sidebar TextBlock text that currently reads
"v3.7.0  •  Command Center" to the correct release string "v3.7.3  •  Command
Center" in MainWindow.xaml (the TextBlock element showing the version);
alternatively replace the literal with a binding or resource that pulls the app
version (e.g., an ApplicationVersion or VersionLabel property) so future
releases don't require manual edits to the TextBlock text.

---

Duplicate comments:
In `@MainWindow.xaml`:
- Around line 76-77: The Mod Config Button uses CommandParameter="ModConfig" and
DataTrigger binding IsModConfigActive but the ViewModel appears to expose
Config/IsConfigActive (or vice versa), so update either the XAML or the
ViewModel to use the same route/property names: ensure the Button's
CommandParameter passed to NavigateCommand (symbol: NavigateCommand) matches the
route key handled in the ViewModel (e.g., "Config" vs "ModConfig"), and make the
active-state binding (IsModConfigActive) use the exact boolean property
implemented in the VM (e.g., rename to IsConfigActive or add IsModConfigActive
forwarding property) so the DataTrigger and navigation logic align.

In `@Views/DashboardView.xaml`:
- Around line 57-58: The TextBlock is rendering the raw boolean bound to
Status.IsLspdfrInstalled; change it to display friendly text (e.g.,
"Installed"/"Not installed") by replacing the direct binding on the TextBlock
with a presentation layer conversion — either use an IValueConverter (e.g.,
BoolToInstalledConverter) and set Text="{Binding Status.IsLspdfrInstalled,
Converter={StaticResource BoolToInstalledConverter}}", or implement a
DataTrigger/Style on the TextBlock that sets Text to "Installed" when
IsLspdfrInstalled is true and "Not installed" when false; update the resource
dictionary to register the converter (or add the style) and reference the
TextBlock in Views/DashboardView.xaml instead of showing raw True/False.
- Around line 39-50: The label "Validated" is hardcoded while the ellipse uses
Status.IsGtaPathValid, causing contradictory UI; update the TextBlock (the Text
property on the TextBlock next to the Ellipse) to reflect Status.IsGtaPathValid
by binding its Text or adding a Style/DataTrigger that sets Text to "Validated"
when Status.IsGtaPathValid == True and to a fallback like "Invalid" when False
(keep the Ellipse and its DataTrigger unchanged).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f9ac6cfb-8d68-4b2a-8dee-3f7f0f30341a

📥 Commits

Reviewing files that changed from the base of the PR and between d3373f3 and 07bc85f.

📒 Files selected for processing (6)
  • LSPDFRManager.Tests/UiRedesignXamlContractTests.cs
  • MainWindow.xaml
  • Resources/Colors.xaml
  • Resources/Styles.xaml
  • Views/DashboardView.xaml
  • Views/LibraryView.xaml

Comment on lines +14 to +53
var text = ReadRepoFile("Resources", "Colors.xaml");

Assert.Contains("x:Key=\"AccentPrimary\"", text);
Assert.Contains("Color=\"#3A98FF\"", text);
Assert.Contains("x:Key=\"AccentGradient\"", text);
Assert.Contains("x:Key=\"AccentGlow\"", text);
Assert.Contains("x:Key=\"ProgressTrackGradient\"", text);
}

[Fact]
public void StylesXaml_UsesDropShadowEffectForPrimaryButtonCardPanelAndStatusChip()
{
var text = ReadRepoFile("Resources", "Styles.xaml");

Assert.Contains("x:Key=\"PrimaryButton\"", text);
Assert.Contains("x:Key=\"CardPanel\"", text);
Assert.Contains("x:Key=\"StatusChip\"", text);
Assert.Contains("<effects:DropShadowEffect", text);

Assert.Contains("x:Key=\"PrimaryButton\" TargetType=\"Button\">", text);
Assert.Contains("x:Key=\"CardPanel\" TargetType=\"Border\">", text);
Assert.Contains("x:Key=\"StatusChip\" TargetType=\"Border\">", text);
}

[Fact]
public void MainWindowXaml_ContainsShellGlowAccentAndBoldActiveNavigationSetters()
{
var text = ReadRepoFile("MainWindow.xaml");

Assert.Contains("x:Key=\"ShellGlowAccent\"", text);
Assert.Contains("Background=\"{StaticResource ShellGlowAccent}\"", text);
Assert.Contains("BasedOn=\"{StaticResource NavButton}\"", text);
Assert.Contains("DataTrigger Binding=\"{Binding IsHomeActive}\" Value=\"True\">", text);
Assert.Contains("Setter Property=\"FontWeight\" Value=\"Bold\"", text);
}

private static string ReadRepoFile(params string[] parts)
{
var path = Path.GetFullPath(
Path.Combine([AppContext.BaseDirectory, "..", "..", "..", "..", .. parts]));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Use explicit nullability types instead of var in this C# test file.

Replace implicit var locals with explicit string declarations per repo rule.

Suggested fix
-        var text = ReadRepoFile("Resources", "Colors.xaml");
+        string text = ReadRepoFile("Resources", "Colors.xaml");
@@
-        var text = ReadRepoFile("Resources", "Styles.xaml");
+        string text = ReadRepoFile("Resources", "Styles.xaml");
@@
-        var text = ReadRepoFile("MainWindow.xaml");
+        string text = ReadRepoFile("MainWindow.xaml");
@@
-        var path = Path.GetFullPath(
+        string path = Path.GetFullPath(
             Path.Combine([AppContext.BaseDirectory, "..", "..", "..", "..", .. parts]));

As per coding guidelines, "**/*.{cs,csproj}: ... declare all variables with explicit nullability: string? for nullable, string for non-null".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var text = ReadRepoFile("Resources", "Colors.xaml");
Assert.Contains("x:Key=\"AccentPrimary\"", text);
Assert.Contains("Color=\"#3A98FF\"", text);
Assert.Contains("x:Key=\"AccentGradient\"", text);
Assert.Contains("x:Key=\"AccentGlow\"", text);
Assert.Contains("x:Key=\"ProgressTrackGradient\"", text);
}
[Fact]
public void StylesXaml_UsesDropShadowEffectForPrimaryButtonCardPanelAndStatusChip()
{
var text = ReadRepoFile("Resources", "Styles.xaml");
Assert.Contains("x:Key=\"PrimaryButton\"", text);
Assert.Contains("x:Key=\"CardPanel\"", text);
Assert.Contains("x:Key=\"StatusChip\"", text);
Assert.Contains("<effects:DropShadowEffect", text);
Assert.Contains("x:Key=\"PrimaryButton\" TargetType=\"Button\">", text);
Assert.Contains("x:Key=\"CardPanel\" TargetType=\"Border\">", text);
Assert.Contains("x:Key=\"StatusChip\" TargetType=\"Border\">", text);
}
[Fact]
public void MainWindowXaml_ContainsShellGlowAccentAndBoldActiveNavigationSetters()
{
var text = ReadRepoFile("MainWindow.xaml");
Assert.Contains("x:Key=\"ShellGlowAccent\"", text);
Assert.Contains("Background=\"{StaticResource ShellGlowAccent}\"", text);
Assert.Contains("BasedOn=\"{StaticResource NavButton}\"", text);
Assert.Contains("DataTrigger Binding=\"{Binding IsHomeActive}\" Value=\"True\">", text);
Assert.Contains("Setter Property=\"FontWeight\" Value=\"Bold\"", text);
}
private static string ReadRepoFile(params string[] parts)
{
var path = Path.GetFullPath(
Path.Combine([AppContext.BaseDirectory, "..", "..", "..", "..", .. parts]));
string text = ReadRepoFile("Resources", "Colors.xaml");
Assert.Contains("x:Key=\"AccentPrimary\"", text);
Assert.Contains("Color=\"#3A98FF\"", text);
Assert.Contains("x:Key=\"AccentGradient\"", text);
Assert.Contains("x:Key=\"AccentGlow\"", text);
Assert.Contains("x:Key=\"ProgressTrackGradient\"", text);
}
[Fact]
public void StylesXaml_UsesDropShadowEffectForPrimaryButtonCardPanelAndStatusChip()
{
string text = ReadRepoFile("Resources", "Styles.xaml");
Assert.Contains("x:Key=\"PrimaryButton\"", text);
Assert.Contains("x:Key=\"CardPanel\"", text);
Assert.Contains("x:Key=\"StatusChip\"", text);
Assert.Contains("<effects:DropShadowEffect", text);
Assert.Contains("x:Key=\"PrimaryButton\" TargetType=\"Button\">", text);
Assert.Contains("x:Key=\"CardPanel\" TargetType=\"Border\">", text);
Assert.Contains("x:Key=\"StatusChip\" TargetType=\"Border\">", text);
}
[Fact]
public void MainWindowXaml_ContainsShellGlowAccentAndBoldActiveNavigationSetters()
{
string text = ReadRepoFile("MainWindow.xaml");
Assert.Contains("x:Key=\"ShellGlowAccent\"", text);
Assert.Contains("Background=\"{StaticResource ShellGlowAccent}\"", text);
Assert.Contains("BasedOn=\"{StaticResource NavButton}\"", text);
Assert.Contains("DataTrigger Binding=\"{Binding IsHomeActive}\" Value=\"True\">", text);
Assert.Contains("Setter Property=\"FontWeight\" Value=\"Bold\"", text);
}
private static string ReadRepoFile(params string[] parts)
{
string path = Path.GetFullPath(
Path.Combine([AppContext.BaseDirectory, "..", "..", "..", "..", .. parts]));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@LSPDFRManager.Tests/UiRedesignXamlContractTests.cs` around lines 14 - 53,
Replace implicit var locals with explicit nullable-aware string types: change
the local declarations named text (in tests like
StylesXaml_UsesDropShadowEffectForPrimaryButtonCardPanelAndStatusChip,
MainWindowXaml_ContainsShellGlowAccentAndBoldActiveNavigationSetters, etc.) from
var text = ReadRepoFile(...) to string text = ReadRepoFile(...), and change the
local path in ReadRepoFile from var path = Path.GetFullPath(...) to string path
= Path.GetFullPath(...). Ensure you use string (not string?) because
ReadRepoFile and Path.GetFullPath return non-null strings and update any other
var string-like locals in this file similarly.

Comment thread MainWindow.xaml
</Border.Background>
<StackPanel>
<TextBlock Text="LSPDFR MANAGER" FontSize="20" FontWeight="Bold" Foreground="White"/>
<TextBlock Text="v3.7.0 • Command Center" Margin="0,4,0,0" Foreground="#D6E7FF" FontSize="11"/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Sidebar version label is stale (v3.7.0).

The shell label should match the release version v3.7.3 to avoid user-facing version drift.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@MainWindow.xaml` at line 41, Update the hardcoded sidebar TextBlock text that
currently reads "v3.7.0  •  Command Center" to the correct release string
"v3.7.3  •  Command Center" in MainWindow.xaml (the TextBlock element showing
the version); alternatively replace the literal with a binding or resource that
pulls the app version (e.g., an ApplicationVersion or VersionLabel property) so
future releases don't require manual edits to the TextBlock text.

@rolling-codes
rolling-codes merged commit 07bc85f into master May 13, 2026
3 checks passed
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.

2 participants