mirror of
https://github.com/block/buzz.git
synced 2026-10-31 14:31:02 +00:00
## Summary - add sticky date headers that crossfade with in-timeline dates - replace the Latest pill with a centered down-arrow control - animate the control out from its bottom-center anchor <img width="630" height="1368" alt="2AF1BB3F-B295-4084-8A65-90AED60B58B5" src="https://github.com/user-attachments/assets/505de450-66f5-4628-8c59-34b5511ffb5c" /> ## Validation - `bin/just mobile-check` - `bin/just mobile-test` (1,359 tests) - Android debug and signed iOS release builds --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Signed-off-by: Kenny Lopez <klopez4212@gmail.com> Co-authored-by: Fast Fizz <2df81cb51f05a9d5387ef24d7b9ecb8fcdfcd1c70ffabc67061c9596e1b5b1c4@buzz.block.builderlab.xyz>
62 lines
1.8 KiB
Dart
62 lines
1.8 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
import '../../shared/theme/theme.dart';
|
|
|
|
/// In-flow date label. The active date gains a glass capsule when it sticks.
|
|
class DayDivider extends StatelessWidget {
|
|
final String label;
|
|
final int? dayTimestamp;
|
|
final ValueListenable<int?>? stickyDayTimestamp;
|
|
|
|
const DayDivider({
|
|
super.key,
|
|
required this.label,
|
|
this.dayTimestamp,
|
|
this.stickyDayTimestamp,
|
|
});
|
|
|
|
Widget _buildOpacity(BuildContext context, {required bool isSticky}) {
|
|
return ExcludeSemantics(
|
|
excluding: isSticky,
|
|
child: AnimatedOpacity(
|
|
key: dayTimestamp == null
|
|
? null
|
|
: ValueKey('channel-day-divider-opacity-$dayTimestamp'),
|
|
duration: MediaQuery.disableAnimationsOf(context)
|
|
? Duration.zero
|
|
: const Duration(milliseconds: 120),
|
|
curve: Curves.easeOutCubic,
|
|
opacity: isSticky ? 0 : 1,
|
|
child: Text(
|
|
label,
|
|
style: context.textTheme.labelSmall?.copyWith(
|
|
color: context.colors.onSurfaceVariant.withValues(alpha: 0.72),
|
|
fontWeight: FontWeight.w500,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final activeTimestamp = stickyDayTimestamp;
|
|
final timestamp = dayTimestamp;
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: Grid.xxs + Grid.quarter),
|
|
child: Center(
|
|
child: activeTimestamp == null || timestamp == null
|
|
? _buildOpacity(context, isSticky: false)
|
|
: ValueListenableBuilder<int?>(
|
|
valueListenable: activeTimestamp,
|
|
builder: (context, activeDayTimestamp, _) => _buildOpacity(
|
|
context,
|
|
isSticky: activeDayTimestamp == timestamp,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|