Skip to content

refactor(flutter): organize the frontend into Elm modules mirroring Iced - #108

Merged
darwin67 merged 7 commits into
mainfrom
refactor/flutter-elm-modules
Sep 13, 2026
Merged

darwin67 merged 7 commits into
mainfrom
refactor/flutter-elm-modules

Conversation

@darwin67

@darwin67 darwin67 commented Sep 13, 2026

Copy link
Copy Markdown
Member

Summary

Reorganizes the Flutter frontend into Elm modules that mirror the Iced reference (State / Message / update / view / shared utils), and adds isolated deterministic tests. No product behavior change.

Layout

lib/
  main.dart                    # entrypoint + ShosaiApp + public re-exports (~160 lines, was 2,484)
  app_theme.dart
  shared/shad_widgets.dart     # shared Shadcn UI helper (ShadIconAction)
  reader/
    controller.dart            # ReaderController (library) + parts
    model.dart / message.dart / effects.dart   # parts of controller.dart (Elm State/Message/effects)
    view.dart                  # ReaderScreen library + parts
    view_document.dart / view_selection.dart / view_dialogs.dart / geometry.dart / painting.dart
  library/
    controller.dart            # LibraryController (library) + parts
    model.dart / message.dart  # parts of controller.dart
    errors.dart                # shared library error mapping (public)
    view.dart                  # ProductShell library + parts
    view_collection.dart / view_dialogs.dart

Dart's library is the privacy unit, so each class-bearing module uses part files (the Dart analogue of Rust mod foo;) to keep private members while splitting storage. Cross-feature helpers live in normal libraries.

Commits

  1. share a Shadcn icon-action widget across reader and library
  2. split the reader controller into Elm model, message, and effect modules
  3. split the reader view into Elm view modules
  4. split the library shell into Elm controller and view modules
  5. cover the shared Shadcn icon action and library error mapping
  6. add deterministic controller and component tests
  7. expose collection and geometry helpers for isolated tests

Deterministic Elm tests

ReaderController and LibraryController are driven directly through dispatch with injected fakes — no widget pumping:

  • test/reader/controller_test.dart: pure transitions (tools visibility, layout/viewport, invalid layout rejection), listener notification, and disposal semantics.
  • test/library/controller_test.dart: effect + completion pipeline (LibraryStarted → page completion publishes books/settings), stale-completion rejection across a newer query, and format-filter reload.
  • test/library/model_test.dart: LibraryModel.copyWith sentinel/clear semantics.
  • test/reader/geometry_test.dart: SurfaceTransform math for contain/cover and clamped mapping.
  • test/reader/painting_test.dart: page color contrast and raster pixel geometry.
  • test/library/view_test.dart: isolated LibraryCollection/LibraryBanner component tests (loading, failure, empty vs. filtered, metadata + open, load-more, actions menu, banners).
  • test/shared/shad_widgets_test.dart and test/library/errors_test.dart: helper coverage.

LibraryCollection, LibraryBanner, and SurfaceTransform were made public so they can be exercised in isolation; the load-more button now keeps its label flexible so it stays inside the card at narrow widths.

Testing

  • make test-flutter (281 tests)
  • make lint-flutter
  • make check-fmt-flutter

Follow-up

Extracting update into a free reduce(model, message) -> effects function (closer to Iced's Task<Message>) is a deeper follow-up; the current controllers already expose deterministic dispatch-driven tests. Splitting the large legacy test/widget_test.dart / test/product_shell_test.dart into per-module files still needs shared, non-private test support.

@darwin67
darwin67 merged commit 1e54270 into main Sep 13, 2026
16 checks passed
@darwin67
darwin67 deleted the refactor/flutter-elm-modules branch September 13, 2026 21:10
@chaba2-bot chaba2-bot Bot mentioned this pull request Sep 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant