Skip to content

Conversation

samruddhi-Rahegaonkar
Copy link
Member

@samruddhi-Rahegaonkar samruddhi-Rahegaonkar commented Jun 23, 2025

Fixes #1314

Changes

  • Introduced dynamic support for multiple badge screen sizes across the app.
  • Added new model: ScreenSize to support scalable layouts.
  • Refactored key components including:
  • draw_badge_screen.dart
  • badge_paint.dart
  • animated_badge.dart
  • Various providers: draw_badge_provider, saved_badge_provider, etc.
  • Updated converters and byte array utilities to respect dynamic screen dimensions.
  • Added/updated unit tests for converters and matrix logic.

Screenshots / Recordings

Screenshot 2025-06-26 at 1 06 07 PM Screenshot 2025-06-26 at 1 07 00 PM Screenshot 2025-06-26 at 1 07 30 PM Screenshot 2025-06-26 at 1 04 52 PM Screenshot 2025-06-26 at 1 05 13 PM Screenshot 2025-06-26 at 1 07 50 PM
Screen.Recording.2025-06-26.at.6.49.21.PM.mov

Checklist:

  • No hard coding: I have used resources from constants.dart without hard coding any value.
  • No end of file edits: No modifications done at end of resource files.
  • Code reformatting: I have reformatted code and fixed indentation in every file included in this pull request.
  • Code analyzation: My code passes analyzations run in flutter analyze and tests run in flutter test.

Summary by Sourcery

Introduce dynamic support for multiple LED badge sizes by adding a ScreenSize model and propagating variable dimensions throughout the UI, providers, converters, painting logic, and tests, while enabling users to select their badge size at runtime.

New Features:

  • Add support for multiple badge screen sizes via a new ScreenSize model and a size selector dropdown in the home and save badge UIs
  • Enable dynamic initialization and resizing of badge grids at runtime across drawing, animation, effects, and transfer workflows based on the selected ScreenSize

Enhancements:

  • Refactor core providers and utilities (AnimationBadgeProvider, DrawBadgeProvider, SavedBadgeProvider, BadgeMessageProvider) to accept badge height/width parameters and initialize grids dynamically
  • Update converters, byte‐array utilities, and custom painters to handle arbitrary badge dimensions
  • Clean up lifecycle handling and listener management in HomeScreen for consistent pause/resume behavior

CI:

  • Update GitHub Actions workflows to trigger on the development branch

Tests:

  • Revise converter and data‐to‐bytearray unit tests to include the badgeHeight parameter

Summary by Sourcery

Support multiple LED badge sizes by introducing a ScreenSize model and wiring dynamic width/height parameters throughout the app to enable scalable layouts in all drawing, animation, effect, saving, and transfer features.

New Features:

  • Introduce ScreenSize model with UI dropdown to select badge dimensions at runtime
  • Enable dynamic initialization and resizing of badge grids based on selected ScreenSize across drawing, animation, effects, and transfer workflows

Enhancements:

  • Refactor core providers and utilities to accept variable badge width/height parameters
  • Update converters, byte array utilities, and custom painters to support arbitrary badge dimensions
  • Enhance image utilities to scale and trim SVG/bitmap assets to match selected badge size
  • Propagate ScreenSize selection through UI components including AnimationBadge, EffectTab, SaveBadgeCard, and DrawBadge

CI:

  • Modify GitHub Actions workflows to trigger on development and flutter_app branches

Tests:

  • Update unit tests for converters and byte array utilities to include dynamic badge dimensions

Copy link
Contributor

sourcery-ai bot commented Jun 23, 2025

Reviewer's Guide

This PR adds dynamic support for multiple LED badge sizes by introducing a ScreenSize model and replacing all hard-coded grid dimensions with runtime-configurable values, propagating the selected size through UI widgets, providers, converters, custom painters, utilities, and tests.

Sequence diagram for badge size selection and propagation

sequenceDiagram
    actor User
    participant HomeScreen
    participant AnimationBadge
    participant DrawBadge
    participant SaveBadgeDialog
    participant SaveBadgeProvider
    User->>HomeScreen: Selects badge size from dropdown
    HomeScreen->>AnimationBadge: Passes selected ScreenSize
    User->>DrawBadge: Navigates to draw badge
    DrawBadge->>DrawBadge: Initializes grid with selected ScreenSize
    User->>SaveBadgeDialog: Opens save dialog
    SaveBadgeDialog->>SaveBadgeProvider: Saves badge with selected ScreenSize
    SaveBadgeProvider->>SaveBadgeProvider: Stores badge data with size info
Loading

Class diagram for ScreenSize and supportedScreenSizes

classDiagram
    class ScreenSize {
        +int width
        +int height
        +String name
        +operator ==(Object other)
        +int hashCode
    }
    class supportedScreenSizes {
        <<constant>>
        +List<ScreenSize>
    }
