call_ui_kit 0.6.0
call_ui_kit: ^0.6.0 copied to clipboard
A ready-to-use Flutter call UI kit for personal audio, video, and group calls.
0.6.0 #
Every size the kit lays out is now configurable. It used to hard-code all of them, so a host could restyle the colours and the text but never the metrics.
Added #
-
CallDimensions— the sizing counterpart toCallTheme. Pass it toCallScreen,IncomingCallScreenorOutgoingCallScreen. It composes one token class per surface, so a host names the metric it wants instead of reaching into a widget it cannot see:CallScreen( dimensions: const CallDimensions( bottomBar: CallBottomBarDimensions( buttonSize: 56, // was 50 endCallButtonSize: 72, // was 58 ), pip: CallPipDimensions(size: Size(120, 160)), // was 90x120 ), ... ) -
Fourteen token classes, each with
copyWith,==andhashCode, covering all 138 metrics the kit lays out:CallTopBarDimensions,CallBottomBarDimensions,CallRightButtonsDimensions,CallVideoContentDimensions,CallParticipantTileDimensions,CallThumbnailRowDimensions,CallPipDimensions,CallConnectionBannerDimensions,CallScreenShareBannerDimensions,CallParticipantsPanelDimensions,CallMoreSheetDimensions,CallHandleBarDimensions,CallIncomingScreenDimensionsandCallOutgoingScreenDimensions. -
CallDimensions.scale— a multiplier over every token, for enlarging the whole UI at once. The kit's sizes are raw logical pixels, which suit a phone at reading distance but leave the controls smaller than the rest of a tablet host. It composes with the tokens:endCallButtonSize: 72atscale: 1.25renders 90. -
CallDimensions.compact()andCallDimensions.comfortable()presets.compact()is the kit's original phone layout;comfortable()is sized for a tablet, or for a device used at arm's length and in gloves. -
CallDimensions.rightButtonsHeight, alongsidetopBarHeight,bottomBarHeightandconnectionBannerHeight. A host composing its own overlay has to reserve the same space, and the layer widgets are not exported. -
dimensionson every exported widget —ParticipantTile,FloatingPipView,MoreBottomSheet,ParticipantsPanel,ConnectionStateBanner,ScreenShareBanner,HandleBar— defaulting toconst CallDimensions(). -
SpeakingIndicator.gap. The bar spacing was hard-coded as2in two independent places, so a widerbarWidthleft the cluster too tight and the two literals could drift apart.
Improvements #
CallScreenderives its PiP insets from the dimensions rather than from static bar heights, so the PiP keeps clear of the controls at any size.- Tap targets in
CallTopBarfollow the icon size.IconButtonwould otherwise stay at its default 48 px however large the glyph grew. - The participant tile's speaking border and the group grid's gutters were bare literals in the middle of a build method. They are tokens now — still hairlines by default, and still exempt from
scale, but no longer unreachable.
Breaking #
CallTopBar.height,CallBottomBar.heightandConnectionStateBanner.heightare replaced byCallDimensions.topBarHeight,.bottomBarHeightand.connectionBannerHeight. A constant cannot follow a configurable size, and leaving one behind is how a host ends up reserving the wrong space — see the94vs102bug fixed in 0.5.0.
Notes #
const CallDimensions()reproduces the 0.5.0 metrics exactly, so existing consumers see no visual change — the goldens pass unmodified, andcall_dimensions_test.dartasserts every default against the number the kit used to hard-code.- Four fields are deliberately exempt from
scale, each documented where it is declared:CallPipDimensions.borderWidth,CallParticipantTileDimensions.speakingBorderWidthandCallVideoContentDimensions.gridGutterare hairlines, which should stay hairlines however large the rest grows;CallVideoContentDimensions.personalAvatarFontRatiois a ratio, and the avatar it multiplies is already scaled. - Font sizes are still multiplied by the host's
MediaQuery.textScaler. A large accessibility text scale combined with large font tokens can overflow the fixed-height bars.
0.5.0 #
Fixed #
- Local video no longer shows as a transparent hole in the PiP — the frame had no background, so a renderer that stopped painting (a texture disposed by a reconnect) showed straight through. All external video widgets now sit on an opaque
VideoSurface. - Group video no longer goes stale after a reconnect: the cached participant list ignored
videoWidgetchanges and kept rendering the disposed renderer. - PiP no longer drifts to another corner when the controls fade. It still follows them WhatsApp-style, but now stores its corner instead of a pixel offset.
- Bottom bar no longer swallows taps and drags aimed at the PiP.
- Buttons still visibly fading out now respond to taps (300 ms dead window removed).
- Turning the local camera off no longer blanks the remote video after a tap-to-swap.
- Personal-call fallback no longer claims the remote party's camera is off.
- Screen-share banner now also appears in personal calls.
- Modal sheets pause the auto-hide timer and refresh with the call state instead of showing a snapshot.
CallBottomBar.heightwas94while the bar measured102, halving the gap the PiP keeps from the controls.
Added #
CallConnectionStateandConnectionStateBanner— passconnectionStatefor a persistent "Connecting…"/"Reconnecting…" banner. AddsCallStrings.connectingandCallStrings.reconnecting.callStatusListenable— for values that tick, such as a call timer.callStatusTextmakes the hostsetState, which rebuilds every video surface once per tick (30 rebuilds per 10 s with three participants); a listenable rebuilds only the status line.PipCorner,PipSnapCalculator.nearestCorner/offsetForCorner/clampToBounds.- Golden tests for six layouts, and CI running format, analysis and tests.
- README: "Reconnection" and "Performance" sections.
Breaking #
- Removed
_VideoErrorBoundary(0.4.0) in favour ofVideoSurface. It never worked: Flutter catches paint exceptions inRenderObject._paintWithContextwithout rethrowing, so an ancestortry/catchwas never reached. CallScreen: removedisHandRaisedandonRaiseHand, which were accepted and never used.FloatingPipView:controlsVisibleis deprecated and ignored — pass visibility-dependenttopBarHeight/controlsHeightinstead.- Internal layers:
CallTopBar.callTypeandCallBottomBar.bottomPaddingremoved.
0.4.0 #
Performance #
- Narrow
LayoutBuilderscope inCallScreen— onlyFloatingPipViewrebuilds on constraint changes instead of all 5 layers. - Pre-compute
allParticipantslist indidUpdateWidgetinstead of allocating on every build. - Add
ValueKeytoParticipantTilein grid layouts for correct widget reuse across participant reorders. - Add
RepaintBoundarytoScreenShareBannerslide animation to isolate repaints.
Improvements #
- Animate grid layout transitions with
AnimatedPositioned(250ms easeOutCubic) — smooth tile repositioning when participants join or leave. - Add
Semanticsto all call control buttons,ParticipantTile, andSignalStrengthIconfor screen reader accessibility. - Add
endCall,speaker,camera,moreOptionslocalisation strings toCallStrings. - Extract controls visibility timer into
_ControlsVisibilityControllerfor cleanerCallScreenstate management. - Add defensive timer cancellation in
_startHideTimer()to prevent timer leaks. - Add
_VideoErrorBoundaryaround externally-provided video widgets — catches rendering errors at theRenderObjectlevel and shows a fallback instead of crashing the call screen. - Add
toString()toCallParticipantandCallThemefor easier debugging. - Document why
videoWidget/screenShareWidgetare excluded fromCallParticipantequality.
Breaking Changes #
CallBottomBar: now requires astrings(CallStrings) parameter for accessibility labels.CallVideoContent: new optionalallParticipantsparameter — pass a pre-built list to avoid per-build allocation.
0.3.1 #
Bug Fixes #
- Fix remote video being hidden when local camera is turned off in personal (1-on-1) calls.
0.3.0 #
Improvements #
- Wrap
CallScreenScaffold withSafeArea— all content now respects device insets automatically. - Replace manual
MediaQuery.paddingOfsafe area handling withLayoutBuilderfor accurate sizing. - Remove
EdgeInsets safeAreaparameter fromCallTopBarandCallBottomBar. - Remove
safeAreaLeft/Right/Top/Bottomparameters fromFloatingPipView. - Remove redundant
SafeAreawrapper fromCallVideoContentgroup call layout.
Breaking Changes #
CallTopBar: removedsafeAreaparameter.CallBottomBar: replacedsafeAreaparameter withbottomPadding(double).FloatingPipView: removedsafeAreaLeft,safeAreaRight,safeAreaTop,safeAreaBottomparameters.
0.2.1 #
- Lower minimum SDK constraints from Dart
^3.11.3/ Flutter>=3.29.0to Dart^3.4.0/ Flutter>=3.22.0for wider compatibility.
0.2.0 #
Performance #
- Cache
CallStrings.english()asCallStrings.englishDefaultsto prevent cascading widget rebuilds. - Extract speaking border animation into isolated
StatefulWidget—ParticipantTileis now aStatelessWidget. - Keep
SpeakingIndicatorin widget tree permanently and toggle viavisibleparameter instead of destroying/recreating theAnimationController. - Skip rendering
SignalStrengthIconwhen signal strength isexcellent(the default). - Cache screen sharer name lookup in
didUpdateWidgetinstead of scanning participants on every build. - Add
RepaintBoundarytoFloatingPipViewchild to isolate video repaints during snap animation. - Remove
_DefaultStringssentinel class (~60 lines of boilerplate).
Bug Fixes #
- Show remote screen share content in personal (1:1) call layout — previously
screenShareWidgetwas ignored outside group calls.
Breaking Changes #
CallScreen.stringsis now nullable (CallStrings?). Passnullor omit to use English defaults. Previously accepted a non-nullCallStringswith an internal sentinel.CallStrings.englishDefaultsis a new cached static field — use it instead ofCallStrings.english()when a stable reference is needed.
0.1.1 #
- Use GitHub-hosted screenshots to reduce package size.
- Exclude build artifacts from published package.
0.1.0 #
- Initial release.
CallScreenwidget for personal audio, personal video, and group calls.- Adaptive group call layouts: 2x2 grid, 2x3 grid, speaker view, screen share view.
- Draggable PiP (Picture-in-Picture) view with corner snapping.
- Animated speaking indicators and speaking tile borders.
- Signal strength indicator per participant.
- Participants panel with host actions (mute, remove).
- Customizable "more" bottom sheet with encryption label.
- Screen share banner with stop button.
- Full theming via
CallThemewith WhatsApp preset. - Full localization via
CallStringswith English defaults. - Zero external dependencies.