Files
Client/lib/widget/downloads/stale_download_guard.dart
T

68 lines
2.3 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import '../../routing/app_routes.dart';
import '../../utils/downloads/download_job.dart';
import '../../utils/downloads/download_manager.dart';
import '../../utils/haptics.dart';
import '../confirm_dialog.dart';
import '../info_dialog.dart';
/// Verifies a finished download's cache file is still on disk before opening.
///
/// Downloads live in the app's temp dir, which Android may clear at any time
/// (storage pressure, "Cache leeren") — while completion notifications and
/// tray entries stay tappable indefinitely. Returns true when the file exists;
/// otherwise drops the stale job (incl. its notification) and offers a
/// re-download when the remote path is known (it isn't for notification taps
/// whose task metadata got lost).
bool ensureDownloadStillExists(BuildContext context, DownloadJob job) {
final path = job.localPath;
if (path == null || File(path).existsSync()) return true;
DownloadManager.instance.markOpened(job);
showFileGoneDialog(
context,
subject: 'Die heruntergeladene Datei',
onRedownload: job.remotePath.isEmpty
? null
: () => unawaited(DownloadManager.instance.retry(job)),
);
return false;
}
/// Opens a finished download in the viewer, unless its file vanished.
void openFinishedDownload(BuildContext context, DownloadJob job, String path) {
if (!ensureDownloadStillExists(context, job)) return;
DownloadManager.instance.markOpened(job);
Haptics.success();
AppRoutes.openFileViewer(context, path, remoteFile: job.remoteFile);
}
/// Tells the user that the system cleared a cached file ([subject], e.g.
/// "Die Datei") and offers a re-download when [onRedownload] is given.
void showFileGoneDialog(
BuildContext context, {
required String subject,
VoidCallback? onRedownload,
}) {
const title = 'Datei nicht mehr verfügbar';
final gone = '$subject wurde vom System aus dem Zwischenspeicher entfernt.';
if (onRedownload == null) {
InfoDialog.show(
context,
'$gone Bitte lade sie erneut herunter.',
title: title,
);
return;
}
ConfirmDialog(
title: title,
content: '$gone\nErneut herunterladen?',
confirmButton: 'Herunterladen',
onConfirm: onRedownload,
).asDialog(context);
}