groupByTimestamp function
Groups notification feed items by their sentAt timestamp into sections.
Groups are sorted newest-first. Items within each group are sorted newest-first. Labels follow the pattern:
- sentAt is today → "Today"
- sentAt is yesterday → "Yesterday"
- sentAt is within this week → Day name (e.g., "Monday")
- sentAt is older → Localized date (e.g., "Jan 15, 2025")
This is a pure function with no side effects.
Implementation
List<TimestampGroup> groupByTimestamp(
List<NotificationFeedItem> items,
String locale,
) {
if (items.isEmpty) return [];
final now = DateTime.now();
final today = DateTime(now.year, now.month, now.day);
final yesterday = today.subtract(const Duration(days: 1));
// Determine the start of the current week (Monday)
final weekStart = today.subtract(Duration(days: today.weekday - 1));
// Group items by calendar day
final Map<String, List<NotificationFeedItem>> groupMap = {};
final Map<String, DateTime> groupDates = {};
for (final item in items) {
final itemDate =
DateTime.fromMillisecondsSinceEpoch(item.sentAt * 1000);
final itemDay = DateTime(itemDate.year, itemDate.month, itemDate.day);
final label = _getLabelForDate(itemDay, today, yesterday, weekStart, locale);
groupMap.putIfAbsent(label, () => []);
groupMap[label]!.add(item);
// Track the actual date for sorting groups
if (!groupDates.containsKey(label) || itemDay.isAfter(groupDates[label]!)) {
groupDates[label] = itemDay;
}
}
// Sort items within each group newest-first
for (final items in groupMap.values) {
items.sort((a, b) => b.sentAt.compareTo(a.sentAt));
}
// Sort groups newest-first by their representative date
final sortedLabels = groupMap.keys.toList()
..sort((a, b) {
final dateA = groupDates[a]!;
final dateB = groupDates[b]!;
return dateB.compareTo(dateA);
});
return sortedLabels
.map((label) => TimestampGroup(
label: label,
items: groupMap[label]!,
))
.toList();
}