Skip to content

fix(tune-editor): replace stacked globals on re-apply and host materi… - #864

Merged
hm21 merged 6 commits into
hm21:stablefrom
saif-ellafi:fix/tune-reapply-and-material-ui-host
Sep 16, 2026
Merged

hm21 merged 6 commits into
hm21:stablefrom
saif-ellafi:fix/tune-reapply-and-material-ui-host

Conversation

@saif-ellafi

@saif-ellafi saif-ellafi commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Description

Hello, I've discovered the tune editor was stacking changes instead of restoring the state. This PR was AI-assisted and includes a bundle of related issues discovered during the testing process.

Tune no longer stacks a full extra set of global matrices on every Done. Re-apply used to append the session on top of history, which could crush the image (often to black). mergeTuneAdjustments keeps timed and custom entries, replaces only this session's untimed globals, and the sliders are seeded from the latest global per id.

A custom TuneEditorWidgets.slider now receives the value it reported through onChanged instead of the value from the last drag end.

Adds TuneEditorStyle.bottomBarActiveItemDecoration so hosts can mark the selected Tune attribute without forking the bottom bar.

Maintainer edit (rebased onto stable, review commits on top): the MaterialUiLocalizationsScope shim was dropped. It only wrapped the main editor, the tune editor and two dialogs, but sub-editors, bottom sheets and the loading overlay are built under the host navigator, so in a host that still uses package:flutter/material.dart the paint, text, filter and blur editors kept failing with No MaterialLocalizations found. The host owns that fix: adding material_ui's GlobalMaterialLocalizations.delegates to the SDK MaterialApp makes the localizations visible to every route and overlay, verified against all sub-editors, the close-warning dialog and the loading dialog. The README setup section now documents it.

Related Issue: Closes #

Type of Change

  • ✨ New feature (non-breaking change which adds functionality)
  • 🛠️ Bug fix (non-breaking change which fixes an issue)
  • ❌ Breaking change (fix or feature that would cause existing functionality to change)
  • 🧹 Code refactor
  • ✅ Build configuration change
  • 📝 Documentation
  • 🗑️ Chore

@hm21
hm21 force-pushed the fix/tune-reapply-and-material-ui-host branch from f3dde8d to 5ba379b Compare September 16, 2026 06:42
saif-ellafi and others added 6 commits September 16, 2026 09:16
…al_ui dialogs

Re-applying Tune appended session matrices and crushed the image. Collapse only this session's untimed globals, keep timed and custom entries, and seed sliders from the latest global per id.

Hosts that use Flutter MaterialApp need a material_ui MaterialLocalizations ancestor for dialogs after the v14 UI migration.

Co-authored-by: Cursor <cursoragent@cursor.com>
PIE CI fails PRs that are not formatted with `dart format`.

Co-authored-by: Cursor <cursoragent@cursor.com>
… instead of an in-package shim

MaterialUiLocalizationsScope wrapped the main editor, the tune editor and
two dialogs. Sub-editors are pushed onto the host navigator, bottom sheets
and the loading overlay are built there as well, so in a host that still
uses `package:flutter/material.dart` the paint, text, filter and blur
editors kept failing with "No MaterialLocalizations found" while only the
tune editor worked. Every entry point would need the wrapper, and any new
one would be a regression.

The host owns the fix: adding material_ui's
`GlobalMaterialLocalizations.delegates` to the SDK `MaterialApp` makes the
`material_ui` and `cupertino_ui` localizations visible to every route and
overlay. The README setup section now says so; the widget and its tests
are gone.
- Seed the sliders from one map pass over the applied adjustments instead
  of scanning the list once per slider through a helper; the map's
  last-write-wins already yields the latest untimed entry per id.
- Rename mergeTuneEditorResult to mergeTuneAdjustments, matching the file
  and the mergeFilterStates sibling, and name its parameters after what
  they hold (applied, sliders).
- Drop the extra copy in openTuneEditor; addHistory copies every entry it
  records.
- Accept any Decoration for bottomBarActiveItemDecoration, not only
  BoxDecoration.
- Fold the state lookup into the cascade in the main editor tests, which
  cascade_invocations flagged and CI treats as fatal.
The preview rendered the merged list, i.e. the applied adjustments plus
the sliders. Two problems with that:

- The tune editor's FilteredWidget has no play position, so timed entries
  in the applied list were applied unconditionally, whatever their window.
- A host that keeps its own adjustment list and seeds the sliders from the
  entry being edited (divine-mobile does this per tune "set") saw that
  entry twice: once from the applied list and once from the slider.

Only done() merges; the preview shows what the sliders edit, as on
stable. A test pins the contract.
@hm21
hm21 force-pushed the fix/tune-reapply-and-material-ui-host branch from d152e88 to a311589 Compare September 16, 2026 07:16
@hm21

hm21 commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Thanks a lot for this PR, @saif-ellafi — great catch on the stacking bug, and the tests you brought along made the review much easier. The setTuneTimeline-aware merge is exactly the right idea, so the core of your change is going in as you wrote it.

Here is what changed on top of your commits before merging:

  • Rebased onto stable (which also picked up ci: test the Flutter 3.44 leg against the material_ui floor #869, a CI fix for the Flutter 3.44 leg unrelated to your change).
  • MaterialUiLocalizationsScope was dropped in favour of a README note. The shim covered the main editor, the tune editor and two dialogs, but every other sub-editor, showModalBottomSheet, showMenu and the loading overlay are built under the host navigator too, so in a host that still uses package:flutter/material.dart the paint, text, filter and blur editors kept failing with No MaterialLocalizations found. Wrapping all ~12 entry points would be fragile, and the host can fix it in one line: localizationsDelegates: material_ui.GlobalMaterialLocalizations.delegates on the SDK MaterialApp. I verified that against every sub-editor and both dialogs; the README setup section now documents it — that should also cover your app.
  • Merge helper simplified: the sliders are now seeded from one map pass (last write wins), mergeTuneEditorResult became mergeTuneAdjustments(applied:, sliders:) to match the file and its mergeFilterStates sibling, and the extra copy in openTuneEditor is gone since addHistory already copies.
  • The tune editor's live preview stays sliders-only (as on stable), only done() merges. The preview has no play position, so timed entries in the applied list would have been applied regardless of their window, and a host that seeds the sliders from an applied entry would have seen it twice. A test pins that.
  • bottomBarActiveItemDecoration accepts any Decoration, two cascade_invocations infos that CI treats as fatal are fixed, and the release is bumped to 14.3.0 with changelog entries.

Also verified against a large downstream app that drives the tune editor on a video timeline (~20k tests, plus a manual run on device). Thanks again!

@hm21
hm21 merged commit 66b1002 into hm21:stable Sep 16, 2026
3 checks passed
@saif-ellafi

Copy link
Copy Markdown
Contributor Author

Amazing, I'm glad it helped. It's hard to take credit anymore unlike in my first PRs back then :) but well, at least the trigger and the testing!

Cheers for improving the library

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