Skip to content

Refactor options view display and add custom theme provider#481

Merged
DropSnorz merged 4 commits into
v2from
chore/options-display
Jun 17, 2026
Merged

Refactor options view display and add custom theme provider#481
DropSnorz merged 4 commits into
v2from
chore/options-display

Conversation

@DropSnorz

Copy link
Copy Markdown
Owner

No description provided.

@DropSnorz DropSnorz self-assigned this Jun 16, 2026
@DropSnorz DropSnorz added this to the 2.0.0 milestone Jun 16, 2026
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 79c7b146-f8e2-4814-b7ca-818f220da745

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Introduces a custom OwlPlugDarkTheme (replacing PrimerDark) with a full SCSS palette and Java class. Refactors OptionsController from a monolithic controller into a sidebar-navigation shell that delegates to four new sub-controllers (PluginScanOptionsController, InstallationOptionsController, ProjectsOptionsController, ApplicationOptionsController). Updates PluginFormat with a two-string model, renames selectMainTab to navigateToMainTab, and refactors ListDirectoryDialogController into a DirectoryChooser-based picker.

Changes

Options UI Refactor + Custom Dark Theme

Layer / File(s) Summary
Custom OwlPlugDarkTheme and application wiring
owlplug-theme/src/main/java/com/owlplug/theme/OwlPlugDarkTheme.java, owlplug-theme/src/main/scss/owlplug-dark.scss, owlplug-theme/.gitignore, owlplug-client/src/main/java/com/owlplug/OwlPlug.java, owlplug-client/src/main/java/com/owlplug/OwlPlugPreloader.java
Adds the OwlPlugDarkTheme class implementing atlantafx.base.theme.Theme, backed by a full SCSS dark palette with OwlPlug terracotta accents. Both OwlPlug and OwlPlugPreloader apply the new theme's user-agent stylesheet at startup instead of PrimerDark.
PluginFormat enum enrichment and PluginPathFragmentController update
owlplug-client/src/main/java/com/owlplug/plugin/model/PluginFormat.java, owlplug-client/src/main/java/com/owlplug/core/controllers/fragments/PluginPathFragmentController.java, owlplug-client/src/main/java/com/owlplug/core/controllers/dialogs/WelcomeDialogController.java, owlplug-client/src/main/resources/fxml/fragments/PluginPathFragment.fxml
PluginFormat gains separate name/fullName fields and new accessors; getText() is deprecated. PluginPathFragmentController constructor now takes PluginFormat and ApplicationDefaults, renders a PluginFormatBadgeView in the header, and changes the toggle label to "Scan plugins". WelcomeDialogController passes PluginFormat.* constants.
MainController navigation API and call-site updates
owlplug-client/src/main/java/com/owlplug/core/controllers/MainController.java, owlplug-client/src/main/java/com/owlplug/project/controllers/ProjectInfoController.java
PLUGINS_TAB_INDEX is replaced by EXPLORE_TAB_INDEX; PROJECTS_TAB_INDEX and OPTIONS_TAB_INDEX are added. selectMainTab is renamed to navigateToMainTab. ProjectInfoController call site is updated accordingly.
OptionsController navigation shell, OptionsView layout, and sidebar CSS
owlplug-client/src/main/java/com/owlplug/core/controllers/OptionsController.java, owlplug-client/src/main/resources/fxml/OptionsView.fxml, owlplug-client/src/main/resources/owlplug.css
OptionsController is refactored into a ToggleGroup-driven navigation shell; refreshView() delegates to four sub-controllers. OptionsView.fxml is restructured from an AnchorPane into a BorderPane with a navContainer sidebar and a StackPane content area embedding four fx:include subviews. CSS adds .options-sidebar, .options-nav-button, heading typography, and tab-pane collapse rules.
Four new Options sub-controllers and their FXML views
owlplug-client/src/main/java/com/owlplug/core/controllers/options/PluginScanOptionsController.java, .../InstallationOptionsController.java, .../ProjectsOptionsController.java, .../ApplicationOptionsController.java, owlplug-client/src/main/resources/fxml/options/*
Adds four Spring @Controller classes—plugin scan (native discovery, format path fragments, sync prefs), installation (organization checkboxes, live path preview), projects (project directory list), and application (telemetry, cache/data, about). Each is backed by a new ScrollPane-based FXML view wired via fx:controller.
ListDirectoryDialog refactor and ProjectsController routing
owlplug-client/src/main/java/com/owlplug/core/controllers/dialogs/ListDirectoryDialogController.java, owlplug-client/src/main/java/com/owlplug/project/controllers/ProjectsController.java, owlplug-client/src/main/resources/fxml/dialogs/ListDirectoryView.fxml, owlplug-client/src/main/resources/fxml/MainView.fxml, owlplug-client/src/main/resources/fxml/projects/ProjectsView.fxml
ListDirectoryDialogController drops ListChangeListener and uses DirectoryChooser; list changes are persisted via a lambda listener. ProjectsController replaces the dialog call with OptionsController.navigateToSection + MainController.navigateToMainTab. Unused Image/ImageView FXML imports are removed and the projects button icon is updated to FontIcon.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • DropSnorz/OwlPlug#479: Both PRs modify OwlPlug.java and OwlPlugPreloader.java to switch the user-agent stylesheet — the retrieved PR migrated to AtlantaFX PrimerDark, while this PR replaces it with the custom OwlPlugDarkTheme.
  • DropSnorz/OwlPlug#430: Directly touches the same PluginPathFragmentController constructor chain and its call sites in OptionsController/WelcomeDialogController that this PR also modifies.
  • DropSnorz/OwlPlug#449: Established the event-driven PreferencesChangedEvent refresh pattern in OptionsController and ListDirectoryDialogController that this PR's delegation refactor builds upon.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning No description was provided by the author, making it impossible to assess whether any description relates to the changeset. Add a pull request description explaining the refactoring objectives, motivation for splitting the options view into sections, and the purpose of the custom theme provider.
Docstring Coverage ⚠️ Warning Docstring coverage is 8.82% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: refactoring the options view into sections and adding a custom theme provider, which aligns with the substantial modifications to OptionsController, creation of section-specific controllers, and the new OwlPlugDarkTheme.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/options-display

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.

@DropSnorz

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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

🧹 Nitpick comments (4)
owlplug-client/src/main/resources/fxml/options/PluginScanOptionsView.fxml (2)

29-36: ⚡ Quick win

Editable Spinner may allow out-of-range values.

The loaderTimeoutSpinner is marked editable="true", allowing users to type values directly. Without additional validation, users could enter values outside the 0-3600 range defined in the SpinnerValueFactory. Consider either removing editable="true" or adding a TextFormatter to enforce range constraints.

🤖 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 `@owlplug-client/src/main/resources/fxml/options/PluginScanOptionsView.fxml`
around lines 29 - 36, The loaderTimeoutSpinner element is marked as
editable="true", which allows users to type values directly and bypass the range
validation defined in the SpinnerValueFactory. Remove the editable="true"
attribute from the loaderTimeoutSpinner Spinner element to prevent direct text
input and ensure users can only select values within the valid 0-3600 second
range using the spinner controls.

30-31: 💤 Low value

Grammatical issue: checkbox label implies continuation.

The label "Enable native plugin discovery using" grammatically expects the ComboBox value to complete the sentence. If no loader is selected initially, the sentence is incomplete. Consider rephrasing to "Enable native plugin discovery" and adding a separate Label like "Loader:" before the ComboBox for clarity.

🤖 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 `@owlplug-client/src/main/resources/fxml/options/PluginScanOptionsView.fxml`
around lines 30 - 31, The CheckBox with fx:id pluginNativeCheckbox has a label
"Enable native plugin discovery using" that grammatically expects completion by
the ComboBox value, making it incomplete when no loader is selected. Rephrase
the checkbox label text to "Enable native plugin discovery" by removing "using",
and add a new Label element before the pluginNativeComboBox with text like
"Loader:" to provide clear context for what the ComboBox represents without
relying on grammatical continuation.
owlplug-client/src/main/java/com/owlplug/core/controllers/OptionsController.java (1)

141-143: ⚡ Quick win

Consider adding bounds validation.

navigateToSection(int index) does not validate the index before accessing navToggleGroup.getToggles().get(index), which could throw IndexOutOfBoundsException if called with an invalid index. Since this is a public method, consider adding bounds checking.

🛡️ Proposed fix
 public void navigateToSection(int index) {
+  if (index < 0 || index >= navToggleGroup.getToggles().size()) {
+    throw new IllegalArgumentException("Invalid section index: " + index);
+  }
   navToggleGroup.getToggles().get(index).setSelected(true);
 }
🤖 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
`@owlplug-client/src/main/java/com/owlplug/core/controllers/OptionsController.java`
around lines 141 - 143, The navigateToSection(int index) method accesses
navToggleGroup.getToggles().get(index) without validating that the index is
within the bounds of the list, which could throw IndexOutOfBoundsException. Add
bounds validation before accessing the list to ensure the index is greater than
or equal to 0 and less than the size of the toggles collection. If the index is
invalid, either return early from the method or throw an
IllegalArgumentException with a descriptive message. Only call setSelected(true)
on the toggle if the index has been validated as valid.
owlplug-client/src/main/java/com/owlplug/core/controllers/MainController.java (1)

134-134: ⚡ Quick win

Replace magic number with constant.

The hardcoded 2 should be replaced with EXPLORE_TAB_INDEX for maintainability.

♻️ Proposed fix
-      if (newValue.intValue() == 2) {
+      if (newValue.intValue() == EXPLORE_TAB_INDEX) {
         exploreController.requestLayout();
       }
🤖 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
`@owlplug-client/src/main/java/com/owlplug/core/controllers/MainController.java`
at line 134, Replace the hardcoded magic number 2 in the condition at line 134
of the MainController.java file with the EXPLORE_TAB_INDEX constant. Change the
comparison from intValue() == 2 to intValue() == EXPLORE_TAB_INDEX to improve
code maintainability and make the intent of the comparison clearer.
🤖 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
`@owlplug-client/src/main/java/com/owlplug/core/controllers/dialogs/ListDirectoryDialogController.java`:
- Around line 97-109: The configure() method in ListDirectoryDialogController
attaches a ListChangeListener to observableItems every time it is called without
removing the previously attached listener. If configure() is invoked multiple
times, listeners accumulate on the same observable list, causing the preference
persistence and event publishing logic (the code that calls
getPreferences().putList() and publisher.publishEvent()) to execute multiple
times per list change. Store the ListChangeListener as a field variable and
remove the old listener before attaching a new one in the configure() method to
ensure only a single listener is active.

In
`@owlplug-client/src/main/java/com/owlplug/core/controllers/options/InstallationOptionsController.java`:
- Around line 114-126: The simulatePath method contains a path traversal
vulnerability where user input from storeDirectoryTextField is appended without
sanitization. Before appending the sub variable to the path via new File(path,
sub), validate that the subdirectory input does not contain path traversal
sequences like ".." or absolute path components that could escape the intended
base directory. Implement a sanitization function that normalizes the path and
verifies the resolved path stays within the base directory, or use a whitelist
approach to only allow safe directory names. This validation should occur before
constructing the File object at the line where storeDirectoryTextField input is
used.

In
`@owlplug-client/src/main/java/com/owlplug/core/controllers/options/PluginScanOptionsController.java`:
- Around line 106-111: The loaderTimeoutSpinner currently allows a minimum
timeout value of 0 seconds, which is impractical and does not align with the
default of 10 seconds. Either change the minimum constraint in the
SpinnerValueFactory.IntegerSpinnerValueFactory constructor from 0 to a practical
minimum like 1 (or 5) seconds, or add validation in the setScannerTimeout()
method to reject zero or negative timeout values before processing them. The
former approach (adjusting the spinner's lower bound) is simpler and prevents
invalid values at the UI level.
- Around line 131-136: Add a defensive null check in PluginScanTask before
calling getCurrentPluginLoader().isAvailable() to ensure consistency with the
defensive null checking pattern used in NativeHostService.loadPlugin(). Even
though initialization logic guarantees getCurrentPluginLoader() returns a
non-null DummyPluginLoader fallback, adding the null check maintains consistency
across the codebase and improves defensive programming practices.

In `@owlplug-theme/src/main/java/com/owlplug/theme/OwlPlugDarkTheme.java`:
- Around line 33-42: The getUserAgentStylesheetBSS() method attempts to load a
resource "owlplug-dark-bss.css" that does not exist, causing a
NullPointerException at runtime. Either create the missing SCSS source file
"owlplug-dark-bss.scss" in the appropriate source directory and add a
corresponding compilation rule in pom.xml (similar to the existing rule for
"owlplug-dark.scss" at line 84) to generate the CSS file during the build, or
remove the getUserAgentStylesheetBSS() method entirely if it is not required by
the implementation.

---

Nitpick comments:
In
`@owlplug-client/src/main/java/com/owlplug/core/controllers/MainController.java`:
- Line 134: Replace the hardcoded magic number 2 in the condition at line 134 of
the MainController.java file with the EXPLORE_TAB_INDEX constant. Change the
comparison from intValue() == 2 to intValue() == EXPLORE_TAB_INDEX to improve
code maintainability and make the intent of the comparison clearer.

In
`@owlplug-client/src/main/java/com/owlplug/core/controllers/OptionsController.java`:
- Around line 141-143: The navigateToSection(int index) method accesses
navToggleGroup.getToggles().get(index) without validating that the index is
within the bounds of the list, which could throw IndexOutOfBoundsException. Add
bounds validation before accessing the list to ensure the index is greater than
or equal to 0 and less than the size of the toggles collection. If the index is
invalid, either return early from the method or throw an
IllegalArgumentException with a descriptive message. Only call setSelected(true)
on the toggle if the index has been validated as valid.

In `@owlplug-client/src/main/resources/fxml/options/PluginScanOptionsView.fxml`:
- Around line 29-36: The loaderTimeoutSpinner element is marked as
editable="true", which allows users to type values directly and bypass the range
validation defined in the SpinnerValueFactory. Remove the editable="true"
attribute from the loaderTimeoutSpinner Spinner element to prevent direct text
input and ensure users can only select values within the valid 0-3600 second
range using the spinner controls.
- Around line 30-31: The CheckBox with fx:id pluginNativeCheckbox has a label
"Enable native plugin discovery using" that grammatically expects completion by
the ComboBox value, making it incomplete when no loader is selected. Rephrase
the checkbox label text to "Enable native plugin discovery" by removing "using",
and add a new Label element before the pluginNativeComboBox with text like
"Loader:" to provide clear context for what the ComboBox represents without
relying on grammatical continuation.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ecf5cd34-56ea-4866-b619-b0c5cdb47314

📥 Commits

Reviewing files that changed from the base of the PR and between 00ba14c and caec459.

⛔ Files ignored due to path filters (4)
  • owlplug-client/pom.xml is excluded by !**/*.xml
  • owlplug-client/src/main/resources/icons/heart-white-32.png is excluded by !**/*.png, !**/*.png
  • owlplug-theme/pom.xml is excluded by !**/*.xml
  • pom.xml is excluded by !**/*.xml
