mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
## Summary - Polish mobile Home, Activity, Search, and Settings navigation chrome. - Add progressive Buzz gradients/frost, aligned theme colors, dividers, typography, and section spacing. - Refine Search and Settings motion, including automatic keyboard focus on search activation. <img width="630" height="1368" alt="C78FA3CE-F2B3-45F2-B9F5-7EA7500778CC" src="https://github.com/user-attachments/assets/5935514b-d894-4010-80dd-a938363fee93" /> <img width="630" height="1368" alt="5C058A73-1879-476A-881C-531ACC256D84" src="https://github.com/user-attachments/assets/5266c841-17ee-49e8-9841-b06d84f4195f" /> <img width="630" height="1368" alt="3F50ADB7-9BDA-4A8D-A81E-20560C3B9EA6" src="https://github.com/user-attachments/assets/f615f61e-9e96-4bce-b261-ae5ec54db872" /> <img width="630" height="1368" alt="35ECE741-01F3-4B79-80C5-1DDD447121A7" src="https://github.com/user-attachments/assets/b5145186-9884-44eb-8ebc-f3303831c0a4" /> ## Validation - `flutter analyze` - Focused Home, Activity, Channels, Search, theme, and footer widget tests - Full pre-push checks, including mobile tests, desktop checks, and Tauri checks - On-device iPhone review during the visual polish pass --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Signed-off-by: npub1glqcqfjxdens59scl477pmejh8lht4hqkhx0y4w38jxr6e6w6y2sm29y4e <47c18026466e670a1618fd7de0ef32b9ff75d6e0b5ccf255d13c8c3d674ed115@buzz.block.builderlab.xyz> Signed-off-by: Code Reviewer <037593536284cf40e221c96c931e9877d4166d54f6bb84e5341a86d7fd5d05a4@buzz.block.builderlab.xyz> Signed-off-by: Kenny Lopez <klopez4212@gmail.com> Co-authored-by: npub1glqcqfjxdens59scl477pmejh8lht4hqkhx0y4w38jxr6e6w6y2sm29y4e <47c18026466e670a1618fd7de0ef32b9ff75d6e0b5ccf255d13c8c3d674ed115@buzz.block.builderlab.xyz> Co-authored-by: Code Reviewer <037593536284cf40e221c96c931e9877d4166d54f6bb84e5341a86d7fd5d05a4@buzz.block.builderlab.xyz>
86 lines
2.8 KiB
Dart
86 lines
2.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import 'directional_transition_scope.dart';
|
|
import 'frosted_app_bar.dart';
|
|
|
|
/// A convenience [Scaffold] that overlays a [FrostedAppBar] on top of its body.
|
|
///
|
|
/// The body is rendered full-bleed inside a [Stack] with the frosted app bar
|
|
/// floating above it. The body is responsible for adding its own top spacing
|
|
/// using [frostedAppBarHeight] so content starts below the bar.
|
|
class FrostedScaffold extends StatelessWidget {
|
|
/// The frosted app bar displayed at the top of the screen.
|
|
final FrostedAppBar appBar;
|
|
|
|
/// The primary content of the scaffold. Must handle its own top spacing
|
|
/// using [frostedAppBarHeight] — the scaffold does NOT add automatic padding.
|
|
final Widget body;
|
|
|
|
/// Optional floating action button, passed through to [Scaffold].
|
|
final Widget? floatingActionButton;
|
|
|
|
/// Whether the body should resize when the on-screen keyboard appears.
|
|
final bool? resizeToAvoidBottomInset;
|
|
|
|
/// Optional scaffold background, useful when a parent supplies a shared
|
|
/// surface behind this page.
|
|
final Color? backgroundColor;
|
|
|
|
/// A fixed gradient painted behind the app bar and scrolling body.
|
|
final Gradient? backgroundGradient;
|
|
|
|
const FrostedScaffold({
|
|
super.key,
|
|
required this.appBar,
|
|
required this.body,
|
|
this.floatingActionButton,
|
|
this.resizeToAvoidBottomInset,
|
|
this.backgroundColor,
|
|
this.backgroundGradient,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: backgroundColor,
|
|
resizeToAvoidBottomInset: resizeToAvoidBottomInset,
|
|
floatingActionButton: floatingActionButton,
|
|
body: Stack(children: _stackChildren()),
|
|
);
|
|
}
|
|
|
|
List<Widget> _stackChildren() {
|
|
final backdrop = backgroundGradient == null
|
|
? const <Widget>[]
|
|
: [
|
|
Positioned.fill(
|
|
child: _PinnedGradientBackground(gradient: backgroundGradient!),
|
|
),
|
|
];
|
|
final bodyMotion = DirectionalTransitionMotion(
|
|
transformKey: const ValueKey(
|
|
'frosted-scaffold-body-transition-transform',
|
|
),
|
|
opacityKey: const ValueKey('frosted-scaffold-body-transition-opacity'),
|
|
child: body,
|
|
);
|
|
// The bar must be painted after the scrollable sheet: [BackdropFilter]
|
|
// only samples pixels that were already painted behind it. This is the
|
|
// same composition as channel navigation, so top-level headers blur their
|
|
// content rather than only the fixed gradient.
|
|
return [...backdrop, bodyMotion, appBar];
|
|
}
|
|
}
|
|
|
|
class _PinnedGradientBackground extends StatelessWidget {
|
|
final Gradient gradient;
|
|
|
|
const _PinnedGradientBackground({required this.gradient});
|
|
|
|
@override
|
|
Widget build(BuildContext context) => DecoratedBox(
|
|
key: const ValueKey('frosted-scaffold-pinned-gradient'),
|
|
decoration: BoxDecoration(gradient: gradient),
|
|
);
|
|
}
|