nc-photos/app/lib/controller/metadata_controller.dart
2024-02-07 01:14:30 +08:00

97 lines
2.7 KiB
Dart

import 'dart:async';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/controller/files_controller.dart';
import 'package:nc_photos/controller/pref_controller.dart';
import 'package:nc_photos/db/entity_converter.dart';
import 'package:nc_photos/di_container.dart';
import 'package:nc_photos/entity/file_descriptor.dart';
import 'package:nc_photos/entity/file_util.dart' as file_util;
import 'package:nc_photos/service.dart' as service;
import 'package:np_codegen/np_codegen.dart';
part 'metadata_controller.g.dart';
@npLog
class MetadataController {
MetadataController(
this._c, {
required this.account,
required this.filesController,
required this.prefController,
}) {
_subscriptions.add(filesController.stream.listen(_onFilesEvent));
_subscriptions.add(prefController.isEnableExif.listen(_onSetEnableExif));
}
void dispose() {
for (final s in _subscriptions) {
s.cancel();
}
}
/// Normally EXIF task only run once, call this function to make it run again
/// after receiving new files
void scheduleNext() {
_hasStarted = false;
}
Future<void> _onFilesEvent(FilesStreamEvent ev) async {
_log.info("[_onFilesEvent]");
if (!prefController.isEnableExif.value) {
// disabled
return;
}
if (ev.data.isNotEmpty && !ev.hasNext) {
// finished querying
if (!_hasStarted) {
await _startMetadataTask(ev.data);
}
}
}
void _onSetEnableExif(bool value) {
_log.info("[_onSetEnableExif]");
if (value) {
final filesState = filesController.stream.value;
if (filesState.hasNext || filesState.data.isEmpty) {
_log.info("[_onSetEnableExif] Ignored as data not ready");
return;
}
_startMetadataTask(filesState.data);
} else {
_stopMetadataTask();
}
}
Future<void> _startMetadataTask(List<FileDescriptor> data) async {
_hasStarted = true;
try {
final missingCount = await _c.npDb.countFilesByFileIdsMissingMetadata(
account: account.toDb(),
fileIds: data.map((e) => e.fdId).toList(),
mimes: file_util.supportedImageFormatMimes,
);
_log.info("[_startMetadataTask] Missing count: $missingCount");
if (missingCount > 0) {
unawaited(service.startService());
}
} catch (e, stackTrace) {
_log.shout(
"[_startMetadataTask] Failed starting metadata task", e, stackTrace);
}
}
void _stopMetadataTask() {
service.stopService();
}
final DiContainer _c;
final Account account;
final FilesController filesController;
final PrefController prefController;
final _subscriptions = <StreamSubscription>[];
var _hasStarted = false;
}