mirror of
https://github.com/block/buzz.git
synced 2026-10-28 13:01:10 +00:00
Originally stacked on #8375, now merged. Rebased onto main. Polishes the onboarding landing page, community-link entry, and recovery sheets. Profile setup uses a consistent sheet with a larger avatar, inline display name, and draft photo/emoji/animated editing; iOS uses native controls and coordinated avatar/sheet transitions. Validation: mobile analysis, full tests, and normal pre-push checks passed after rebase. Prior iOS build and device walkthrough passed; native validation was not repeated after this rebase. Snapshots omitted as requested. --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Co-authored-by: Tom Brow <tomb@block.xyz>
125 lines
3.9 KiB
Dart
125 lines
3.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
|
|
|
import '../theme/theme.dart';
|
|
import 'buzz_sheet_header.dart';
|
|
import 'concentric_sheet_surface.dart';
|
|
|
|
/// Shared solid sheet surface with a centered navigation row.
|
|
class BuzzTitledSheetLayout extends HookWidget {
|
|
const BuzzTitledSheetLayout({
|
|
super.key,
|
|
required this.title,
|
|
required this.child,
|
|
this.leading,
|
|
this.trailing,
|
|
this.onClose,
|
|
this.titleKey,
|
|
this.showDragHandle = false,
|
|
this.surfaceColor,
|
|
});
|
|
|
|
final String title;
|
|
final Widget child;
|
|
final Widget? leading;
|
|
final Widget? trailing;
|
|
|
|
/// Overrides the header close action; null dismisses the current route.
|
|
final VoidCallback? onClose;
|
|
final Key? titleKey;
|
|
final bool showDragHandle;
|
|
final Color? surfaceColor;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final isScrolledUnder = useState(false);
|
|
final pendingScrolledUnder = useRef<bool?>(null);
|
|
final scrollUpdateScheduled = useRef(false);
|
|
final color = surfaceColor ?? context.colors.surface;
|
|
final paintsSurface = !ConcentricSheetSurface.providesSurfaceOf(context);
|
|
|
|
void updateScrollUnder(bool next) {
|
|
if (scrollUpdateScheduled.value) {
|
|
pendingScrolledUnder.value =
|
|
(pendingScrolledUnder.value ?? false) || next;
|
|
return;
|
|
}
|
|
pendingScrolledUnder.value = next;
|
|
scrollUpdateScheduled.value = true;
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
scrollUpdateScheduled.value = false;
|
|
final pending = pendingScrolledUnder.value;
|
|
pendingScrolledUnder.value = null;
|
|
if (!context.mounted ||
|
|
pending == null ||
|
|
pending == isScrolledUnder.value) {
|
|
return;
|
|
}
|
|
isScrolledUnder.value = pending;
|
|
});
|
|
}
|
|
|
|
final sheet = SizedBox(
|
|
width: double.infinity,
|
|
child: ColoredBox(
|
|
key: const ValueKey('buzz-sheet-surface'),
|
|
color: paintsSurface ? color : Colors.transparent,
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
DecoratedBox(
|
|
key: const ValueKey('buzz-sheet-scroll-divider'),
|
|
decoration: BoxDecoration(
|
|
border: Border(
|
|
bottom: BorderSide(
|
|
color: isScrolledUnder.value
|
|
? navigationDivider(context, 0.05)
|
|
: Colors.transparent,
|
|
),
|
|
),
|
|
),
|
|
child: BuzzSheetHeader(
|
|
title: title,
|
|
titleKey: titleKey,
|
|
leading: leading,
|
|
trailing: trailing,
|
|
onClose: onClose,
|
|
showDragHandle: showDragHandle,
|
|
),
|
|
),
|
|
Flexible(
|
|
child: NotificationListener<ScrollNotification>(
|
|
onNotification: (notification) {
|
|
if (notification.depth != 0 ||
|
|
notification.metrics.axis != Axis.vertical ||
|
|
(notification is! ScrollUpdateNotification &&
|
|
notification is! OverscrollNotification)) {
|
|
return false;
|
|
}
|
|
final next = notification.metrics.extentBefore > 0.5;
|
|
if (next != isScrolledUnder.value) updateScrollUnder(next);
|
|
return false;
|
|
},
|
|
child: child,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
|
|
// The native iOS surface owns its exact iOS 26 container-concentric mask.
|
|
// A second fixed Flutter radius would visibly square off those corners.
|
|
if (!paintsSurface) return sheet;
|
|
|
|
return ClipRRect(
|
|
key: const ValueKey('buzz-sheet-surface-clip'),
|
|
borderRadius: const BorderRadius.vertical(
|
|
top: Radius.circular(Radii.dialog),
|
|
),
|
|
clipBehavior: Clip.antiAlias,
|
|
child: sheet,
|
|
);
|
|
}
|
|
}
|