Release v3.7.3: LSPDFR UI redesign - #15
Conversation
📝 WalkthroughSummary by CodeRabbitRelease v3.7.3
WalkthroughPR ChangesUI/UX Redesign and Design System
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Review Summary by QodoRelease v3.7.3: LSPDFR UI redesign with police-blue theme
WalkthroughsDescription• 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 Diagramflowchart 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"]
File Changes1. LSPDFRManager.csproj
|
Code Review by Qodo
1. Missing XAML style keys
|
| <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> |
There was a problem hiding this comment.
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
| <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> |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
📒 Files selected for processing (7)
LSPDFRManager.csprojMainWindow.xamlRELEASE_v3.7.3.mdResources/Colors.xamlResources/Styles.xamlViews/DashboardView.xamlViews/LibraryView.xaml
| <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> |
There was a problem hiding this comment.
🧩 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.csRepository: 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.csRepository: rolling-codes/LSPDFRManager
Length of output: 1293
🏁 Script executed:
# Search for ModConfigView or Config view directly
find . -name '*View.xaml*' | grep -i configRepository: rolling-codes/LSPDFRManager
Length of output: 122
🏁 Script executed:
# Check what ConfigVM references - should find ModConfigViewModel
rg -n 'ConfigVM|ModConfigViewModel' ViewModels/MainViewModel.csRepository: 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.
| <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> |
There was a problem hiding this comment.
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.
| <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"/> |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (3)
Views/DashboardView.xaml (2)
57-58:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAvoid rendering raw boolean values in the LSPDFR CORE metric.
True/Falseis 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 winStatus 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 Confignavigation 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.xamlshould 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
📒 Files selected for processing (6)
LSPDFRManager.Tests/UiRedesignXamlContractTests.csMainWindow.xamlResources/Colors.xamlResources/Styles.xamlViews/DashboardView.xamlViews/LibraryView.xaml
| 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])); |
There was a problem hiding this comment.
🛠️ 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.
| 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.
| </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"/> |
There was a problem hiding this comment.
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.
LSPDFR Manager v3.7.3
This release delivers a major UI refresh with an LSPDFR-aligned command-center visual system.
Highlights
Visual System
Resources/Colors.xaml.Resources/Styles.xaml:ShellSidebar,ShellContentPanelMetricCard,ActionGroupCard,TelemetryCardStatusChip,LibraryToolbarCard,LibraryRowCardVersion Consistency
3.7.3inLSPDFRManager.csproj.v3.7.3.Known Scope Boundaries
Validation
dotnet restoredotnet build -c Releasedotnet testDownload
LSPDFRManager-v3.7.3-win-x64.zip