Loading

Class diagram for updated AnimationBadgeProvider and DrawBadgeProvider

classDiagram
    class AnimationBadgeProvider {
        -List<List<bool>> _paintGrid
        -List<List<bool>> _newGrid
        -List<List<List<bool>>> _frames
        -int _currentFrame
        +void initGrids(ScreenSize size)
        +void badgeAnimation(String, Converters, bool, ScreenSize)
        +List<List<bool>> getPaintGrid()
        +List<List<bool>> getNewGrid()
    }
    class DrawBadgeProvider {
        -List<List<bool>> _drawViewGrid
        -ScreenSize _currentSize
        +void initGridWithSize(ScreenSize size)
        +List<List<bool>> getDrawViewGrid()
        +ScreenSize getCurrentSize()
    }
Loading

Class diagram for updated UI widgets with ScreenSize support

classDiagram
    class AnimationBadge {
        +ScreenSize selectedSize
    }
    class BMBadge {
        +ScreenSize selectedSize
    }
    class EffectContainer {
        +ScreenSize selectedSize
    }
    class EffectTab {
        +ScreenSize selectedSize
    }
    class SaveBadgeCard {
        +ScreenSize selectedSize
    }
    class BadgeListView {
        +ScreenSize selectedSize
    }
    class SavedClipartListView {
        +ScreenSize selectedSize
    }
    class SaveBadgeDialog {
        +ScreenSize selectedSize
    }
Loading

File-Level Changes

Change Details Files
Add ScreenSize model and supported sizes
  • Define ScreenSize class with width, height, name
  • Initialize supportedScreenSizes list
  • Import and use ScreenSize where needed
lib/bademagic_module/models/screen_size.dart
UI updates to select and propagate badge size
  • Add dropdown and _selectedSize field in HomeScreen and SaveBadgeScreen
  • Pass selectedSize into AnimationBadge, BMBadge, EffectTab, SaveBadgeCard, SaveBadgeDialog, DrawBadgeScreen, ClipartListView
  • Update main.dart routes to include initial selectedSize
lib/view/homescreen.dart
lib/view/save_badge_screen.dart
lib/view/draw_badge_screen.dart
lib/view/saved_clipart.dart
lib/view/widgets/clipart_list_view.dart
lib/main.dart
lib/view/widgets/save_badge_card.dart
lib/view/widgets/save_badge_dialog.dart
lib/view/widgets/effects_container.dart
lib/view/widgets/homescreentabs.dart
lib/virtualbadge/view/animated_badge.dart
Refactor providers for dynamic dimensions
  • Replace hard-coded 44×11 grids with initGrids/initGridWithSize taking ScreenSize
  • Extend methods (badgeAnimation, saveBadgeData, getBadgeData) to accept badgeHeight/width
  • Update grid logic and notifyListeners accordingly
lib/providers/animation_badge_provider.dart
lib/providers/draw_badge_provider.dart
lib/providers/saved_badge_provider.dart
lib/providers/badge_message_provider.dart
Converters and utilities accept dynamic sizes
  • Change messageTohex signature to include badgeHeight and ScreenSize
  • Implement scaling/padding logic based on ScreenSize in converters
  • Update hexStringToBool, byteArrayToBinaryArray, binaryStringTo2DList to use rows parameter
  • Add generateLedHexWithSize in ImageUtils
lib/bademagic_module/utils/converters.dart
lib/bademagic_module/utils/byte_array_utils.dart
lib/bademagic_module/utils/image_utils.dart
Dynamic badge painting based on grid dimensions
  • Compute cellSize and aspectRatio from grid length and height
  • Guard against empty grids before painting
lib/virtualbadge/view/badge_paint.dart
Update tests for dynamic screen sizes
  • Pass badgeHeight and ScreenSize into messageTohex calls
  • Adjust expected hex outputs and utility calls
test/data_to_bytearray_converter_test.dart
test/converters_test.dart
Update CI workflows to include new branches
  • Add flutter_app branch trigger in pull_request_closed.yml
  • Ensure push.yml triggers remain correct
.github/workflows/pull_request_closed.yml
.github/workflows/push.yml

Assessment against linked issues

Issue Objective Addressed Explanation

Possibly linked issues


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

