Skip to content

Conversation

@marcnause
Copy link
Contributor

@marcnause marcnause commented Dec 11, 2025

Fixes #2986

Changes

  • Replaced separate lists with single list of custom data structure
  • Replaced switch/case with lots of duplicate code with index based implementation
  • Removed non-implemented instruments by turning respective lines into comments (to be reverted one instruments are added)

Screenshots / Recordings

Old Version

New Version

Checklist:

  • No hard coding: I have used values from constants.dart or localization files instead of hard-coded values.
  • No end of file edits: No modifications done at end of resource files.
  • Code reformatting: I have formatted the code using dart format or the IDE formatter.
  • Code analysis: My code passes checks run in flutter analyze and tests run in flutter test.

Summary by Sourcery

Refactor the instruments screen to use a unified data model for instruments and data-driven navigation, while temporarily hiding non-implemented instruments from the list.

Bug Fixes:

  • Hide non-implemented instruments from the instruments screen by removing them from the rendered list.

Enhancements:

  • Introduce a single instrument data structure to consolidate instrument labels, descriptions, and routes.
  • Replace the large switch-based navigation logic with index-based, data-driven routing using the shared instrument list.
  • Update search filtering and list rendering to operate on the unified instrument data collection instead of parallel string lists.

Summary by Sourcery

Refactor the instruments screen to use a single unified data model for instruments and simplify navigation and search logic while hiding instruments that are not yet implemented.

Bug Fixes:

  • Hide not-yet-implemented instruments such as gas and dust sensors from the instruments list so only functional tools are shown.

Enhancements:

  • Introduce an internal InstrumentData structure combining instrument labels, descriptions, and route names into a single list.
  • Replace the large switch-based navigation logic with data-driven routing derived from the unified instrument list.
  • Update search filtering and list rendering to operate over the new instrument data collection instead of parallel heading/description lists.
  • Remove hard-coded instrument headings and descriptions from global constants in favor of localized, screen-specific definitions.

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Dec 11, 2025

Reviewer's Guide

Refactors the instruments screen to use a unified instrument data model and index-based navigation, removes duplicated switch/case routing logic, and temporarily hides non-implemented instruments by omitting them from the unified list while updating search, filtering, and rendering to rely on the new structure.

Sequence diagram for data-driven instrument navigation

sequenceDiagram
  actor User
  participant InstrumentsScreen as InstrumentsScreenState
  participant InstrumentData as _InstrumentData
  participant Navigator

  User->>InstrumentsScreen: tap instrument at listIndex
  InstrumentsScreen->>InstrumentsScreen: _onItemTapped(listIndex)
  InstrumentsScreen->>InstrumentData: instrument = _instrumentDatas[listIndex]
  alt route already on top of stack
    InstrumentsScreen->>Navigator: canPop(context)
    InstrumentsScreen->>Navigator: popUntil(routeWithName(instrument.name))
  else route not on top of stack
    InstrumentsScreen->>Navigator: pushNamedAndRemoveUntil(instrument.name, isFirstRoute)
  end
Loading

Class diagram for unified instrument data model

classDiagram
  class _InstrumentData {
    +String heading
    +String description
    +String name
    +_InstrumentData(String heading, String description, String name)
  }

  class _InstrumentsScreenState {
    +List~int~ _filteredIndices
    +AppLocalizations appLocalizations
    +List~_InstrumentData~ _instrumentDatas
    +void _onItemTapped(int index)
    +void _filterInstruments(String query)
    +void initState()
    +Widget build(BuildContext context)
  }

  _InstrumentsScreenState --> _InstrumentData : uses
Loading

File-Level Changes

Change Details Files
Introduce a unified instrument data model and replace parallel heading/description lists.
  • Add a private _InstrumentData class encapsulating heading, description, and route name for each instrument.
  • Replace local instrumentHeadings and instrumentDesc lists in _InstrumentsScreenState with a single _instrumentDatas list of _InstrumentData instances.
  • Initialize _instrumentDatas from AppLocalizations values and route names, including comments for non-implemented instruments.
  • Remove global instrumentHeadings and instrumentDesc lists from constants.dart.
lib/view/instruments_screen.dart
lib/constants.dart
Refactor navigation to be data-driven and index-based instead of a large switch/case block.
  • Replace the long switch statement in _onItemTapped with logic that looks up the tapped _InstrumentData by index and navigates using its route name.
  • Reuse the existing Navigator.canPop / popUntil / pushNamedAndRemoveUntil pattern, but parameterized by instrument.name instead of hard-coded route strings.
lib/view/instruments_screen.dart
Update filtering and list rendering to operate on the unified instrument data list and hide non-implemented instruments.
  • Change search filtering to generate indices based on _instrumentDatas.length and filter by _instrumentDatas[i].heading rather than a separate headings list.
  • Set the initial _filteredIndices length from _instrumentDatas instead of a headings list.
  • Update ApplicationsListItem construction to read heading and description from _instrumentDatas, uppercasing heading at render time.
  • Comment out _InstrumentData entries for gasSensor and dustSensor so they are not rendered until implemented, while keeping soundMeter in the list.
lib/view/instruments_screen.dart

Assessment against linked issues