📒 Files selected for processing (27)
  • owlplug-client/src/main/java/com/owlplug/OwlPlug.java
  • owlplug-client/src/main/java/com/owlplug/OwlPlugPreloader.java
  • owlplug-client/src/main/java/com/owlplug/core/controllers/MainController.java
  • owlplug-client/src/main/java/com/owlplug/core/controllers/OptionsController.java
  • owlplug-client/src/main/java/com/owlplug/core/controllers/dialogs/ListDirectoryDialogController.java
  • owlplug-client/src/main/java/com/owlplug/core/controllers/dialogs/WelcomeDialogController.java
  • owlplug-client/src/main/java/com/owlplug/core/controllers/fragments/PluginPathFragmentController.java
  • owlplug-client/src/main/java/com/owlplug/core/controllers/options/ApplicationOptionsController.java
  • owlplug-client/src/main/java/com/owlplug/core/controllers/options/InstallationOptionsController.java
  • owlplug-client/src/main/java/com/owlplug/core/controllers/options/PluginScanOptionsController.java
  • owlplug-client/src/main/java/com/owlplug/core/controllers/options/ProjectsOptionsController.java
  • owlplug-client/src/main/java/com/owlplug/plugin/model/PluginFormat.java
  • owlplug-client/src/main/java/com/owlplug/project/controllers/ProjectInfoController.java
  • owlplug-client/src/main/java/com/owlplug/project/controllers/ProjectsController.java
  • owlplug-client/src/main/resources/fxml/MainView.fxml
  • owlplug-client/src/main/resources/fxml/OptionsView.fxml
  • owlplug-client/src/main/resources/fxml/dialogs/ListDirectoryView.fxml
  • owlplug-client/src/main/resources/fxml/fragments/PluginPathFragment.fxml
  • owlplug-client/src/main/resources/fxml/options/ApplicationOptionsView.fxml
  • owlplug-client/src/main/resources/fxml/options/InstallationOptionsView.fxml
  • owlplug-client/src/main/resources/fxml/options/PluginScanOptionsView.fxml
  • owlplug-client/src/main/resources/fxml/options/ProjectsOptionsView.fxml
  • owlplug-client/src/main/resources/fxml/projects/ProjectsView.fxml
  • owlplug-client/src/main/resources/owlplug.css
  • owlplug-theme/.gitignore
  • owlplug-theme/src/main/java/com/owlplug/theme/OwlPlugDarkTheme.java
  • owlplug-theme/src/main/scss/owlplug-dark.scss
💤 Files with no reviewable changes (1)
  • owlplug-client/src/main/resources/fxml/MainView.fxml

Comment thread owlplug-theme/src/main/java/com/owlplug/theme/OwlPlugDarkTheme.java Outdated
@DropSnorz DropSnorz merged commit 0a740fe into v2 Jun 17, 2026
3 of 4 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.

1 participant