groupByTimestamp function

List<TimestampGroup> groupByTimestamp(
  1. List<NotificationFeedItem> items,
  2. String locale
)

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();
}