Aves_mio0.88/lib/model/activity/activity_folder_stats.dart
2026-10-03 12:51:15 +02:00

93 lines
2.7 KiB
Dart

// lib/model/activity/activity_folder_stats.dart
import 'package:aves/model/activity/activity_entry.dart';
import 'package:aves/model/db/folder_content_type.dart';
import 'package:aves/model/db/folder_stats.dart';
class ActivityFolderStats {
const ActivityFolderStats._();
static List<FolderStats> build(Iterable<ActivityEntry> activities) {
final folders = <String, FolderStats>{};
for (final entry in activities) {
final folderPath = _folderPathForEntry(entry);
if (folderPath == null || folderPath.isEmpty) continue;
final stats = folders.putIfAbsent(folderPath, () {
return FolderStats(
path: folderPath,
displayName: _displayNameForPath(folderPath),
contentType: FolderContentType.activity,
fileCount: 0,
totalSize: 0,
thumbEntryId: null,
thumbDate: null,
albumType: 0,
priority: 0,
isRemote: entry.origin,
user: null,
deviceId: null,
hidden: 0,
hybridFolder: null,
);
});
stats.fileCount++;
stats.totalSize += entry.sizeBytes ?? 0;
final date = entry.startTimeMillis ?? entry.dateModifiedMillis;
if (stats.thumbDate == null || date > stats.thumbDate!) {
stats.thumbDate = date;
stats.thumbEntryId = entry.id;
}
// If one activity folder ever contains both local and remote activities,
// for now the most recently processed activity defines the folder origin.
stats.isRemote = entry.origin;
}
return folders.values.toList()..sort(
(a, b) => a.displayName.toLowerCase().compareTo(
b.displayName.toLowerCase(),
),
);
}
static String? _folderPathForEntry(ActivityEntry entry) {
final relativePath = entry.relativePath?.trim();
if (relativePath != null && relativePath.isNotEmpty) {
return _normalizePath(relativePath);
}
final directoryName = entry.directoryName?.trim();
if (directoryName != null && directoryName.isNotEmpty) {
return _normalizePath(directoryName);
}
return 'Activity';
}
static String _normalizePath(String path) {
var normalized = path.replaceAll('\\', '/').trim();
while (normalized.contains('//')) {
normalized = normalized.replaceAll('//', '/');
}
if (normalized.endsWith('/')) {
normalized = normalized.substring(0, normalized.length - 1);
}
return normalized.isEmpty ? 'Activity' : normalized;
}
static String _displayNameForPath(String path) {
final normalized = _normalizePath(path);
final parts = normalized.split('/').where((part) => part.isNotEmpty);
if (parts.isEmpty) return 'Activity';
return parts.last;
}
}