loadDownloadsIfNeeded method
SMART API/Storage Refresh
Implementation
/* Future<void> loadDownloadsIfNeeded({bool force = false}) async {
if (isLoading) return;
final now = DateTime.now();
if (!force && lastFetchTime != null && now.difference(lastFetchTime!).inSeconds < 10) {
return;
}
isLoading = true;
try {
await _loadPersistedDownloads();
lastFetchTime = DateTime.now();
} catch (e) {
debugPrint("Error loading downloads: $e");
}
isLoading = false;
}*/
Future<void> loadDownloadsIfNeeded({bool force = false}) async {
if (isLoading) return;
final now = DateTime.now();
// ⏱ cache for 10 sec — avoids hammering the API on every drawer open
if (!force &&
lastFetchTime != null &&
now.difference(lastFetchTime!).inSeconds < 10) {
return;
}
isLoading = true;
try {
final List<DownloadItem> apiData = await repo.getDownloads();
final List<DownloadItem> persistedTasks = kIsWeb ? [] : await service.loadPersistedTasks();
for (final apiItem in apiData) {
if (deletedIds.contains(apiItem.id)) continue;
// Try matching by database ID or background task ID
final existing = downloads.firstWhereOrNull((e) => e.id == apiItem.id || (e.bgTaskId != null && e.bgTaskId == apiItem.bgTaskId));
final persisted = persistedTasks.firstWhereOrNull((t) => t.id == apiItem.id || (t.bgTaskId != null && t.bgTaskId == apiItem.bgTaskId));
if (existing != null) {
// Merge API fields without overwriting active downloading/queued states
existing.fileUrl = apiItem.fileUrl;
existing.isActive = apiItem.isActive;
existing.statusName = apiItem.statusName;
existing.createdOn = apiItem.createdOn;
existing.updatedOn = apiItem.updatedOn;
existing.downloadId = apiItem.downloadId;
final isLocallyDownloading = locallyDownloadingIds.contains(existing.id);
final isLocallyQueued = locallyQueuedIds.contains(existing.id);
if (!isLocallyDownloading && !isLocallyQueued) {
existing.status = apiItem.status;
if (persisted != null) {
existing.progress = persisted.progress;
existing.status = persisted.status;
existing.localPath = persisted.localPath;
if (persisted.bgTaskId != null) {
existing.bgTaskId = persisted.bgTaskId;
}
}
}
} else {
// New item from API
if (persisted != null) {
apiItem.progress = persisted.progress;
apiItem.status = persisted.status;
apiItem.localPath = persisted.localPath;
if (persisted.bgTaskId != null) {
apiItem.bgTaskId = persisted.bgTaskId;
}
}
downloads.add(apiItem);
}
}
// Remove items no longer present in API, unless they are active
final apiIds = apiData.map((e) => e.id).toSet();
downloads.removeWhere((e) => !apiIds.contains(e.id) && e.status != DownloadStatus.downloading && e.status != DownloadStatus.queued);
// Sort downloads list: Newest items (highest DownloadId) first
downloads.sort((a, b) {
final idA = a.downloadId ?? 0;
final idB = b.downloadId ?? 0;
return idB.compareTo(idA); // Descending order
});
// Re-calculate running tasks count
running = downloads.where((e) => e.status == DownloadStatus.downloading).length;
downloadCount.value = downloads.length;
lastFetchTime = DateTime.now();
} catch (e) {
debugPrint('Error loading downloads: $e');
} finally {
isLoading = false;
downloads.refresh();
_managePollingTimer();
}
}