Skip to content

FEATURE: Calculator Plugin History#4454

Open
01Dri wants to merge 9 commits into
Flow-Launcher:devfrom
01Dri:feature/history-calc-plugin
Open

FEATURE: Calculator Plugin History#4454
01Dri wants to merge 9 commits into
Flow-Launcher:devfrom
01Dri:feature/history-calc-plugin

Conversation

@01Dri
Copy link
Copy Markdown
Contributor

@01Dri 01Dri commented May 10, 2026

Changes

  • Added History and HistoryItem objects to persist calculator results
  • Added a plugin setting to enable or disable history
  • Implemented a debounce strategy to reduce unnecessary history entries

Debounce Strategy

Currently, the calculator plugin returns results even when the Enter key is not pressed. Because of this behavior, every partial expression can be added to the history while the user is typing.

For example, while the user is building the expression:

1+2+3+4+5

Without a debounce mechanism, each intermediate expression is stored in history, generating multiple unnecessary entries.

With the debounce strategy, the plugin waits for a short delay before saving the result. This ensures that only the final or more complete expression is added to history.

Without debounce

  • 1
  • 1+2
  • 1+2+3
  • 1+2+3+4
  • 1+2+3+4+5

With debounce

  • 1+2+3+4+5

This keeps the history cleaner and improves the overall user experience.

Note: I'm not fully satisfied with the result title and subtitles yet, so suggestions are welcome!

1 2

Summary by cubic

Adds an optional calculation history to the calculator with an 800ms debounce and a 5-item cap. Shows recent calculations below the current result when enabled and improves copy-to-clipboard handling.

  • Summary of changes

    • Changed: Query returns the current result plus recent history items when EnableHistory is on, excluding the active expression. NaN and incomplete expressions are skipped. Clipboard copy is now handled by a reusable helper.
    • Added: Local History store with 800ms debounce and 5-item limit; HistoryItem with badge icon, timestamp, and subtitle; EnableHistory setting (off by default); new localized strings; history icon asset. Tests cover history on/off behavior and use a deterministic debounce flush.
    • Removed: Inline copy logic from Query (now centralized).
    • Memory impact: Minimal. Up to 5 history items plus a debounce timer.
    • Security risks: Low. History is off by default, stored locally, and may include user expressions/results. No external transmission.
    • Unit tests: Added tests for storing history when enabled, excluding when disabled, and verifying stored fields; tests reset and flush history between runs.
  • Release Note

    • You can now enable a simple calculator history to quickly reuse recent calculations.

Written for commit 6d93ce0. Summary will update on new commits.

@github-actions github-actions Bot added this to the 2.2.0 milestone May 10, 2026
@coderabbitai coderabbitai Bot added the enhancement New feature or request label May 10, 2026
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 8 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Flow.Launcher.Test/Plugins/CalculatorTest.cs">

<violation number="1" location="Flow.Launcher.Test/Plugins/CalculatorTest.cs:98">
P2: History persistence is debounced, so asserting `Items.Count` immediately after `Query` is timing-flaky and may fail before the timer flushes the pending item.</violation>
</file>

<file name="Plugins/Flow.Launcher.Plugin.Calculator/Main.cs">

<violation number="1" location="Plugins/Flow.Launcher.Plugin.Calculator/Main.cs:156">
P2: History entries are persisted even when history is disabled in settings.</violation>
</file>

<file name="Plugins/Flow.Launcher.Plugin.Calculator/Storage/History.cs">

<violation number="1" location="Plugins/Flow.Launcher.Plugin.Calculator/Storage/History.cs:72">
P2: Capacity eviction removes the wrong history item because list order is not kept aligned with recency. `Items.RemoveAt(0)` assumes FIFO ordering, but `Refresh` updates `CalculatedAt` without repositioning the item, so a recently-refreshed item at index 0 can be incorrectly evicted when capacity is reached.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread Flow.Launcher.Test/Plugins/CalculatorTest.cs
};


if (isValidResultToAddHistory)
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.

