Restructure into a monorepo: standalone LiquidToasts Swift package + Flutter plugin - #9
Merged
Merged
Conversation
… plugin) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CcBgqiJJfA28A8BKzdUWq
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CcBgqiJJfA28A8BKzdUWq
…e, org URL Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CcBgqiJJfA28A8BKzdUWq
Wire decoding moves out of Models.swift into bridge-side WireModels.swift; the models gain plain memberwise initializers whose defaults mirror the wire defaults exactly. Image bytes already crossed the plugin boundary as Data. Flutter is now imported only by LiquidToastsPlugin.swift and WireModels.swift. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CcBgqiJJfA28A8BKzdUWq
Typed events and dismiss reasons (raw values are the wire strings), listener fanout on ToastManager (bridge and native facade coexist on one stack), a curated public surface for the future core module, and the native facade: LiquidToast.show/success/error/warning/info/loading, LiquidToastHandle with patch updates and dismissal callbacks/await, async promise that returns the value and rethrows, native id minting, and a SemanticDefaults table kept in lockstep with lib/src/semantic_defaults.dart. Flutter wire behavior is unchanged (event maps verified key-for-key; flushed events never cross). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CcBgqiJJfA28A8BKzdUWq
…er plugin liquid-toasts-swift/Sources/LiquidToasts is the Flutter-free core, built by a root Package.swift (SwiftPM requires the manifest at the repo root for git-URL installs). The Flutter plugin moves to liquid_toasts/ (basename doubles as its SwiftPM identity, ending the checkout-rename caveat) and its ios package keeps only the bridge (plugin + wire decoding), consuming the core by relative path. The podspec is deleted (SwiftPM-only). URLs point at SimplifyJobs; new umbrella and native READMEs; CLAUDE.md rewritten for the layout. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CcBgqiJJfA28A8BKzdUWq
ci.yml runs dart analyze/test, an iOS-simulator build of the root LiquidToasts package, the example app in SwiftPM mode, and the plugin's Android unit tests. release.yml fires on v* tags: it reuses ci.yml via workflow_call, guards that the tag matches the pubspec version, and publishes a GitHub Release whose body is that version's CHANGELOG section plus a pinned install block. Version bumps to 0.8.0 with a CHANGELOG entry covering the restructure and the two breaking install changes (CocoaPods dropped; git dependency with path). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CcBgqiJJfA28A8BKzdUWq
There was a problem hiding this comment.
All reported issues were addressed across 176 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
- CI: xcodebuild's auto-generated scheme is named after the package (liquid-toasts), not the product; fix the swift job and add a -list step. - LiquidToastCenter.dismissAll: snapshot registry ids before the sweep so a toast shown from an onDismissed callback mid-sweep isn't completed out from under its live view. - ToastDuration: treat non-finite or un-representable intervals as persistent instead of trapping in the Int conversion. - LiquidToastsPlugin: unregister the event listener in detachFromEngine so re-registration doesn't stack dead listeners on the app-lifetime manager. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CcBgqiJJfA28A8BKzdUWq
There was a problem hiding this comment.
All reported issues were addressed across 5 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CcBgqiJJfA28A8BKzdUWq
The useDynamicIslandOrigin flag threaded through every layer (Dart model and facades, wire, Android and iOS decoders, Swift facade) but no renderer on any platform ever consulted it — it is gone entirely, including the geometry snapshot's supportsDynamicIslandOrigin key. Both wire decoders defaulted when the key was absent, so protocolVersion stays 1; queryGeometry still reports the cutout itself. The long-deprecated legacy LiquidToasts facade, LoadingToast, and showLoading are deleted (every member has a one-line toast.* equivalent, mapped in the CHANGELOG), along with legacy_facade_test.dart. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CcBgqiJJfA28A8BKzdUWq
The wrap decision now has a synchronous UIKit pre-measurement (ToastPreMeasurement, mirroring the off-screen probe's reference-width math) that seeds ToastView's initial state, so a tall toast's first layout is already at final height and the sibling push is one continuous spring. Previously the toast entered at single-line height and grew a frame later when the probe landed — an unanimated re-layout that snapped every visible sibling down before the spring caught up. The probe still confirms after layout; a disagreement (or a later morph across the wrap boundary) animates instead of applying instantly, so the didMeasure gate is gone. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CcBgqiJJfA28A8BKzdUWq
There was a problem hiding this comment.
All reported issues were addressed across 4 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
A wide action label could skew the pre-measured wrap decision (it used the flat 72pt estimate) and shift the toast's height once the live button reported its width. ToastPreMeasurement now measures the label at the button's real font + capsule insets (routed through ToastMetrics so the lockstep is structural) and seeds both actionWidth and the wrap decision, so the probe's first pass agrees with the entrance layout even for action toasts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CcBgqiJJfA28A8BKzdUWq
With both CGSize members implicit, the literal resolves against CGFloat and Double candidates and fails to compile; spell the type out. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CcBgqiJJfA28A8BKzdUWq
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Restructures the repo so the SwiftUI renderer is a standalone Swift package installable straight from GitHub in any iOS app, with the Flutter plugin living beside it and consuming it by relative path. The wire protocol is unchanged (
protocolVersionstays 1); the Dart API is unchanged except for two deliberate removals listed under breaking changes. Executed per the approved plan indocs/monorepo-plan.md.Layout
What changed, phase by phase (one commit each)
Models.swiftinto bridge-sideWireModels.swift; the models gained plain memberwise initializers whose defaults mirror the wire defaults exactly. Flutter is imported only by the plugin and the wire decoders.ToastManager, a curatedpublicsurface, and the nativeLiquidToastfacade:show/semantic variants/loading, live handles with patch updates and dismissal callbacks/await, an asyncpromisethat returns the value and rethrows, native id minting that coexists with Dart-minted ids on one stack, and aSemanticDefaultstable kept in lockstep withlib/src/semantic_defaults.dart(cross-reference comments in both files). Event dictionaries reaching Dart were verified key-for-key identical.ci.yml(Dart analyze/test, iOS-simulator build of the root package, example app in SwiftPM mode, Android unit tests) andrelease.yml(fires onv*tags, reuses ci.yml, guards tag == pubspec version, publishes a GitHub Release from the CHANGELOG section). Version bumped to 0.8.0 with a CHANGELOG entry.Follow-up commits on this branch: fixes from the first CI run and review round (scheme name,
dismissAllre-entrancy snapshot, non-finite duration guard, plugin listener teardown on engine detach), and the two API removals below.Breaking changes (all in the 0.8.0 CHANGELOG with migration pointers)
flutter config --enable-swift-package-manager.path: liquid_toastsandref: vX.Y.Z; pub.dev publishing is deferred (would need a vendoring step — documented in the plan).useDynamicIslandOriginremoved entirely — fromToast, everytoast.*method,ToastHandle.update, the wire, the Android/iOS decoders, the native facade, and the geometry snapshot'ssupportsDynamicIslandOriginkey. No renderer on either platform ever consulted it.toast.queryGeometry()still reports the cutout itself.LiquidToastsfacade,LoadingToast, andshowLoadingare deleted (were marked "Removed in 1.0"); every member has a one-linetoast.*equivalent.Needs verification on macOS (no Apple toolchain in this environment)
CI covers the builds (the
swift,example, andandroidjobs compile everything, and the example job exercises the plugin-through-SwiftPM symlink path — the plan's one flagged structural risk, now passing). Before taggingv0.8.0, still worth a human pass:bg_probe_demo.dart,render_probe_demo.dart) to confirm runtime behavior is unchanged.LiquidToastfacade.🤖 Generated with Claude Code
https://claude.ai/code/session_014CcBgqiJJfA28A8BKzdUWq