Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
@@ -1,31 +1,55 @@
|
|||||||
import 'package:toaster_ui/toaster_ui.dart';
|
import 'package:toaster_ui/toaster_ui.dart';
|
||||||
|
|
||||||
|
const _toasts = [
|
||||||
|
(
|
||||||
|
icon: Icons.chat_bubble_outline,
|
||||||
|
title: 'Messages',
|
||||||
|
timestamp: '10:42 AM',
|
||||||
|
content: 'New message received from +1 (555) 019-2834',
|
||||||
|
tags: ['res/values/strings.xml', 'en-US'],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
icon: Icons.notifications_outlined,
|
||||||
|
title: 'Push Notification',
|
||||||
|
timestamp: '10:45 AM',
|
||||||
|
content: 'Your order has been shipped!',
|
||||||
|
tags: ['res/values/strings.xml', 'en-US'],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
icon: Icons.email_outlined,
|
||||||
|
title: 'Email',
|
||||||
|
timestamp: '11:03 AM',
|
||||||
|
content: 'You have a new message in your inbox.',
|
||||||
|
tags: ['res/values/strings.xml', 'en-US'],
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
class HomeScreen extends StatelessWidget {
|
class HomeScreen extends StatelessWidget {
|
||||||
const HomeScreen({super.key});
|
const HomeScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final spacing = context.appSpacing;
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Center(
|
body: ListView.builder(
|
||||||
child: Column(
|
padding: EdgeInsets.all(spacing.md),
|
||||||
mainAxisAlignment: .center,
|
itemCount: _toasts.length,
|
||||||
children: [
|
itemBuilder: (context, index) {
|
||||||
Padding(
|
final toast = _toasts[index];
|
||||||
padding: EdgeInsets.symmetric(horizontal: context.appSpacing.md),
|
return TimelineToastCard(
|
||||||
child: ToastCard(
|
isFirst: index == 0,
|
||||||
icon: Icons.chat_bubble_outline,
|
isLast: index == _toasts.length - 1,
|
||||||
title: 'Messages',
|
card: ToastCard(
|
||||||
timestamp: '10:42 AM',
|
icon: toast.icon,
|
||||||
content: 'New message received from +1 (555) 019-2834',
|
title: toast.title,
|
||||||
tags: ['res/values/strings.xml', 'en-US'],
|
timestamp: toast.timestamp,
|
||||||
onDelete: () {
|
content: toast.content,
|
||||||
/* ... */
|
tags: [...toast.tags],
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
);
|
||||||
),
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
import 'package:toaster_ui/toaster_ui.dart';
|
||||||
|
|
||||||
|
/// {@template timeline_toast_card}
|
||||||
|
/// Wraps a [ToastCard] with a vertical timeline indicator (dot + line).
|
||||||
|
/// Lines are drawn above and below the dot based on [isFirst] and [isLast].
|
||||||
|
/// {@endtemplate}
|
||||||
|
class TimelineToastCard extends StatelessWidget {
|
||||||
|
/// {@macro timeline_toast_card}
|
||||||
|
const TimelineToastCard({
|
||||||
|
required this.card,
|
||||||
|
super.key,
|
||||||
|
this.isFirst = false,
|
||||||
|
this.isLast = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// The card to display.
|
||||||
|
final ToastCard card;
|
||||||
|
|
||||||
|
/// Whether this is the first item in the timeline (no line above the dot).
|
||||||
|
final bool isFirst;
|
||||||
|
|
||||||
|
/// Whether this is the last item in the timeline (no line below the dot).
|
||||||
|
final bool isLast;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final cs = Theme.of(context).colorScheme;
|
||||||
|
final spacing = context.appSpacing;
|
||||||
|
|
||||||
|
return IntrinsicHeight(
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 24,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
if (!isFirst)
|
||||||
|
Container(width: 2, height: spacing.md, color: cs.outlineVariant)
|
||||||
|
else
|
||||||
|
SizedBox(height: spacing.md),
|
||||||
|
_Dot(color: cs.primary),
|
||||||
|
if (!isLast)
|
||||||
|
Expanded(
|
||||||
|
child: Center(
|
||||||
|
child: Container(width: 2, color: cs.outlineVariant),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: spacing.sm),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: isLast ? 0 : spacing.sm),
|
||||||
|
child: card,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _Dot extends StatelessWidget {
|
||||||
|
const _Dot({required this.color});
|
||||||
|
|
||||||
|
final Color color;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
width: 10,
|
||||||
|
height: 10,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
color: color,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,4 +8,5 @@ export 'src/theme/app_colors.dart';
|
|||||||
export 'src/theme/app_spacing.dart';
|
export 'src/theme/app_spacing.dart';
|
||||||
export 'src/theme/app_theme.dart';
|
export 'src/theme/app_theme.dart';
|
||||||
export 'src/widgets/app_button.dart';
|
export 'src/widgets/app_button.dart';
|
||||||
|
export 'src/widgets/timeline_toast_card.dart';
|
||||||
export 'src/widgets/toast_card.dart';
|
export 'src/widgets/toast_card.dart';
|
||||||
|
|||||||
Reference in New Issue
Block a user