Issue Objective Addressed Explanation
#2986 Hide or remove all non-implemented instruments from the instruments dashboard so that only implemented instruments are shown.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@marcnause marcnause marked this pull request as ready for review December 11, 2025 22:18
Copy link
Contributor

@sourcery-ai sourcery-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.

Hey there - I've reviewed your changes - here's some feedback:

  • Several _InstrumentData entries use the non-Desc localization key for the description (e.g. appLocalizations.multimeter instead of multimeterDesc), which will show the title text instead of the intended description; please switch these to the corresponding *Desc keys where applicable.
  • Consider making _InstrumentData’s fields final and constructing _instrumentDatas as a const list to better express immutability and potentially enable small performance optimizations.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Several `_InstrumentData` entries use the non-`Desc` localization key for the `description` (e.g. `appLocalizations.multimeter` instead of `multimeterDesc`), which will show the title text instead of the intended description; please switch these to the corresponding `*Desc` keys where applicable.
- Consider making `_InstrumentData`’s fields `final` and constructing `_instrumentDatas` as a `const` list to better express immutability and potentially enable small performance optimizations.

## Individual Comments

### Comment 1
<location> `lib/view/instruments_screen.dart:92-101` </location>
<code_context>
+      _InstrumentData(appLocalizations.multimeter, appLocalizations.multimeter,
</code_context>

<issue_to_address>
**issue (bug_risk):** Descriptions for most instruments are using the title string instead of the dedicated `*Desc` localization, changing UI text compared to previous behavior.

In the new `_instrumentDatas` list, only `oscilloscope` still uses its `*Desc` value; the others now reuse the heading key for the description (e.g. `appLocalizations.multimeter` for both fields). This will make the description text identical to the heading and drop the explanatory copy. Please switch these to the corresponding `*Desc` localizations (e.g. `appLocalizations.multimeterDesc`, `logicAnalyzerDesc`, `sensorsDesc`, etc.) to match prior behavior.
</issue_to_address>

### Comment 2
<location> `lib/view/instruments_screen.dart:16-22` </location>
<code_context>
   State<StatefulWidget> createState() => _InstrumentsScreenState();
 }

+class _InstrumentData {
+  String heading;
+  String description;
+  String name;
+
+  _InstrumentData(this.heading, this.description, this.name);
+}
+
</code_context>

<issue_to_address>
**suggestion:** Consider making `_InstrumentData` immutable by using `final` fields.

Because `_InstrumentData` is only created in `initState` and then read, these fields don’t need to change. Making `heading`, `description`, and `name` `final` clarifies that the data is immutable and avoids accidental mutation, which is important for navigation/search data that can be hard to debug if modified unexpectedly.

```suggestion
class _InstrumentData {
  final String heading;
  final String description;
  final String name;

  const _InstrumentData(this.heading, this.description, this.name);
}
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Fixed bugs introduced in last commit.
@github-actions
Copy link
Contributor

github-actions bot commented Dec 11, 2025

Build Status

Build successful. APKs to test: https://github.com/fossasia/pslab-app/actions/runs/20215378713/artifacts/4865734429.

Screenshots

Android Screenshots
iPhone Screenshots
iPad Screenshots

@marcnause marcnause marked this pull request as draft December 11, 2025 22:51
@marcnause marcnause marked this pull request as ready for review December 14, 2025 21:41
@marcnause marcnause enabled auto-merge (squash) December 14, 2025 21:42
Copy link
Contributor

@sourcery-ai sourcery-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.

Hey there - I've reviewed your changes - here's some feedback:

  • Now that the list of instruments is driven by _instrumentDatas, the instrumentIcons array in constants.dart should be updated to contain the same instruments in the same order (and with the removed instruments also removed or moved), otherwise the icons will be misaligned with the visible instruments (e.g., soundMeter currently reuses the gasSensor icon index).
  • For the commented-out instrument entries (gasSensor, dustSensor), consider normalizing their future name values to match the other routes (i.e., include the leading /) so they can be safely uncommented later without introducing routing inconsistencies.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Now that the list of instruments is driven by `_instrumentDatas`, the `instrumentIcons` array in `constants.dart` should be updated to contain the same instruments in the same order (and with the removed instruments also removed or moved), otherwise the icons will be misaligned with the visible instruments (e.g., `soundMeter` currently reuses the `gasSensor` icon index).
- For the commented-out instrument entries (`gasSensor`, `dustSensor`), consider normalizing their future `name` values to match the other routes (i.e., include the leading `/`) so they can be safely uncommented later without introducing routing inconsistencies.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@marcnause
Copy link
Contributor Author

* Now that the list of instruments is driven by `_instrumentDatas`, the `instrumentIcons` array in `constants.dart` should be updated to contain the same instruments in the same order (and with the removed instruments also removed or moved), otherwise the icons will be misaligned with the visible instruments (e.g., `soundMeter` currently reuses the `gasSensor` icon index).

I will create a separate issue for this.

* For the commented-out instrument entries (`gasSensor`, `dustSensor`), consider normalizing their future `name` values to match the other routes (i.e., include the leading `/`) so they can be safely uncommented later without introducing routing inconsistencies.

Done in last commit.

@marcnause marcnause merged commit f894ff2 into fossasia:flutter Dec 15, 2025
20 of 21 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.

Remove missing instruments from dashboard

2 participants