redesign app phase 3
This commit is contained in:
@@ -11,6 +11,7 @@ import 'package:path/path.dart' as path_helper;
|
||||
|
||||
import 'finamp_settings_helper.dart';
|
||||
import 'finamp_user_helper.dart';
|
||||
import 'download_support.dart';
|
||||
import 'jellyfin_api.dart';
|
||||
import 'jellyfin_api_helper.dart';
|
||||
import 'get_internal_song_dir.dart';
|
||||
@@ -61,6 +62,10 @@ class DownloadsHelper {
|
||||
/// The view that this download is in. Used for sorting in offline mode.
|
||||
required String viewId,
|
||||
}) async {
|
||||
if (!isDownloaderSupported) {
|
||||
return Future.error("Downloads are only supported on Android and iOS");
|
||||
}
|
||||
|
||||
// Check if we have external storage permission. It's a bit of a hack, but
|
||||
// we only do this if downloadLocation.deletable is true because if it's
|
||||
// true, we're downloading to a user location. You wouldn't want the app
|
||||
@@ -228,6 +233,10 @@ class DownloadsHelper {
|
||||
/// Gets the download status for the given item ids (Jellyfin item id, not flutter_downloader task id).
|
||||
Future<List<DownloadTask>?> getDownloadStatus(List<String> itemIds) async {
|
||||
try {
|
||||
if (!isDownloaderSupported) {
|
||||
return [];
|
||||
}
|
||||
|
||||
List<String> downloadIds = [];
|
||||
|
||||
for (final itemId in itemIds) {
|
||||
@@ -248,7 +257,8 @@ class DownloadsHelper {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> removeChildFromParent({required String parentId, required List<String> childIds}) async {
|
||||
Future<void> removeChildFromParent(
|
||||
{required String parentId, required List<String> childIds}) async {
|
||||
var album = _downloadedParentsBox.get(parentId);
|
||||
for (String childId in childIds) {
|
||||
album?.downloadedChildren.removeWhere((key, value) => key == childId);
|
||||
@@ -266,17 +276,18 @@ class DownloadsHelper {
|
||||
_downloadsLogger.info(
|
||||
"Could not find $jellyfinItemId in downloadedItemsBox, assuming already deleted");
|
||||
} else {
|
||||
DownloadedImage? downloadedImage = getDownloadedImage(downloadedSong.song);
|
||||
DownloadedImage? downloadedImage =
|
||||
getDownloadedImage(downloadedSong.song);
|
||||
downloadedImage?.requiredBy.remove(jellyfinItemId);
|
||||
if (downloadedSong.requiredBy.isEmpty) {
|
||||
_downloadsLogger.info(
|
||||
"Item $jellyfinItemId has no dependencies, deleting files");
|
||||
_downloadsLogger
|
||||
.info("Item $jellyfinItemId has no dependencies, deleting files");
|
||||
|
||||
_downloadsLogger.info(
|
||||
"Deleting ${downloadedSong.downloadId} from flutter_downloader");
|
||||
deleteDownloadFutures.add(FlutterDownloader.remove(
|
||||
deleteDownloadFutures.add(_removeDownload(
|
||||
taskId: downloadedSong.downloadId,
|
||||
shouldDeleteContent: true,
|
||||
file: downloadedSong.file,
|
||||
));
|
||||
|
||||
await _downloadedItemsBox.delete(jellyfinItemId);
|
||||
@@ -308,7 +319,8 @@ class DownloadsHelper {
|
||||
|
||||
/// This function will delete all given jellyfinItemIds regardless if they are still used
|
||||
/// by other albums/playlists
|
||||
Future<void> deleteDownloadChildren({required List<String> jellyfinItemIds, String? deletedFor}) async {
|
||||
Future<void> deleteDownloadChildren(
|
||||
{required List<String> jellyfinItemIds, String? deletedFor}) async {
|
||||
final List<Future> deleteDownloadFutures = [];
|
||||
final Map<String, Directory> directoriesToCheck = {};
|
||||
|
||||
@@ -321,11 +333,11 @@ class DownloadsHelper {
|
||||
"Could not find $jellyfinItemId in downloadedItemsBox, assuming already deleted");
|
||||
} else {
|
||||
DownloadedImage? downloadedImage =
|
||||
getDownloadedImage(downloadedSong.song);
|
||||
getDownloadedImage(downloadedSong.song);
|
||||
|
||||
if (deletedFor != null) {
|
||||
_downloadsLogger
|
||||
.info("Removing $deletedFor dependency from $jellyfinItemId, current dependencies ${downloadedSong.requiredBy}");
|
||||
_downloadsLogger.info(
|
||||
"Removing $deletedFor dependency from $jellyfinItemId, current dependencies ${downloadedSong.requiredBy}");
|
||||
downloadedSong.requiredBy.removeWhere((item) => item == deletedFor);
|
||||
}
|
||||
|
||||
@@ -337,9 +349,9 @@ class DownloadsHelper {
|
||||
|
||||
_downloadsLogger.info(
|
||||
"Deleting ${downloadedSong.downloadId} from flutter_downloader");
|
||||
deleteDownloadFutures.add(FlutterDownloader.remove(
|
||||
deleteDownloadFutures.add(_removeDownload(
|
||||
taskId: downloadedSong.downloadId,
|
||||
shouldDeleteContent: true,
|
||||
file: downloadedSong.file,
|
||||
));
|
||||
|
||||
await _downloadedItemsBox.delete(jellyfinItemId);
|
||||
@@ -347,7 +359,7 @@ class DownloadsHelper {
|
||||
|
||||
if (deletedFor != null) {
|
||||
DownloadedParent? downloadedAlbumTemp =
|
||||
_downloadedParentsBox.get(deletedFor);
|
||||
_downloadedParentsBox.get(deletedFor);
|
||||
if (downloadedAlbumTemp != null) {
|
||||
downloadedAlbumTemp.downloadedChildren.remove(jellyfinItemId);
|
||||
await _downloadedParentsBox.put(deletedFor, downloadedAlbumTemp);
|
||||
@@ -417,7 +429,8 @@ class DownloadsHelper {
|
||||
String? deletedFor,
|
||||
}) async {
|
||||
try {
|
||||
await deleteDownloadChildren(jellyfinItemIds: jellyfinItemIds, deletedFor: deletedFor);
|
||||
await deleteDownloadChildren(
|
||||
jellyfinItemIds: jellyfinItemIds, deletedFor: deletedFor);
|
||||
if (deletedFor != null) {
|
||||
await deleteDownloadParent(deletedFor: deletedFor);
|
||||
}
|
||||
@@ -445,12 +458,27 @@ class DownloadsHelper {
|
||||
_downloadedImagesBox.delete(downloadedImage.id);
|
||||
_downloadedImageIdsBox.delete(downloadedImage.downloadId);
|
||||
|
||||
await FlutterDownloader.remove(
|
||||
await _removeDownload(
|
||||
taskId: downloadedImage.downloadId,
|
||||
shouldDeleteContent: true,
|
||||
file: downloadedImage.file,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _removeDownload(
|
||||
{required String taskId, required File file}) async {
|
||||
if (isDownloaderSupported) {
|
||||
await FlutterDownloader.remove(
|
||||
taskId: taskId,
|
||||
shouldDeleteContent: true,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (await file.exists()) {
|
||||
await file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates the total file size of the given directory.
|
||||
/// Returns the total file size in bytes.
|
||||
/// Returns 0 if the directory doesn't exist.
|
||||
@@ -480,6 +508,10 @@ class DownloadsHelper {
|
||||
|
||||
Future<List<DownloadTask>?> getIncompleteDownloads() async {
|
||||
try {
|
||||
if (!isDownloaderSupported) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return await FlutterDownloader.loadTasksWithRawQuery(
|
||||
query: "SELECT * FROM task WHERE status <> 3");
|
||||
} catch (e) {
|
||||
@@ -491,9 +523,13 @@ class DownloadsHelper {
|
||||
Future<List<DownloadTask>?> getDownloadsWithStatus(
|
||||
DownloadTaskStatus downloadTaskStatus) async {
|
||||
try {
|
||||
if (!isDownloaderSupported) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return await FlutterDownloader.loadTasksWithRawQuery(
|
||||
query:
|
||||
"SELECT * FROM task WHERE status = ${downloadTaskStatus.value}");
|
||||
"SELECT * FROM task WHERE status = ${downloadTaskStatus.index}");
|
||||
} catch (e) {
|
||||
_downloadsLogger.severe(e);
|
||||
return Future.error(e);
|
||||
@@ -851,6 +887,10 @@ class DownloadsHelper {
|
||||
/// creating new ones with the same settings. Returns number of songs
|
||||
/// redownloaded
|
||||
Future<int> redownloadFailed() async {
|
||||
if (!isDownloaderSupported) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
final failedDownloadTasks =
|
||||
await getDownloadsWithStatus(DownloadTaskStatus.failed);
|
||||
|
||||
@@ -883,8 +923,8 @@ class DownloadsHelper {
|
||||
for (String parent in parents) {
|
||||
// We don't specify deletedFor here because it could cause the parent
|
||||
// to get deleted
|
||||
deleteFutures
|
||||
.add(deleteParentAndChildDownloads(jellyfinItemIds: [downloadedSong.song.id]));
|
||||
deleteFutures.add(deleteParentAndChildDownloads(
|
||||
jellyfinItemIds: [downloadedSong.song.id]));
|
||||
|
||||
if (parentItems[downloadedSong.song.id] == null) {
|
||||
parentItems[downloadedSong.song.id] = [];
|
||||
@@ -1055,7 +1095,6 @@ class DownloadsHelper {
|
||||
{List<String>? keys}) =>
|
||||
_downloadedItemsBox.listenable(keys: keys);
|
||||
|
||||
|
||||
/// Converts a dart list to a string with the correct SQL syntax
|
||||
String _dartListToSqlList(List dartList) {
|
||||
try {
|
||||
@@ -1106,6 +1145,10 @@ class DownloadsHelper {
|
||||
}) async {
|
||||
assert(item.blurHash != null);
|
||||
|
||||
if (!isDownloaderSupported) {
|
||||
return Future.error("Downloads are only supported on Android and iOS");
|
||||
}
|
||||
|
||||
if (_downloadedImagesBox.containsKey(item.blurHash)) return;
|
||||
|
||||
final imageUrl = _jellyfinApiData.getImageUrl(
|
||||
|
||||
Reference in New Issue
Block a user