@samruddhi-Rahegaonkar samruddhi-Rahegaonkar force-pushed the issue1344 branch 12 times, most recently from fc0ac96 to 74a1dda Compare June 28, 2025 04:34
@samruddhi-Rahegaonkar samruddhi-Rahegaonkar marked this pull request as ready for review June 28, 2025 04:55
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 @samruddhi-Rahegaonkar - I've reviewed your changes - here's some feedback:

  • This change spreads the new ScreenSize parameters into almost every widget and provider method; consider using a single Provider or InheritedWidget to hold the selected badge size so you don’t have to modify every signature and widget.
  • The Converters.messageTohex method has become extremely large with mixed responsibilities (emoji tags, char scaling, bitmap scaling); refactor by extracting emoji, character, and bitmap conversion into separate helper classes or private services to improve readability and testability.
  • BadgePaint (and other rendering code) still uses magic scaling factors like 0.93 and 0.5—extract these into named constants or compute them dynamically from width/height ratios to avoid unexpected layout issues on non-standard sizes.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- This change spreads the new ScreenSize parameters into almost every widget and provider method; consider using a single Provider or InheritedWidget to hold the selected badge size so you don’t have to modify every signature and widget.
- The Converters.messageTohex method has become extremely large with mixed responsibilities (emoji tags, char scaling, bitmap scaling); refactor by extracting emoji, character, and bitmap conversion into separate helper classes or private services to improve readability and testability.
- BadgePaint (and other rendering code) still uses magic scaling factors like 0.93 and 0.5—extract these into named constants or compute them dynamically from width/height ratios to avoid unexpected layout issues on non-standard sizes.

## Individual Comments

