Skip to content

Add Platinum & Ducat counting to 'Auto Add' window#411

Open
occluder wants to merge 7 commits into
WFCD:masterfrom
occluder:plat-ducat-summary
Open

Add Platinum & Ducat counting to 'Auto Add' window#411
occluder wants to merge 7 commits into
WFCD:masterfrom
occluder:plat-ducat-summary

Conversation

@occluder
Copy link
Copy Markdown

@occluder occluder commented Feb 17, 2026

Display cumulative Platinum and Ducats earned in 'Auto Add' view by; adding TotalPlatinum and TotalDucats to AutoAddViewModel.
7LHtle1Owl

Totals update automatically as items are added/removed.

I am however running into an issue with updating values when a relic reward option is changed (see line 118 here). So far, have not had any success investigating what is causing this, so this PR will be a draft until the issue and considerations below are addressed. Any help with this would be appreciated.

Considerations

  • Does this contain a new dependency? No
  • Does this introduce opinionated data formatting or manual data entry? Maybe (See changes to WFInfo/AutoCount.xaml)
  • Does this pr include updated data files in a separate commit that can be reverted for a clean code-only pr? No
  • Have I run the linter? No
  • Is is a bug fix, feature request, or enhancement? Enhancement

Summary by CodeRabbit

  • New Features
    • Real-time aggregate totals for Platinum and Ducats added; totals update automatically as items change.
  • UI
    • Totals are prominently displayed in the bottom bar with icons.
    • Layout adjusted to three columns so Save and Dismiss actions sit beside the totals.
  • Behavior
    • Selection and item changes now propagate immediately for a more responsive experience.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 17, 2026

📝 Walkthrough

Walkthrough

Adds aggregate tracking for Platinum and Ducats to AutoAdd: ViewModel properties, per-item parsed value properties, and event-driven recomputation on collection or item option changes; UI updated to display totals and adjust layout/commands.

Changes

Cohort / File(s) Summary
ViewModel & Item logic
WFInfo/AutoAddViewModel.cs
Added TotalPlatinum (double) and TotalDucats (int) with change notifications. Totals recomputed on collection changes and when items raise PropertyChanged for PlatinumValue/DucatValue. AutoAddSingleItem now exposes PlatinumValue and DucatValue and updates them when ActiveOption changes; add/remove now trigger totals recalculation.
UI: totals display & layout
WFInfo/AutoCount.xaml
DataGrid SelectedItem binding now uses UpdateSourceTrigger=PropertyChanged. Bottom Grid changed to three columns; replaced label with a StackPanel showing "Total:", platinum icon + TotalPlatinum, ducat icon + TotalDucats. "Save all" moved to column 1, "Dismiss all" to column 2.

Sequence Diagram

sequenceDiagram
    participant UI as AutoCount UI
    participant Item as AutoAddSingleItem
    participant VM as AutoAddViewModel

    UI->>Item: User selects/changes option
    Item->>Item: Parse new PlatinumValue/DucatValue\nraise PropertyChanged for values
    Item->>VM: Notify PropertyChanged (PlatinumValue/DucatValue)
    VM->>VM: RecalculateTotals() (iterate items or adjust by delta)
    VM->>UI: Raise PropertyChanged (TotalPlatinum, TotalDucats)
    UI->>UI: Refresh displayed totals
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through options, parsed each prize,

Counting platinum with bright, eager eyes,
Ducats lined up in tidy rows,
Totals update as each choice grows,
A tiny rabbit keeps the sums precise.

🚥 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding Platinum & Ducat counting functionality to the 'Auto Add' window, which aligns with the substantive changes shown in the raw summary.
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

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.

@D1firehail
Copy link
Copy Markdown
Contributor

Adding UpdateSourceTrigger=PropertyChanged to the binding fixes it. Found it in this StackOverflow answer.

Mode=TwoWay is the default behaviour of SelectedItem, so you don't need to explicitly state it. It's fine to keep for the sake of readability, though.

@occluder
Copy link
Copy Markdown
Author

occluder commented Feb 17, 2026

Thank you for the remedy to my headache, I was jumping around in code trying to debug it 😅

I believe the functionality to be complete now, so I will open the PR for review. Code has to be looked at, as I do not fully understand what the considerations ask of me

@occluder occluder marked this pull request as ready for review February 17, 2026 18:18
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
WFInfo/AutoAddViewModel.cs (2)

100-100: Public mutable field _parent with underscore prefix — consider encapsulating.

