mirror of
https://github.com/block/buzz.git
synced 2026-11-07 18:01:06 +00:00
Replace the mobile organization sign-in bottom card with the existing top toast treatment. Use shorter status copy, a solid-red Cancel button with white text in both modes, and stacked Retry / Use a different account buttons for denied access with 12 pt side and bottom padding. The account-switch action uses a dark secondary treatment. Recovery callbacks and visibility rules are preserved. Validation: `just mobile-install mobile-check mobile-test`; widget journeys cover sign-in/cancel/completion, saved-session errors, account switching at 200% text size, and transient-toast coordination. The cancel regression was verified to fail with its callback disabled. Local Flutter previews using production widgets, with synthetic state; not device captures. Manual test: sign in, cancel, retry, and switch accounts after denied access; verify each action remains reachable and the toast clears after successful sign-in. Before:  | Light mode · 375 pt | Dark mode · 375 pt | | --- | --- | |  |  | --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz>
54 lines
1.6 KiB
Dart
54 lines
1.6 KiB
Dart
part of 'buzz_toast.dart';
|
|
|
|
/// Parent-owned persistent feedback with the same motion as transient toasts.
|
|
class ReconnectCapsule extends HookWidget {
|
|
const ReconnectCapsule({
|
|
super.key,
|
|
required this.onSignIn,
|
|
this.visible = true,
|
|
this.message = 'Reconnect to Builderlab',
|
|
this.actionLabel = 'Sign in',
|
|
this.destructiveAction = false,
|
|
this.secondaryAction,
|
|
this.islandOrigin,
|
|
this.islandSpeed = 0.75,
|
|
});
|
|
|
|
final VoidCallback onSignIn;
|
|
final bool visible;
|
|
|
|
/// Persistent status displayed beside or above the actions.
|
|
final String message;
|
|
|
|
/// Label for the primary recovery action.
|
|
final String actionLabel;
|
|
|
|
/// Uses the theme error colors for the primary action.
|
|
final bool destructiveAction;
|
|
|
|
/// Adds a second recovery action and stacks both buttons below the message.
|
|
final ({String label, VoidCallback onPressed})? secondaryAction;
|
|
final Rect? islandOrigin;
|
|
final double islandSpeed;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final transientVisible = useValueListenable(_toastCoordinator(context));
|
|
// Remove immediately so neither text nor island surfaces overlap.
|
|
// Remounting after dismissal restarts the persistent entrance if needed.
|
|
if (transientVisible) return const SizedBox.shrink();
|
|
return _ToastBubble(
|
|
message: message,
|
|
actionLabel: actionLabel,
|
|
destructiveAction: destructiveAction,
|
|
secondaryAction: secondaryAction,
|
|
onRetry: onSignIn,
|
|
onDismiss: () {},
|
|
persistent: true,
|
|
visible: visible,
|
|
islandOrigin: islandOrigin,
|
|
islandSpeed: islandSpeed,
|
|
);
|
|
}
|
|
}
|