P2: History entries are persisted even when history is disabled in settings.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Plugins/Flow.Launcher.Plugin.Calculator/Main.cs, line 156:

<comment>History entries are persisted even when history is disabled in settings.</comment>

<file context>
@@ -119,43 +123,47 @@ public List<Result> Query(Query query)
+                    };
+
+
+                    if (isValidResultToAddHistory)
+                    {
+                        History.AddOrUpdate(new History.PendingHistoryItem(resultObject, expression, action));
</file context>
Suggested change
if (isValidResultToAddHistory)
if (isValidResultToAddHistory && _settings.EnableHistory)

{
var item = new HistoryItem(_pendingItem.Result, _pendingItem.Expression, _pendingItem.Action);

if (Items.Count >= MaxItems)
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.

P2: Capacity eviction removes the wrong history item because list order is not kept aligned with recency. Items.RemoveAt(0) assumes FIFO ordering, but Refresh updates CalculatedAt without repositioning the item, so a recently-refreshed item at index 0 can be incorrectly evicted when capacity is reached.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Plugins/Flow.Launcher.Plugin.Calculator/Storage/History.cs, line 72:

<comment>Capacity eviction removes the wrong history item because list order is not kept aligned with recency. `Items.RemoveAt(0)` assumes FIFO ordering, but `Refresh` updates `CalculatedAt` without repositioning the item, so a recently-refreshed item at index 0 can be incorrectly evicted when capacity is reached.</comment>

<file context>
@@ -0,0 +1,85 @@
+            {
+                var item = new HistoryItem(_pendingItem.Result, _pendingItem.Expression, _pendingItem.Action);
+
+                if (Items.Count >= MaxItems)
+                {
+                    Items.RemoveAt(0);
</file context>

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 10, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a debounced, capped calculation history to the Calculator plugin: new storage models (History, HistoryItem, PendingHistoryItem), settings toggle (EnableHistory), UI checkbox and localization, Main.cs wiring to load/persist history and conditionally record results, and unit tests accessing history via reflection.

Changes

Calculator History Feature

Layer / File(s) Summary
Storage & Data Contracts
Plugins/Flow.Launcher.Plugin.Calculator/Settings.cs, Plugins/Flow.Launcher.Plugin.Calculator/Storage/History.cs, Plugins/Flow.Launcher.Plugin.Calculator/Storage/HistoryItem.cs, Plugins/Flow.Launcher.Plugin.Calculator/Storage/PendingHistoryItem.cs
Adds Settings.EnableHistory. History stores up to 5 HistoryItem entries with debounced AddOrUpdate/FlushPendingItem and GetItemsExcluding(). HistoryItem extends Result with Query, CalculatedAt, constructors and Refresh(). PendingHistoryItem record represents a pending entry.
Core Plugin Implementation
Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
Loads persisted History in Init(). Query method computes isValidResultToAddHistory (excludes NaN and incomplete function results), builds primary Result with a clipboard-action helper, calls History.AddOrUpdate() for valid results, and when enabled returns current result plus prior history items. Helper methods handle pending item creation and clipboard copy with exception handling.
Localization & Settings UI
Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml, Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml
Adds flowlauncher_plugin_calculator_enable_history and flowlauncher_plugin_calculator_history_subtitle strings. Settings XAML adds a CheckBox bound two-way to Settings.EnableHistory in a new grid row.
Tests & Validation
Flow.Launcher.Test/Plugins/CalculatorTest.cs
Enables history in test fixture, resets plugin History before each test via reflection helpers, and adds tests that verify history is stored when enabled and that query results remain available when disabled. Reflection helpers GetHistory(), SetHistory(), and WaitForHistoryDebounce() are added to drive and observe debounced persistence.

Sequence Diagram(s)

sequenceDiagram
  participant User as User Input
  participant Plugin as Calculator.Main.Query
  participant Eval as Calculator Engine
  participant Validity as Validity Check
  participant History as History
  participant Storage as Settings JSON
  User->>Plugin: submits expression
  Plugin->>Eval: parse & evaluate
  Eval->>Validity: return type/result
  Validity->>Plugin: isValidResultToAddHistory
  Plugin->>History: AddOrUpdate(PendingHistoryItem) [if valid]
  Plugin->>History: GetItemsExcluding(expression) [if enabled]
  Plugin->>User: return current result + history items
  History->>Storage: persisted in plugin settings (FlushPendingItem)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

  • Flow-Launcher/Flow.Launcher#3859: Modifies Main.cs Query method; PR#3859 changes parsing/formatting logic while this PR adds history recording and result aggregation to the same method.

Suggested labels

enhancement

Suggested reviewers

  • Jack251970
  • jjw24
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'FEATURE: Calculator Plugin History' is directly related to the main change: adding persistent history functionality to the calculator plugin, as evidenced by all modified files implementing history storage, settings, and UI components.
Description check ✅ Passed The description clearly relates to the changeset, explaining the history feature, debounce strategy to prevent intermediate expressions from being saved, and how it improves user experience. It also includes screenshots demonstrating the feature in action.
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

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

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

🧹 Nitpick comments (2)
Plugins/Flow.Launcher.Plugin.Calculator/Main.cs (1)

156-159: 💤 Low value

History stores normalized expression, not original user input.

The expression variable passed to History.AddOrUpdate (line 158) is the normalized form after number formatting and function rewrites (pow/log/ln workarounds). This means users who type "1,234+5" will see "1234+5" in their history, and users who type "pow(2,3)" will see "(2^3)".

This is likely acceptable for most users, but consider whether showing the original query.Search instead would provide a better experience. The normalized form is what was actually computed, so there's a tradeoff.

🤖 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 `@Plugins/Flow.Launcher.Plugin.Calculator/Main.cs` around lines 156 - 159, The
history entry is being stored using the normalized expression variable (used
after number formatting and function rewrites) which loses the original user
input; change the argument passed to History.AddOrUpdate so it uses the original
query string (query.Search) instead of expression when creating the new
History.PendingHistoryItem, or choose to store both by passing query.Search as
the display/original value and expression as the computed/normalized value to
PendingHistoryItem if that type supports it (update PendingHistoryItem
constructor if needed) so history shows what the user typed while still
preserving the actual computed expression.
Plugins/Flow.Launcher.Plugin.Calculator/Storage/HistoryItem.cs (1)

11-12: ⚡ Quick win

Remove [JsonIgnore] from const field.

Constants are not serialized by System.Text.Json (or most serializers) by default. Adding [JsonIgnore] to a const field is misleading because it suggests the field might be serialized otherwise, which is never the case.

♻️ Proposed fix
-    [JsonIgnore]
     private const string BadgeIconPath = "Images/history.png";
🤖 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 `@Plugins/Flow.Launcher.Plugin.Calculator/Storage/HistoryItem.cs` around lines
11 - 12, Remove the misleading [JsonIgnore] attribute applied to the const field
BadgeIconPath in the HistoryItem class: locate the private const string
BadgeIconPath = "Images/history.png" declaration and delete the [JsonIgnore]
attribute so the const remains attribute-free; no other code changes required.
🤖 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 `@Flow.Launcher.Test/Plugins/CalculatorTest.cs`:
- Around line 102-110: The test CalculationHistory_IsNotStoredWhenDisabled
checks history immediately after calling _plugin.Query without waiting for the
debounce flush used by the plugin (same as
CalculationHistory_IsStoredWhenEnabled), so update the test to wait for the
debounce to complete or call the same helper that forces a flush used by the
other test before asserting; specifically, after _plugin.Query(new Plugin.Query
{ Search = "1+1" }) add the same wait/flush step used in
CalculationHistory_IsStoredWhenEnabled (e.g., await Task.Delay(debounceMs +
margin) or call the test helper that flushes history) then assert
GetHistory().Items.Count is 0, keeping references to _settings.EnableHistory,
_plugin.Query, GetHistory(), and the other test name for locating the helper.
- Around line 91-100: The test fails to account for History's 800ms debounce so
_plugin.Query(...) is called but GetHistory().Items.Count is checked before the
debounce flush; fix by either waiting for the debounce to elapse (e.g.,
Thread.Sleep(900) or an async wait after calling _plugin.Query) or add a
test-only synchronous flush on History (add an internal FlushNow() in History
that stops the _debounceTimer and calls FlushPendingItem()) and call that from
the test before asserting; reference History.FlushNow, History.FlushPendingItem,
_plugin.Query, and GetHistory() to locate the code to change.
- Around line 163-174: GetHistory() is using reflection for a static field but
Main declares a private instance property History; update the reflection to
retrieve the non-public instance property and read it from the plugin instance
used in SetUp() (e.g. use typeof(Main).GetProperty("History",
BindingFlags.NonPublic | BindingFlags.Instance) and call GetValue(_plugin)),
then assert the property exists and returns a History instance; alternatively,
if static behavior was intended change Main.History to a static field, but the
safer fix in the test is to use GetProperty with BindingFlags.Instance and the
_plugin instance.

In `@Plugins/Flow.Launcher.Plugin.Calculator/Main.cs`:
- Line 31: The History property is declared as an instance property but tests
access it via reflection with BindingFlags.Static; change the declaration of
History in Main.cs to a static property (e.g., private static History History {
get; set; } = null!;) so the reflection in CalculatorTest (which expects a
static member) will find it; ensure any usages of History in methods are updated
to reference the static property if needed.

In `@Plugins/Flow.Launcher.Plugin.Calculator/Storage/History.cs`:
- Around line 72-75: The eviction currently removes Items.RemoveAt(0) which uses
list order; change it to remove the item with the oldest CalculatedAt timestamp
so refreshed entries (via Refresh) aren’t evicted; in History.cs locate the
block checking Items.Count >= MaxItems and replace the RemoveAt(0) call with
logic that finds the item with the minimum CalculatedAt (e.g., via
Items.OrderBy(i => i.CalculatedAt).First() or a manual scan) and removes that
item from Items, ensuring you handle any null/zero timestamps consistently.

---

Nitpick comments:
In `@Plugins/Flow.Launcher.Plugin.Calculator/Main.cs`:
- Around line 156-159: The history entry is being stored using the normalized
expression variable (used after number formatting and function rewrites) which
loses the original user input; change the argument passed to History.AddOrUpdate
so it uses the original query string (query.Search) instead of expression when
creating the new History.PendingHistoryItem, or choose to store both by passing
query.Search as the display/original value and expression as the
computed/normalized value to PendingHistoryItem if that type supports it (update
PendingHistoryItem constructor if needed) so history shows what the user typed
while still preserving the actual computed expression.

In `@Plugins/Flow.Launcher.Plugin.Calculator/Storage/HistoryItem.cs`:
- Around line 11-12: Remove the misleading [JsonIgnore] attribute applied to the
const field BadgeIconPath in the HistoryItem class: locate the private const
string BadgeIconPath = "Images/history.png" declaration and delete the
[JsonIgnore] attribute so the const remains attribute-free; no other code
changes required.
🪄 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: CHILL

Plan: Pro

Run ID: f00f3981-70fd-4e0a-bb48-4b468541be79

📥 Commits

Reviewing files that changed from the base of the PR and between 5779818 and 4fc3016.

⛔ Files ignored due to path filters (1)
  • Plugins/Flow.Launcher.Plugin.Calculator/Images/history.png is excluded by !**/*.png
📒 Files selected for processing (7)
  • Flow.Launcher.Test/Plugins/CalculatorTest.cs
  • Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml
  • Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
  • Plugins/Flow.Launcher.Plugin.Calculator/Settings.cs
  • Plugins/Flow.Launcher.Plugin.Calculator/Storage/History.cs
  • Plugins/Flow.Launcher.Plugin.Calculator/Storage/HistoryItem.cs
  • Plugins/Flow.Launcher.Plugin.Calculator/Views/CalculatorSettings.xaml

Comment thread Flow.Launcher.Test/Plugins/CalculatorTest.cs
Comment thread Flow.Launcher.Test/Plugins/CalculatorTest.cs
Comment thread Flow.Launcher.Test/Plugins/CalculatorTest.cs Outdated
Comment thread Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
Comment on lines +72 to +75
if (Items.Count >= MaxItems)
{
Items.RemoveAt(0);
}
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix removal to evict oldest by timestamp, not insertion order.

When the history reaches capacity, RemoveAt(0) removes the first item in the internal list, which is based on insertion order. However, if an existing item is refreshed via Refresh (line 66), its CalculatedAt timestamp is updated but it remains at the same list position. This means a recently refreshed item at index 0 could be evicted even though it's the newest by timestamp, while older (by timestamp) items at higher indices are retained.

🐛 Proposed fix to remove oldest by timestamp
                 if (Items.Count >= MaxItems)
                 {
-                    Items.RemoveAt(0);
+                    var oldestItem = Items.OrderBy(x => x.CalculatedAt).First();
+                    Items.Remove(oldestItem);
                 }
📝 Committable suggestion

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

Suggested change
if (Items.Count >= MaxItems)
{
Items.RemoveAt(0);
}
if (Items.Count >= MaxItems)
{
var oldestItem = Items.OrderBy(x => x.CalculatedAt).First();
Items.Remove(oldestItem);
}
🤖 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 `@Plugins/Flow.Launcher.Plugin.Calculator/Storage/History.cs` around lines 72 -
75, The eviction currently removes Items.RemoveAt(0) which uses list order;
change it to remove the item with the oldest CalculatedAt timestamp so refreshed
entries (via Refresh) aren’t evicted; in History.cs locate the block checking
Items.Count >= MaxItems and replace the RemoveAt(0) call with logic that finds
the item with the minimum CalculatedAt (e.g., via Items.OrderBy(i =>
i.CalculatedAt).First() or a manual scan) and removes that item from Items,
ensuring you handle any null/zero timestamps consistently.

@01Dri 01Dri closed this May 10, 2026
@01Dri 01Dri reopened this May 10, 2026
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)
Plugins/Flow.Launcher.Plugin.Calculator/Storage/History.cs (1)

71-74: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix eviction to remove oldest by timestamp, not insertion order.

When capacity is reached, RemoveAt(0) evicts based on list position. However, when an existing item is refreshed (line 65), its CalculatedAt is updated but it remains at the same index. This means a recently refreshed item at index 0 will be evicted even though newer (by timestamp) items exist at higher indices.

🐛 Proposed fix to remove oldest by timestamp
                 if (Items.Count >= MaxItems)
                 {
-                    Items.RemoveAt(0);
+                    var oldestItem = Items.OrderBy(x => x.CalculatedAt).First();
+                    Items.Remove(oldestItem);
                 }
🤖 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 `@Plugins/Flow.Launcher.Plugin.Calculator/Storage/History.cs` around lines 71 -
74, The eviction currently uses Items.RemoveAt(0) which removes by list
position; change it to remove the item with the oldest CalculatedAt timestamp so
refreshes aren't evicted; in the eviction block in History (the method
updating/adding items that uses Items, MaxItems and updates CalculatedAt)
compute the item with the minimum CalculatedAt (e.g., via Items.MinBy(i =>
i.CalculatedAt) or Items.OrderBy(i => i.CalculatedAt).First()) and call
Items.Remove(oldest) instead of RemoveAt(0).
🧹 Nitpick comments (2)
Plugins/Flow.Launcher.Plugin.Calculator/Storage/HistoryItem.cs (2)

22-22: 💤 Low value

Consider extracting magic number to a named constant.

The hardcoded score 300 would be more maintainable as a named constant (e.g., private const int HistoryItemScore = 300) to clarify its purpose and make it easier to adjust if needed.

♻️ Proposed fix
+    private const int HistoryItemScore = 300;
+
     public HistoryItem(PendingHistoryItem item)
     {
         CalculatedAt = item.CalculatedAt;
         Title = item.Expression;
         SubTitle = item.SubTitle;
-        Score = 300;
+        Score = HistoryItemScore;
🤖 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 `@Plugins/Flow.Launcher.Plugin.Calculator/Storage/HistoryItem.cs` at line 22,
The hardcoded assignment Score = 300 in HistoryItem should be replaced with a
named constant to remove the magic number; add a private const int (e.g.,
HistoryItemScore = 300) in the HistoryItem class and use that constant when
setting the Score property (refer to the Score assignment in HistoryItem and the
class declaration to locate the change).

11-11: 💤 Low value

Remove redundant [JsonIgnore] attribute.

The [JsonIgnore] attribute on a private const field is redundant. Private constants are not serialized by System.Text.Json by default, and const fields are implicitly static (which are also excluded from serialization).

♻️ Proposed fix
-    [JsonIgnore] private const string BadgeIconPath = "Images/history.png";
+    private const string BadgeIconPath = "Images/history.png";
🤖 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 `@Plugins/Flow.Launcher.Plugin.Calculator/Storage/HistoryItem.cs` at line 11,
Remove the redundant [JsonIgnore] attribute applied to the private const field
BadgeIconPath in HistoryItem (the line "[JsonIgnore] private const string
BadgeIconPath = \"Images/history.png\""); simply delete the [JsonIgnore] token
so the field is declared as "private const string BadgeIconPath =
\"Images/history.png\"". If that was the only usage of
System.Text.Json.Serialization in the file, also remove the now-unused using for
cleanliness.
🤖 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.

Duplicate comments:
In `@Plugins/Flow.Launcher.Plugin.Calculator/Storage/History.cs`:
- Around line 71-74: The eviction currently uses Items.RemoveAt(0) which removes
by list position; change it to remove the item with the oldest CalculatedAt
timestamp so refreshes aren't evicted; in the eviction block in History (the
method updating/adding items that uses Items, MaxItems and updates CalculatedAt)
compute the item with the minimum CalculatedAt (e.g., via Items.MinBy(i =>
i.CalculatedAt) or Items.OrderBy(i => i.CalculatedAt).First()) and call
Items.Remove(oldest) instead of RemoveAt(0).

---

Nitpick comments:
In `@Plugins/Flow.Launcher.Plugin.Calculator/Storage/HistoryItem.cs`:
- Line 22: The hardcoded assignment Score = 300 in HistoryItem should be
replaced with a named constant to remove the magic number; add a private const
int (e.g., HistoryItemScore = 300) in the HistoryItem class and use that
constant when setting the Score property (refer to the Score assignment in
HistoryItem and the class declaration to locate the change).
- Line 11: Remove the redundant [JsonIgnore] attribute applied to the private
const field BadgeIconPath in HistoryItem (the line "[JsonIgnore] private const
string BadgeIconPath = \"Images/history.png\""); simply delete the [JsonIgnore]
token so the field is declared as "private const string BadgeIconPath =
\"Images/history.png\"". If that was the only usage of
System.Text.Json.Serialization in the file, also remove the now-unused using for
cleanliness.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 16e2d2a3-7a8a-46ab-a47a-40f9fe95bcb0

📥 Commits

Reviewing files that changed from the base of the PR and between 4fc3016 and 6d93ce0.

📒 Files selected for processing (5)
  • Flow.Launcher.Test/Plugins/CalculatorTest.cs
  • Plugins/Flow.Launcher.Plugin.Calculator/Main.cs
  • Plugins/Flow.Launcher.Plugin.Calculator/Storage/History.cs
  • Plugins/Flow.Launcher.Plugin.Calculator/Storage/HistoryItem.cs
  • Plugins/Flow.Launcher.Plugin.Calculator/Storage/PendingHistoryItem.cs
🚧 Files skipped from review as they are similar to previous changes (1)
  • Plugins/Flow.Launcher.Plugin.Calculator/Main.cs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant