freezer/lib/api/download_manager/download_manager.dart

134 lines
4.0 KiB
Dart

import 'dart:io';
import 'dart:isolate';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_background_service/flutter_background_service.dart';
import 'package:freezer/api/deezer.dart';
import 'package:freezer/api/definitions.dart' as d;
import 'package:freezer/api/download_manager/database.dart';
import 'package:freezer/api/download_manager/download_service.dart';
import 'package:freezer/api/download_manager/service_interface.dart';
import 'package:freezer/api/paths.dart';
import 'package:freezer/main.dart';
import 'package:freezer/settings.dart';
import 'package:freezer/translations.i18n.dart';
import 'package:isar/isar.dart';
import '../download.dart' as dl;
class DownloadManager {
//implements dl.DownloadManager {
late Isar _isar;
SendPort? _sendPort;
Isolate? _isolate;
Future<bool> configure() async {
_isar = await Isar.open(
[
// collections
TrackSchema,
AlbumSchema,
ArtistSchema,
PlaylistSchema,
],
directory: await Paths.dataDirectory(),
name: 'offline',
);
if (Platform.isAndroid || Platform.isIOS) {
return FlutterBackgroundService().configure(
iosConfiguration: IosConfiguration(), // fuck ios
androidConfiguration: AndroidConfiguration(
onStart: _startNative,
isForegroundMode: false,
autoStart: false,
autoStartOnBoot: false,
foregroundServiceNotificationId: DownloadService.NOTIFICATION_ID,
notificationChannelId: DownloadService.NOTIFICATION_CHANNEL_ID,
initialNotificationTitle: 'Freezer'.i18n,
initialNotificationContent: 'Starting download service...'.i18n,
));
}
// will run in foreground instead, in a separate isolate
return Future.value(true);
}
Future<bool> startService() async {
if (Platform.isAndroid) {
return FlutterBackgroundService().startService();
}
final receivePort = ReceivePort();
_sendPort = receivePort.sendPort;
_isolate = await Isolate.spawn(
_startService, ServiceInterface(receivePort: receivePort));
return true;
}
void kill() {
_isolate?.kill();
}
void invoke(String method, [Map<String, dynamic>? args]) {
if (_sendPort != null) {
_sendPort!.send({
'method': method,
if (args != null) ...args,
});
return;
}
FlutterBackgroundService().invoke(method, args);
}
Future<bool> addOfflineTrack(d.Track track,
{bool private = true, BuildContext? context, isSingleton = false}) async {
//Permission
if (!private && !(await dl.DownloadManager.checkCanDownload())) {
return false;
}
//Ask for quality
//AudioQuality? quality;
if (!private && settings.downloadQuality == AudioQuality.ASK) {
// quality = await qualitySelect(context!);
// if (quality == null) return false;
}
if (private) {
if (track.artists == null ||
track.artists!.isEmpty ||
track.album == null) {
track = await deezerAPI.track(track.id);
}
// cache album art
cacheManager.getSingleFile(track.albumArt!.thumb);
cacheManager.getSingleFile(track.albumArt!.full);
await _isar.writeTxn(() async {
await _isar.tracks.put(Track.from(track));
if (track.album != null) {
await _isar.albums.put(Album.from(track.album!));
}
if (track.artists != null) {
await _isar.artists
.putAll(track.artists!.map(Artist.from).toList(growable: false));
}
});
}
// logic for downloading the track
invoke('addDownloads', {'track': track.toJson()});
return true;
}
static void _startNative(ServiceInstance service) =>
_startService(ServiceInterface(service: service));
static void _startService(ServiceInterface service) =>
DownloadService(service).run();
}