import 'dart:developer' as developer; import 'dart:isolate'; import 'package:flutter/material.dart'; import 'package:flutter_isolate/flutter_isolate.dart'; import '../local_storage/key_value_storage.dart'; import '../local_storage/sqflite_localpodcast.dart'; enum RefreshState { none, fetch, error, artwork } class RefreshItem { String title; RefreshState refreshState; bool artwork; RefreshItem(this.title, this.refreshState, {this.artwork = false}); } class RefreshWorker extends ChangeNotifier { FlutterIsolate refreshIsolate; ReceivePort receivePort; SendPort refreshSendPort; RefreshItem _currentRefreshItem = RefreshItem('', RefreshState.none); bool _complete = false; RefreshItem get currentRefreshItem => _currentRefreshItem; bool get complete => _complete; bool _created = false; bool get created => _created; Future _createIsolate() async { receivePort = ReceivePort(); refreshIsolate = await FlutterIsolate.spawn( refreshIsolateEntryPoint, receivePort.sendPort); } void _listen(List podcasts) { receivePort.distinct().listen((message) { if (message is SendPort) { refreshSendPort = message; refreshSendPort.send(podcasts); } if (message is List) { _currentRefreshItem = RefreshItem(message[0], RefreshState.values[message[1]]); notifyListeners(); } else if (message is String && message == "done") { _currentRefreshItem = RefreshItem('', RefreshState.none); refreshIsolate?.kill(); refreshIsolate = null; _created = false; _complete = true; notifyListeners(); _complete = false; } }); } Future start(List podcasts) async { if (!_created) { if (podcasts.isEmpty) { final refreshstorage = KeyValueStorage(refreshdateKey); await refreshstorage.saveInt(DateTime.now().millisecondsSinceEpoch); } _complete = false; await _createIsolate(); _listen(podcasts); _created = true; } } void dispose() { refreshIsolate?.kill(); refreshIsolate = null; super.dispose(); } } Future refreshIsolateEntryPoint(SendPort sendPort) async { var refreshReceivePort = ReceivePort(); sendPort.send(refreshReceivePort.sendPort); var _dbHelper = DBHelper(); Future _refreshAll(List podcasts) async { var podcastList; if (podcasts.isEmpty) { podcastList = await _dbHelper.getPodcastLocalAll(updateOnly: true); } else { podcastList = await _dbHelper.getPodcastLocal(podcasts, updateOnly: true); } for (var podcastLocal in podcastList) { sendPort.send([podcastLocal.title, 1]); var updateCount = await _dbHelper.updatePodcastRss(podcastLocal); developer.log('Refresh ${podcastLocal.title}$updateCount'); } sendPort.send("done"); } refreshReceivePort.distinct().listen((message) { if (message is List) { _refreshAll(message); } }); }