By convention, underscore-prefixed members are private backing fields. Exposing _parent as a public field allows any caller to mutate it. Consider making it a read-only property set via the constructor, or at least internal.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@WFInfo/AutoAddViewModel.cs` at line 100, The public mutable field _parent on
AutoAddViewModel breaks encapsulation and uses an underscore prefix reserved for
private backing fields; change _parent to a private readonly field or expose it
as a read-only property (e.g., Parent) set via the AutoAddViewModel constructor
(or at minimum mark it internal instead of public) so external callers cannot
mutate it directly and the naming follows conventions; update any callers to use
the new constructor/property.

134-149: Constructor relies on _parent being null when ActiveOption is first set — fragile ordering.

ActiveOption is assigned at line 141 before _parent is set at line 147. This works today because the null-conditional _parent?.UpdateTotalsForOptionChange(...) is a no-op, and addItem separately accounts for the initial totals. However, if anyone reorders these two assignments (e.g. setting _parent first), the totals will be double-counted.

Consider moving _parent = parent; before the ActiveOption assignment and removing the redundant UpdateTotalsForOptionChange call in addItem, or add a brief comment explaining the required ordering.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@WFInfo/AutoAddViewModel.cs` around lines 134 - 149, Constructor
AutoAddSingleItem sets ActiveOption before assigning _parent which makes
behavior ordering-dependent; move the assignment _parent = parent to before
setting ActiveOption inside AutoAddSingleItem (or alternatively remove the
redundant call to UpdateTotalsForOptionChange inside addItem), so that
ActiveOption's setter can safely call _parent?.UpdateTotalsForOptionChange
without relying on null ordering; update or add a short comment on the
constructor explaining the intended ordering if you choose to keep the current
sequence.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@WFInfo/AutoAddViewModel.cs`:
- Around line 64-95: UpdateTotalsForOptionChange currently casts the result of
Main.dataBase.marketData.GetValue(previousOption/newOption) to JObject and then
indexes into it, which throws a NullReferenceException when GetValue returns
null; update the method to null-guard each lookup (check the result of GetValue
and ensure previousJob/newJob is not null before accessing ["plat"] or
["ducats"]), or better extract a small helper (e.g. TryGetMarketValues(string
key, out double plat, out int ducats) used by UpdateTotalsForOptionChange) to
centralize the GetValue, null-check, parsing (double.TryParse/int.TryParse) and
return success/failure so you avoid duplicated code and prevent NREs when a key
is missing.

---

Nitpick comments:
In `@WFInfo/AutoAddViewModel.cs`:
- Line 100: The public mutable field _parent on AutoAddViewModel breaks
encapsulation and uses an underscore prefix reserved for private backing fields;
change _parent to a private readonly field or expose it as a read-only property
(e.g., Parent) set via the AutoAddViewModel constructor (or at minimum mark it
internal instead of public) so external callers cannot mutate it directly and
the naming follows conventions; update any callers to use the new
constructor/property.
- Around line 134-149: Constructor AutoAddSingleItem sets ActiveOption before
assigning _parent which makes behavior ordering-dependent; move the assignment
_parent = parent to before setting ActiveOption inside AutoAddSingleItem (or
alternatively remove the redundant call to UpdateTotalsForOptionChange inside
addItem), so that ActiveOption's setter can safely call
_parent?.UpdateTotalsForOptionChange without relying on null ordering; update or
add a short comment on the constructor explaining the intended ordering if you
choose to keep the current sequence.

Comment thread WFInfo/AutoAddViewModel.cs Outdated
@D1firehail
Copy link
Copy Markdown
Contributor

I suggest letting each AutoAddSingleItem keep track of its own plat/ducat value, with updates triggering AutoAddViewModel to re-sum the items. That should solve the rounding issues of the incremental approach you're using now.

@occluder
Copy link
Copy Markdown
Author

occluder commented Feb 18, 2026

I have deliberately not implemented CodeRabbit's suggestions above as they require a higher language version. The code to get an item's value is copy pasted from another part of the codebase. Let me know if any changes are necessary

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 18, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":500,"request":{"method":"PATCH","url":"https://api.github.com/repos/WFCD/WFinfo/issues/comments/3914120901","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- walkthrough_start -->\n\n<details>\n<summary>📝 Walkthrough</summary>\n\n## Walkthrough\n\nAdds aggregate TotalPlatinum (double) and TotalDucats (int) to AutoAddViewModel with automatic recalculation on collection/item changes and when an item's ActiveOption changes. AutoAddSingleItem now tracks parsed Platinum/Ducat values and updates the parent. UI (AutoCount.xaml) displays these totals and adjusts layout/bindings.\n\n## Changes\n\n|Cohort / File(s)|Summary|\n|---|---|\n|**ViewModel: totals & wiring** <br> `WFInfo/AutoAddViewModel.cs`|Added `TotalPlatinum` (double) and `TotalDucats` (int) with private setters and PropertyChanged notifications. Added backing fields, `RecalculateTotals()`, `ItemChanged` and `CollectionChanged` handlers, collection subscription/unsubscription, and destructor cleanup. Item add/remove now manage child event subscriptions and trigger recalculation.|\n|**Item: option/value propagation** <br> `WFInfo/AutoAddViewModel.cs` (class `AutoAddSingleItem`)|Added `_activeOption` field, `PlatinumValue` (double) and `DucatValue` (int) properties, numeric parsing style constant, `UpdateValues()` to parse/fetch market values with fallbacks, and ActiveOption setter logic to update values and notify parent. Preserves public parent reference for communication.|\n|**UI: totals display & bindings** <br> `WFInfo/AutoCount.xaml`|DataGrid SelectedItem binding now uses `UpdateSourceTrigger=PropertyChanged`. Bottom Grid changed from 2→3 columns. Replaced label with StackPanel showing \"Total:\", platinum icon and `TotalPlatinum`, ducat icon and `TotalDucats`. \"Save all\" moved to column 1, \"Dismiss all\" to column 2.|\n\n## Sequence Diagram\n\n```mermaid\nsequenceDiagram\n    participant UI as AutoCount UI\n    participant Item as AutoAddSingleItem\n    participant VM as AutoAddViewModel\n    participant Market as MarketData\n\n    UI->>Item: Change ActiveOption (user)\n    Item->>Item: set ActiveOption\\ncall UpdateValues()\n    Item->>Market: request platinum/ducat for option\n    Market-->>Item: return values (or null)\n    Item->>Item: parse values (NumberStyles)\n    Item->>VM: notify parent (PropertyChanged / direct call)\n    VM->>VM: ItemChanged -> RecalculateTotals()\n    VM->>VM: sum Platinum/Ducats across collection\n    VM->>UI: PropertyChanged TotalPlatinum / TotalDucats\n    UI->>UI: update totals display\n```\n\n## Estimated code review effort\n\n🎯 3 (Moderate) | ⏱️ ~20 minutes\n\n## Poem\n\n> 🐰 I rabbit-hop through code and sums,  \n> I count the platinum, clang the drums,  \n> When options flip and values sway,  \n> I nudge the totals—every day,  \n> Now UI gleams with numbers plumb! ✨\n\n</details>\n\n<!-- walkthrough_end -->\n\n\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 2 | ❌ 1</summary>\n\n### ❌ Failed checks (1 warning)\n\n|     Check name     | Status     | Explanation                                                                          | Resolution                                                                         |\n| :----------------: | :--------- | :----------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------- |\n| 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. |\n\n<details>\n<summary>✅ Passed checks (2 passed)</summary>\n\n|     Check name    | Status   | Explanation                                                                                                                     |\n| :---------------: | :------- | :------------------------------------------------------------------------------------------------------------------------------ |\n| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled.                                                                     |\n|    Title check    | ✅ Passed | The title accurately describes the main feature added: displaying cumulative Platinum and Ducats totals in the Auto Add window. |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing Touches</summary>\n\n- [ ] <!-- {\"checkboxId\": \"7962f53c-55bc-4827-bfbf-6a18da830691\"} --> 📝 Generate docstrings\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"07f1e7d6-8a8e-4e23-9900-8731c2c87f58\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Post copyable unit tests in a comment\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=WFCD/WFinfo&utm_content=411)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n\n<!-- internal state start -->\n\n\n<!-- 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 -->\n\n<!-- internal state end -->"},"request":{"retryCount":3,"retries":3,"retryAfter":16}}}

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
WFInfo/AutoAddViewModel.cs (1)

215-222: ⚠️ Potential issue | 🟡 Minor

RaisePropertyChanged() in RemoveFromParent fires for a non-existent property.

With no explicit argument, [CallerMemberName] injects "RemoveFromParent" as the property name. No property by that name exists, so all listeners receive a spurious change event. If the intent is to signal that the item was removed, the notification is better placed on an actual property; if there is no such intent, the call should be removed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@WFInfo/AutoAddViewModel.cs` around lines 215 - 222, The
RaisePropertyChanged() call in RemoveFromParent fires a spurious notification
because CallerMemberName will emit "RemoveFromParent" which is not a real
property; fix by either removing the RaisePropertyChanged() call entirely from
RemoveFromParent if no property change should be announced, or replace it with a
call that supplies the actual property name that changed (e.g.,
RaisePropertyChanged("Parent") or the relevant property like "IsRemoved" or the
collection property that observers expect) and ensure that property (or an
appropriate boolean flag) exists on the class; locate the RemoveFromParent
method and the _parent.removeItem(this) call to apply the change.
🧹 Nitpick comments (2)
WFInfo/AutoAddViewModel.cs (2)