### Comment 1
<location> `lib/providers/animation_badge_provider.dart:110` </location>
<code_context>
   }

   void startTimer() {
+    if (_newGrid.isEmpty || _newGrid[0].isEmpty) {
+      logger.w("Cannot start animation timer: _newGrid is empty");
+      return;
</code_context>

<issue_to_address>
startTimer silently returns if _newGrid is empty, which may mask upstream issues.

Consider surfacing this condition as an error or notifying the caller, so they are aware the animation did not start.
</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.

@samruddhi-Rahegaonkar
Copy link
Member Author

samruddhi-Rahegaonkar commented Jun 28, 2025

Hey @samruddhi-Rahegaonkar - I've reviewed your changes - here's some feedback:

  • This change spreads the new ScreenSize parameters into almost every widget and provider method; consider using a single Provider or InheritedWidget to hold the selected badge size so you don’t have to modify every signature and widget.
  • The Converters.messageTohex method has become extremely large with mixed responsibilities (emoji tags, char scaling, bitmap scaling); refactor by extracting emoji, character, and bitmap conversion into separate helper classes or private services to improve readability and testability.
  • BadgePaint (and other rendering code) still uses magic scaling factors like 0.93 and 0.5—extract these into named constants or compute them dynamically from width/height ratios to avoid unexpected layout issues on non-standard sizes.

Prompt for AI Agents
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.

Hey @sourcery-ai ,
If every animation, effect, data transformation, and BLE message depends directly on ScreenSize, then yes — passing it explicitly ensures:

  • Clear contract of what a function needs
  • Easier to debug misalignment between expected and actual sizes
  • Avoids hidden side-effects from global access

Isn't It ?

@samruddhi-Rahegaonkar samruddhi-Rahegaonkar force-pushed the issue1344 branch 3 times, most recently from 1038c33 to e334dbe Compare June 28, 2025 08:59
@samruddhi-Rahegaonkar samruddhi-Rahegaonkar marked this pull request as draft June 28, 2025 09:21
@samruddhi-Rahegaonkar samruddhi-Rahegaonkar force-pushed the issue1344 branch 2 times, most recently from 4d3d10a to 856c79e Compare June 28, 2025 09:42

This comment was marked as outdated.

@samruddhi-Rahegaonkar samruddhi-Rahegaonkar marked this pull request as ready for review June 28, 2025 11:35
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 @samruddhi-Rahegaonkar - I've reviewed your changes - here's some feedback:

  • Consider centralizing the selected ScreenSize in a provider or InheritedWidget so you don’t have to prop-drill it through every widget and method call.
  • The Converters class now mixes text parsing, bitmap scaling, emoji handling, and hex formatting—splitting it into focused services (e.g. TextConverter, ImageConverter) will improve readability and testability.
  • There are multiple bitmap scaling and trimming routines (_scaleBitmapToBadgeSize, _scaleTextCharacterToBadgeSize, convertBitmapToLEDHex, etc.); consolidating them into shared utilities will reduce duplication and ensure consistent behavior.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider centralizing the selected ScreenSize in a provider or InheritedWidget so you don’t have to prop-drill it through every widget and method call.
- The Converters class now mixes text parsing, bitmap scaling, emoji handling, and hex formatting—splitting it into focused services (e.g. TextConverter, ImageConverter) will improve readability and testability.
- There are multiple bitmap scaling and trimming routines (_scaleBitmapToBadgeSize, _scaleTextCharacterToBadgeSize, convertBitmapToLEDHex, etc.); consolidating them into shared utilities will reduce duplication and ensure consistent behavior.

## Individual Comments

### Comment 1
<location> `lib/providers/draw_badge_provider.dart:25` </location>
<code_context>
-        }
+    final rows = _drawViewGrid.length;
+    final cols = _drawViewGrid.isNotEmpty ? _drawViewGrid[0].length : 0;
+    for (int i = 0; i < rows && i < badgeData.length; i++) {
+      for (int j = 0; j < cols && j < badgeData[0].length; j++) {
+        _drawViewGrid[i][j] = badgeData[i][j];
</code_context>

<issue_to_address>
updateDrawViewGrid only copies overlapping regions, which may leave parts of the grid unchanged.

If badgeData is smaller than the grid, leftover cells may show outdated data. Please clear or reset all grid cells before copying new values.
</issue_to_address>

### Comment 2
<location> `lib/virtualbadge/view/badge_paint.dart:50` </location>
<code_context>
+    final int rows = grid.length;
+
+    // Adjust cell size to fit all pixels inside the badge area
+    final double cellWidth = badgeWidth / (cols * 0.93);
+    final double cellHeight = badgeHeight / rows;
+    final double cellSize = math.min(cellWidth, cellHeight);
</code_context>

<issue_to_address>
The cell width uses a 0.93 scaling factor, which may not be intuitive.

Please document the choice of 0.93 or make it a configurable parameter to improve clarity and adaptability.
</issue_to_address>

### Comment 3
<location> `lib/virtualbadge/view/badge_paint.dart:97` </location>
<code_context>
-  bool shouldRepaint(covariant CustomPainter oldDelegate) {
-    return true;
-  }
+  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
 }
</code_context>

<issue_to_address>
shouldRepaint always returns true, which may cause unnecessary repaints.

Compare the old and new grid values in shouldRepaint to avoid unnecessary repaints and improve performance.

Suggested implementation:

```
  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    if (oldDelegate is! YourPainterClassName) return true;
    return oldDelegate.grid != grid;
  }
}

```

- Replace `YourPainterClassName` with the actual name of your CustomPainter subclass.
- Ensure that `grid` is a field of your painter class and that it implements `==` properly (e.g., use `ListEquality` from `collection` if it's a List).
- If `grid` is a complex object, you may need to implement or use a deep equality check.
</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.

@samruddhi-Rahegaonkar
Copy link
Member Author

samruddhi-Rahegaonkar commented Sep 5, 2025

@samruddhi-Rahegaonkar
Copy link
Member Author

Multiple.badge.size.mp4

@mariobehling
Copy link
Member

The screen size is relevant to the screen, but the spacing to the above screen is larger than the spacing to the text box. Please make it the other way around.

Screenshot from 2025-09-05 17-28-26

@samruddhi-Rahegaonkar
Copy link
Member Author

@mariobehling We can maximum have the above one or the centered one because the widget takes its space too.
Screenshot 2025-09-05 at 10 23 12 PM

@samruddhi-Rahegaonkar
Copy link
Member Author

@mariobehling I think the current one is better than to be centered with the white space above and below.

@mariobehling
Copy link
Member

486199871-f84e72a2-dd3d-4f89-a627-ca4c7cbde74f Please see image. Do not change the color of the button, keep it white as before. Do not introduce a new gray color into the app.

@samruddhi-Rahegaonkar
Copy link
Member Author

486199871-f84e72a2-dd3d-4f89-a627-ca4c7cbde74f Please see image. Do not change the color of the button, keep it white as before. Do not introduce a new gray color into the app.

No, I had made a grey color to show the space taking by the widget.

@samruddhi-Rahegaonkar
Copy link
Member Author

Screenshot_20250907_115342 Screenshot 2025-09-07 at 11 55 17 AM

@samruddhi-Rahegaonkar
Copy link
Member Author

samruddhi-Rahegaonkar commented Sep 7, 2025

@mariobehling This is the maxiumum closer we can make to the Badge preview further more it will overlay on the badge.

@samruddhi-Rahegaonkar
Copy link
Member Author

@mariobehling Can we go with this ?

@Jhalakupadhyay
Copy link
Contributor

@samruddhi-Rahegaonkar why there is changes in actions. and this is a really long PR 30 files changes it becomes impossible to review.

@samruddhi-Rahegaonkar
Copy link
Member Author

@samruddhi-Rahegaonkar why there is changes in actions. and this is a really long PR 30 files changes it becomes impossible to review.

I have attached Video and changes are not that much just passed the Screen size parameters to evry file and tests thats why file changed are very large.

@samruddhi-Rahegaonkar
Copy link
Member Author

@Jhalakupadhyay This PR was too old and after resolving cinflicts it has grown.

@nope3472
Copy link
Contributor

hey @samruddhi-Rahegaonkar can you resolve the conflicts.

@samruddhi-Rahegaonkar
Copy link
Member Author

@nope3472 I will resolve it by end of the day.

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.

Support User-Selectable LED Badge Screen Sizes in App
5 participants