mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-01-22 16:56:19 +01:00
Run startup sync in background isolate
This commit is contained in:
parent
49b5901149
commit
3387378181
6 changed files with 127 additions and 16 deletions
|
@ -39,7 +39,10 @@ import 'package:visibility_detector/visibility_detector.dart';
|
|||
|
||||
enum InitIsolateType {
|
||||
main,
|
||||
service,
|
||||
|
||||
/// Isolates with Flutter engine, e.g., those spawned by flutter_isolate or
|
||||
/// flutter_background_service
|
||||
flutterIsolate,
|
||||
}
|
||||
|
||||
Future<void> init(InitIsolateType isolateType) async {
|
||||
|
@ -200,7 +203,7 @@ Future<sql.SqliteDb> _createDb(InitIsolateType isolateType) async {
|
|||
return sql_isolate.createDb();
|
||||
}
|
||||
|
||||
case InitIsolateType.service:
|
||||
case InitIsolateType.flutterIsolate:
|
||||
// service already runs in an isolate
|
||||
return sql.SqliteDb();
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ class _Service {
|
|||
final service = FlutterBackgroundService();
|
||||
service.setForegroundMode(true);
|
||||
|
||||
await app_init.init(app_init.InitIsolateType.service);
|
||||
await app_init.init(app_init.InitIsolateType.flutterIsolate);
|
||||
await _L10n().init();
|
||||
|
||||
_log.info("[call] Service started");
|
||||
|
|
104
app/lib/use_case/startup_sync.dart
Normal file
104
app/lib/use_case/startup_sync.dart
Normal file
|
@ -0,0 +1,104 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:event_bus/event_bus.dart';
|
||||
import 'package:flutter_isolate/flutter_isolate.dart';
|
||||
import 'package:kiwi/kiwi.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/app_init.dart' as app_init;
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/event/event.dart';
|
||||
import 'package:nc_photos/platform/k.dart' as platform_k;
|
||||
import 'package:nc_photos/type.dart';
|
||||
import 'package:nc_photos/use_case/sync_favorite.dart';
|
||||
|
||||
/// Sync various properties with server during startup
|
||||
class StartupSync {
|
||||
StartupSync(this._c)
|
||||
: assert(require(_c)),
|
||||
assert(SyncFavorite.require(_c));
|
||||
|
||||
static bool require(DiContainer c) => true;
|
||||
|
||||
/// Sync in a background isolate
|
||||
static Future<SyncResult> runInIsolate(Account account) async {
|
||||
if (platform_k.isWeb) {
|
||||
// not supported on web
|
||||
final c = KiwiContainer().resolve<DiContainer>();
|
||||
return await StartupSync(c)(account);
|
||||
} else {
|
||||
// we can't use regular isolate here because self-signed cert support
|
||||
// requires native plugins
|
||||
final resultJson =
|
||||
await flutterCompute(_isolateMain, _IsolateMessage(account).toJson());
|
||||
final result = SyncResult.fromJson(resultJson);
|
||||
// events fired in background isolate won't be noticed by the main isolate,
|
||||
// so we fire them again here
|
||||
_broadcastResult(account, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Future<SyncResult> call(Account account) async {
|
||||
_log.info("[_run] Begin sync");
|
||||
late final int syncFavoriteCount;
|
||||
try {
|
||||
syncFavoriteCount = await SyncFavorite(_c)(account);
|
||||
} catch (e, stackTrace) {
|
||||
_log.shout("[_run] Failed while SyncFavorite", e, stackTrace);
|
||||
syncFavoriteCount = -1;
|
||||
}
|
||||
return SyncResult(syncFavoriteCount);
|
||||
}
|
||||
|
||||
static void _broadcastResult(Account account, SyncResult result) {
|
||||
final eventBus = KiwiContainer().resolve<EventBus>();
|
||||
if (result.syncFavoriteCount > 0) {
|
||||
eventBus.fire(FavoriteResyncedEvent(account));
|
||||
}
|
||||
}
|
||||
|
||||
final DiContainer _c;
|
||||
|
||||
static final _log = Logger("use_case.startup_sync.StartupSync");
|
||||
}
|
||||
|
||||
class SyncResult {
|
||||
const SyncResult(this.syncFavoriteCount);
|
||||
|
||||
factory SyncResult.fromJson(JsonObj json) => SyncResult(
|
||||
json["syncFavoriteCount"],
|
||||
);
|
||||
|
||||
JsonObj toJson() => {
|
||||
"syncFavoriteCount": syncFavoriteCount,
|
||||
};
|
||||
|
||||
final int syncFavoriteCount;
|
||||
}
|
||||
|
||||
class _IsolateMessage {
|
||||
const _IsolateMessage(this.account);
|
||||
|
||||
factory _IsolateMessage.fromJson(JsonObj json) => _IsolateMessage(
|
||||
Account.fromJson(
|
||||
json["account"].cast<String, dynamic>(),
|
||||
upgraderV1: const AccountUpgraderV1(),
|
||||
)!,
|
||||
);
|
||||
|
||||
JsonObj toJson() => {
|
||||
"account": account.toJson(),
|
||||
};
|
||||
|
||||
final Account account;
|
||||
}
|
||||
|
||||
Future<JsonObj> _isolateMain(JsonObj messageJson) async {
|
||||
final message = _IsolateMessage.fromJson(messageJson);
|
||||
await app_init.init(app_init.InitIsolateType.flutterIsolate);
|
||||
|
||||
final c = KiwiContainer().resolve<DiContainer>();
|
||||
final result = await StartupSync(c)(message.account);
|
||||
return result.toJson();
|
||||
}
|
|
@ -21,7 +21,6 @@ import 'package:nc_photos/entity/album.dart';
|
|||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
||||
import 'package:nc_photos/event/event.dart';
|
||||
import 'package:nc_photos/exception.dart';
|
||||
import 'package:nc_photos/exception_util.dart' as exception_util;
|
||||
import 'package:nc_photos/k.dart' as k;
|
||||
import 'package:nc_photos/language_util.dart' as language_util;
|
||||
|
@ -35,7 +34,7 @@ import 'package:nc_photos/share_handler.dart';
|
|||
import 'package:nc_photos/snack_bar_manager.dart';
|
||||
import 'package:nc_photos/theme.dart';
|
||||
import 'package:nc_photos/throttler.dart';
|
||||
import 'package:nc_photos/use_case/sync_favorite.dart';
|
||||
import 'package:nc_photos/use_case/startup_sync.dart';
|
||||
import 'package:nc_photos/widget/album_browser_util.dart' as album_browser_util;
|
||||
import 'package:nc_photos/widget/builder/photo_list_item_builder.dart';
|
||||
import 'package:nc_photos/widget/handler/add_selection_to_album_handler.dart';
|
||||
|
@ -381,7 +380,7 @@ class _HomePhotosState extends State<HomePhotos>
|
|||
state is ScanAccountDirBlocLoading) {
|
||||
_transformItems(state.files);
|
||||
if (state is ScanAccountDirBlocSuccess) {
|
||||
_syncFavorite();
|
||||
_startupSync();
|
||||
_tryStartMetadataTask();
|
||||
}
|
||||
} else if (state is ScanAccountDirBlocFailure) {
|
||||
|
@ -536,18 +535,10 @@ class _HomePhotosState extends State<HomePhotos>
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> _syncFavorite() async {
|
||||
Future<void> _startupSync() async {
|
||||
if (!_hasResyncedFavorites.value) {
|
||||
final c = KiwiContainer().resolve<DiContainer>();
|
||||
try {
|
||||
await SyncFavorite(c)(widget.account);
|
||||
} catch (e, stackTrace) {
|
||||
if (e is! ApiException) {
|
||||
_log.shout(
|
||||
"[_syncFavorite] Failed while SyncFavorite", e, stackTrace);
|
||||
}
|
||||
}
|
||||
_hasResyncedFavorites.value = true;
|
||||
StartupSync.runInIsolate(widget.account);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -490,6 +490,15 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.3.0"
|
||||
flutter_isolate:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: "2.0.2-nc-photos-1"
|
||||
resolved-ref: "8d8516b169860caba762baed43a7888798c5b7d7"
|
||||
url: "https://gitlab.com/nc-photos/flutter_isolate.git"
|
||||
source: git
|
||||
version: "2.0.2"
|
||||
flutter_keyboard_visibility:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -57,6 +57,10 @@ dependencies:
|
|||
url: https://gitlab.com/nc-photos/flutter_background_service.git
|
||||
ref: v0.2.6-nc-photos-2
|
||||
flutter_bloc: ^8.0.0
|
||||
flutter_isolate:
|
||||
git:
|
||||
url: https://gitlab.com/nc-photos/flutter_isolate.git
|
||||
ref: 2.0.2-nc-photos-1
|
||||
flutter_map: ^1.1.1
|
||||
flutter_staggered_grid_view:
|
||||
git:
|
||||
|
|
Loading…
Reference in a new issue