loadDownloadsIfNeeded method

Future<void> loadDownloadsIfNeeded({
  1. bool force = false,
})

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