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 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 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? args]) { if (_sendPort != null) { _sendPort!.send({ 'method': method, if (args != null) ...args, }); return; } FlutterBackgroundService().invoke(method, args); } @override Future addOfflineTrack(d.Track track, {bool private = true, BuildContext? context, isSingleton = false}) async { //Permission //if (!private && !(await checkPermission())) 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(); }