import 'dart:math' as math; import 'package:collection/collection.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/date_time_extension.dart'; import 'package:nc_photos/entity/album.dart'; import 'package:nc_photos/entity/album/cover_provider.dart'; import 'package:nc_photos/entity/album/provider.dart'; import 'package:nc_photos/entity/album/sort_provider.dart'; import 'package:nc_photos/entity/file_descriptor.dart'; class DateGroupHelper { DateGroupHelper({ required this.isMonthOnly, }); DateTime? onFile(FileDescriptor file) { final newDate = file.fdDateTime.toLocal(); if (newDate.year != _currentDate?.year || newDate.month != _currentDate?.month || (!isMonthOnly && newDate.day != _currentDate?.day)) { _currentDate = newDate; return newDate; } else { return null; } } final bool isMonthOnly; DateTime? _currentDate; } /// Build memory album from files /// /// Feb 29 is treated as Mar 1 on non leap years class MemoryAlbumHelper { MemoryAlbumHelper({ DateTime? today, required int dayRange, }) : today = (today?.toLocal() ?? DateTime.now()).toMidnight(), dayRange = math.max(dayRange, 0); void addFile(FileDescriptor f) { final date = f.fdDateTime.toLocal().toMidnight(); final diff = today.difference(date).inDays; if (diff < 300) { return; } for (final dy in [0, -1, 1]) { if (today.copyWith(year: date.year + dy).difference(date).abs().inDays <= dayRange) { _log.fine("[addFile] Add file (${f.fdDateTime}) to ${date.year + dy}"); _addFileToYear(f, date.year + dy); break; } } } /// Build list of memory albums /// /// [nameBuilder] is a function that return the name of the album for a /// particular year List build(String Function(int year) nameBuilder) { return _data.entries .sorted((a, b) => b.key.compareTo(a.key)) .map((e) => Album( name: nameBuilder(e.key), provider: AlbumMemoryProvider( year: e.key, month: today.month, day: today.day), coverProvider: AlbumMemoryCoverProvider(coverFile: e.value.coverFile), sortProvider: const AlbumTimeSortProvider(isAscending: false), )) .toList(); } void _addFileToYear(FileDescriptor f, int year) { final item = _data[year]; final date = today.copyWith(year: year); if (item == null) { _data[year] = _MemoryAlbumHelperItem(date, f); } else { final coverDiff = _MemoryAlbumHelperItem.getCoverDiff(date, f); if (coverDiff < item.coverDiff) { item.coverFile = f; item.coverDiff = coverDiff; } } } final DateTime today; final int dayRange; final _data = {}; static final _log = Logger("widget.photo_list_util.MemoryAlbumHelper"); } int getThumbSize(int zoomLevel) { switch (zoomLevel) { case -1: return 96; case 1: return 176; case 2: return 256; case 0: default: return 112; } } class _MemoryAlbumHelperItem { _MemoryAlbumHelperItem(this.date, this.coverFile) : coverDiff = getCoverDiff(date, coverFile); static Duration getCoverDiff(DateTime date, FileDescriptor f) => f.fdDateTime.difference(date.copyWith(hour: 12)).abs(); final DateTime date; FileDescriptor coverFile; Duration coverDiff; }