58-63: Redundant RecalculateTotals() call in removeItem.

_itemList.Remove(item) already fires CollectionChanged, which calls RecalculateTotals(). The explicit call on line 62 is redundant.

♻️ Proposed fix
         public void removeItem(AutoAddSingleItem item)
         {
             item.PropertyChanged -= ItemChanged;
             _itemList.Remove(item);
-            RecalculateTotals();
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@WFInfo/AutoAddViewModel.cs` around lines 58 - 63, In
removeItem(AutoAddSingleItem item) the explicit call to RecalculateTotals() is
redundant because _itemList.Remove(item) triggers the CollectionChanged handler
that already calls RecalculateTotals; remove the direct RecalculateTotals()
invocation (keep the PropertyChanged unsubscribe and the _itemList.Remove(item)
call intact) so totals are only recalculated via the collection change event.

27-44: Consider using SetField to avoid spurious property-change notifications.

Both TotalPlatinum and TotalDucats unconditionally call RaisePropertyChanged() even when the computed total is identical to the previous value. Since RecalculateTotals fires on every ItemChanged and every CollectionChanged, this can produce unnecessary UI re-renders. The SetField helper on the INPC base class already provides equality-gated notification.

♻️ Proposed refactor
-        public double TotalPlatinum
-        {
-            get => _totalPlatinum;
-            private set
-            {
-                _totalPlatinum = value;
-                RaisePropertyChanged();
-            }
-        }
-        public int TotalDucats
-        {
-            get => _totalDucats;
-            private set
-            {
-                _totalDucats = value;
-                RaisePropertyChanged();
-            }
-        }
+        public double TotalPlatinum
+        {
+            get => _totalPlatinum;
+            private set => SetField(ref _totalPlatinum, value);
+        }
+        public int TotalDucats
+        {
+            get => _totalDucats;
+            private set => SetField(ref _totalDucats, value);
+        }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@WFInfo/AutoAddViewModel.cs` around lines 27 - 44, The property setters for
TotalPlatinum and TotalDucats currently assign and call RaisePropertyChanged
unconditionally, causing spurious notifications when RecalculateTotals runs on
ItemChanged/CollectionChanged; change both setters to use the INPC base helper
SetField (or its equivalent) to perform equality-checked assignment and only
raise PropertyChanged when the value actually changes so UI rerenders are
avoided.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@WFInfo/AutoAddViewModel.cs`:
- Around line 84-87: Remove the finalizer ~AutoAddViewModel() that unsubscribes
_itemList.CollectionChanged because detaching managed events in a finalizer is
unsafe and unnecessary; either delete the finalizer entirely from the
AutoAddViewModel class, or if explicit teardown is required implement
IDisposable on AutoAddViewModel and move the _itemList.CollectionChanged -=
CollectionChanged logic into Dispose() (ensuring Dispose is idempotent and
called by consumers).
- Around line 148-150: The ternary in ActiveOption uses a dead null check on
options (new ObservableCollection<string>(options) already throws if options is
null); remove the redundant "options != null" and read the selected value from
the newly assigned RewardOptions collection instead. Concretely, keep the
activeIndex bounds logic, and set ActiveOption = activeIndex >= 0 ?
RewardOptions[activeIndex] : "" (referencing RewardOptions, ActiveOption,
activeIndex and the ObservableCollection<string>(options) construction).

---

Outside diff comments:
In `@WFInfo/AutoAddViewModel.cs`:
- Around line 215-222: The RaisePropertyChanged() call in RemoveFromParent fires
a spurious notification because CallerMemberName will emit "RemoveFromParent"
which is not a real property; fix by either removing the RaisePropertyChanged()
call entirely from RemoveFromParent if no property change should be announced,
or replace it with a call that supplies the actual property name that changed
(e.g., RaisePropertyChanged("Parent") or the relevant property like "IsRemoved"
or the collection property that observers expect) and ensure that property (or
an appropriate boolean flag) exists on the class; locate the RemoveFromParent
method and the _parent.removeItem(this) call to apply the change.

---

Duplicate comments:
In `@WFInfo/AutoAddViewModel.cs`:
- Around line 156-171: UpdateValues currently casts the result of
Main.dataBase.marketData.GetValue(ActiveOption) to JObject and then dereferences
job["plat"] which throws NullReferenceException when the key is missing; modify
UpdateValues to capture the result into a JToken/JObject variable from
Main.dataBase.marketData.GetValue(ActiveOption), check for null (or use
TryGetValue if available) before accessing job["plat"] and job["ducats"], and if
missing set PlatinumValue and DucatValue to 0 (or the existing else-path) so
missing marketData entries (e.g. "Forma Blueprint") no longer crash the UI.

---

Nitpick comments:
In `@WFInfo/AutoAddViewModel.cs`:
- Around line 58-63: In removeItem(AutoAddSingleItem item) the explicit call to
RecalculateTotals() is redundant because _itemList.Remove(item) triggers the
CollectionChanged handler that already calls RecalculateTotals; remove the
direct RecalculateTotals() invocation (keep the PropertyChanged unsubscribe and
the _itemList.Remove(item) call intact) so totals are only recalculated via the
collection change event.
- Around line 27-44: The property setters for TotalPlatinum and TotalDucats
currently assign and call RaisePropertyChanged unconditionally, causing spurious
notifications when RecalculateTotals runs on ItemChanged/CollectionChanged;
change both setters to use the INPC base helper SetField (or its equivalent) to
perform equality-checked assignment and only raise PropertyChanged when the
value actually changes so UI rerenders are avoided.

Comment thread WFInfo/AutoAddViewModel.cs Outdated
Comment thread WFInfo/AutoAddViewModel.cs Outdated
@occluder
Copy link
Copy Markdown
Author

occluder commented Mar 2, 2026

@D1firehail Any chance this could be looked at again? I'd like to have things ironed out before someone with merge capability takes a look

@D1firehail
Copy link
Copy Markdown
Contributor

Yeah no problem. Not sure I'll have time today, but should be able to within a few days at most.

{
public AutoAddViewModel _parent;

private const NumberStyles style = NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands | NumberStyles.AllowExponent;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The necessity of this confused me a bit, but apparently the overload of double.TryParse that accepts a CultureInfo without NumberStyles doesn't exist in our .NET version.

@D1firehail
Copy link
Copy Markdown
Contributor

LGTM

I could imagine similar info (and ducat efficiency) on a per-item level to be somewhat useful, but it's far from necessary and would require UI space considerations. No need to bother until/unless someone actually requests it.

@occluder
Copy link
Copy Markdown
Author

occluder commented Mar 3, 2026

Initially I had thoughts about having a plat/ducats per minute counter, but I have lost interest in that thought. If someone is interested in any of the mentioned ideas I would be happy to put in the effort

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
WFInfo/AutoAddViewModel.cs (1)

156-171: ⚠️ Potential issue | 🔴 Critical

Null-reference crash if the option is not found in marketData.

GetValue(ActiveOption) returns null for items like "Forma Blueprint" that aren't in market data. The subsequent indexer access job["plat"] throws NullReferenceException, crashing the UI thread.

🐛 Proposed fix — guard against missing market data entries
         private void UpdateValues()
         {
             if (!string.IsNullOrEmpty(ActiveOption))
             {
-                JObject job = (JObject)Main.dataBase.marketData.GetValue(ActiveOption);
-                string plat = job["plat"].ToObject<string>();
-                string ducats = job["ducats"].ToObject<string>();
-                PlatinumValue = double.TryParse(plat, style, CultureInfo.InvariantCulture, out double platValue) ? platValue : 0;
-                DucatValue = int.TryParse(ducats, style, CultureInfo.InvariantCulture, out int ducatValue) ? ducatValue : 0;
+                JObject job = Main.dataBase.marketData.GetValue(ActiveOption) as JObject;
+                if (job != null)
+                {
+                    string plat = job["plat"]?.ToObject<string>();
+                    string ducats = job["ducats"]?.ToObject<string>();
+                    PlatinumValue = double.TryParse(plat, style, CultureInfo.InvariantCulture, out double platValue) ? platValue : 0;
+                    DucatValue = int.TryParse(ducats, style, CultureInfo.InvariantCulture, out int ducatValue) ? ducatValue : 0;
+                }
+                else
+                {
+                    PlatinumValue = 0;
+                    DucatValue = 0;
+                }
             }
             else
             {
                 PlatinumValue = 0;
                 DucatValue = 0;
             }
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@WFInfo/AutoAddViewModel.cs` around lines 156 - 171, UpdateValues currently
assumes Main.dataBase.marketData.GetValue(ActiveOption) returns a JObject, but
GetValue can return null for missing items causing job["plat"] to throw; modify
UpdateValues to check the result of
Main.dataBase.marketData.GetValue(ActiveOption) (and/or use TryGetValue) and
treat a null job as "not found" by setting PlatinumValue and DucatValue to 0,
and additionally guard accesses to job["plat"] and job["ducats"] (check for null
JToken before ToObject) so parsing only occurs when the tokens exist.
🧹 Nitpick comments (1)
WFInfo/AutoAddViewModel.cs (1)

64-80: Minor inefficiency: RecalculateTotals() invoked twice per option change.

When UpdateValues() sets both PlatinumValue and DucatValue, each raises PropertyChanged, triggering two consecutive RecalculateTotals() calls. For small collections this is negligible, but you could batch by deferring recalculation.

♻️ Proposed optimization — debounce or batch updates
+        private bool _recalculationPending;
+
         private void ItemChanged(object sender, PropertyChangedEventArgs e)
         {
             if (e.PropertyName == nameof(AutoAddSingleItem.PlatinumValue) || e.PropertyName == nameof(AutoAddSingleItem.DucatValue))
             {
-                RecalculateTotals();
+                if (!_recalculationPending)
+                {
+                    _recalculationPending = true;
+                    System.Windows.Application.Current.Dispatcher.InvokeAsync(() =>
+                    {
+                        RecalculateTotals();
+                        _recalculationPending = false;
+                    }, System.Windows.Threading.DispatcherPriority.DataBind);
+                }
             }
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@WFInfo/AutoAddViewModel.cs` around lines 64 - 80, ItemChanged currently calls
RecalculateTotals for each PropertyChanged (so when UpdateValues changes both
PlatinumValue and DucatValue it recalculates twice); modify the class to
batch/suppress redundant recalculations by introducing a short-lived suppression
flag or BeginUpdate/EndUpdate pattern: add a boolean (e.g. _suppressRecalculate)
and update ItemChanged to set the flag when UpdateValues is running (or have
UpdateValues call BeginUpdate/EndUpdate), have RecalculateTotals no-op when
suppressed and perform a single recalculation on EndUpdate (or when clearing the
flag); reference ItemChanged, RecalculateTotals, CollectionChanged, and
AutoAddSingleItem.PlatinumValue/ Duca tValue to locate where to add the
flag/begin-end calls.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@WFInfo/AutoAddViewModel.cs`:
- Around line 156-171: UpdateValues currently assumes
Main.dataBase.marketData.GetValue(ActiveOption) returns a JObject, but GetValue
can return null for missing items causing job["plat"] to throw; modify
UpdateValues to check the result of
Main.dataBase.marketData.GetValue(ActiveOption) (and/or use TryGetValue) and
treat a null job as "not found" by setting PlatinumValue and DucatValue to 0,
and additionally guard accesses to job["plat"] and job["ducats"] (check for null
JToken before ToObject) so parsing only occurs when the tokens exist.

---

Nitpick comments:
In `@WFInfo/AutoAddViewModel.cs`:
- Around line 64-80: ItemChanged currently calls RecalculateTotals for each
PropertyChanged (so when UpdateValues changes both PlatinumValue and DucatValue
it recalculates twice); modify the class to batch/suppress redundant
recalculations by introducing a short-lived suppression flag or
BeginUpdate/EndUpdate pattern: add a boolean (e.g. _suppressRecalculate) and
update ItemChanged to set the flag when UpdateValues is running (or have
UpdateValues call BeginUpdate/EndUpdate), have RecalculateTotals no-op when
suppressed and perform a single recalculation on EndUpdate (or when clearing the
flag); reference ItemChanged, RecalculateTotals, CollectionChanged, and
AutoAddSingleItem.PlatinumValue/ Duca tValue to locate where to add the
flag/begin-end calls.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 31bb5727-a3d4-4a3e-8ffa-86edf84607e1

📥 Commits

Reviewing files that changed from the base of the PR and between dc6f7e7 and 905722a.

📒 Files selected for processing (1)
  • WFInfo/AutoAddViewModel.cs

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