source init scope review
This commit is contained in:
parent
687ca5eb41
commit
33ffb1cd1a
10 changed files with 83 additions and 73 deletions
|
@ -32,7 +32,7 @@ import 'package:event_bus/event_bus.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:leak_tracker/leak_tracker.dart';
|
import 'package:leak_tracker/leak_tracker.dart';
|
||||||
|
|
||||||
enum SourceScope { none, album, full }
|
typedef SourceScope = Set<CollectionFilter>?;
|
||||||
|
|
||||||
mixin SourceBase {
|
mixin SourceBase {
|
||||||
EventBus get eventBus;
|
EventBus get eventBus;
|
||||||
|
@ -63,6 +63,8 @@ mixin SourceBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class CollectionSource with SourceBase, AlbumMixin, CountryMixin, PlaceMixin, StateMixin, LocationMixin, TagMixin, TrashMixin {
|
abstract class CollectionSource with SourceBase, AlbumMixin, CountryMixin, PlaceMixin, StateMixin, LocationMixin, TagMixin, TrashMixin {
|
||||||
|
static const fullScope = <CollectionFilter>{};
|
||||||
|
|
||||||
CollectionSource() {
|
CollectionSource() {
|
||||||
if (kFlutterMemoryAllocationsEnabled) {
|
if (kFlutterMemoryAllocationsEnabled) {
|
||||||
LeakTracking.dispatchObjectCreated(
|
LeakTracking.dispatchObjectCreated(
|
||||||
|
@ -428,11 +430,13 @@ abstract class CollectionSource with SourceBase, AlbumMixin, CountryMixin, Place
|
||||||
eventBus.fire(EntryMovedEvent(MoveType.move, movedEntries));
|
eventBus.fire(EntryMovedEvent(MoveType.move, movedEntries));
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceScope get scope => SourceScope.none;
|
SourceScope get loadedScope;
|
||||||
|
|
||||||
|
SourceScope get targetScope;
|
||||||
|
|
||||||
Future<void> init({
|
Future<void> init({
|
||||||
|
required SourceScope scope,
|
||||||
AnalysisController? analysisController,
|
AnalysisController? analysisController,
|
||||||
AlbumFilter? albumFilter,
|
|
||||||
bool loadTopEntriesFirst = false,
|
bool loadTopEntriesFirst = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -21,38 +21,40 @@ class MediaStoreSource extends CollectionSource {
|
||||||
final Debouncer _changeDebouncer = Debouncer(delay: ADurations.mediaContentChangeDebounceDelay);
|
final Debouncer _changeDebouncer = Debouncer(delay: ADurations.mediaContentChangeDebounceDelay);
|
||||||
final Set<String> _changedUris = {};
|
final Set<String> _changedUris = {};
|
||||||
int? _lastGeneration;
|
int? _lastGeneration;
|
||||||
SourceScope _scope = SourceScope.none;
|
SourceScope _loadedScope, _targetScope;
|
||||||
bool _canAnalyze = true;
|
bool _canAnalyze = true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set canAnalyze(bool enabled) => _canAnalyze = enabled;
|
set canAnalyze(bool enabled) => _canAnalyze = enabled;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
SourceScope get scope => _scope;
|
SourceScope get loadedScope => _loadedScope;
|
||||||
|
|
||||||
|
@override
|
||||||
|
SourceScope get targetScope => _targetScope;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> init({
|
Future<void> init({
|
||||||
|
required SourceScope scope,
|
||||||
AnalysisController? analysisController,
|
AnalysisController? analysisController,
|
||||||
AlbumFilter? albumFilter,
|
|
||||||
bool loadTopEntriesFirst = false,
|
bool loadTopEntriesFirst = false,
|
||||||
}) async {
|
}) async {
|
||||||
await reportService.log('$runtimeType init album=${albumFilter?.album}');
|
_targetScope = scope;
|
||||||
if (_scope == SourceScope.none) {
|
await reportService.log('$runtimeType init target scope=$scope');
|
||||||
await _loadEssentials();
|
await _loadEssentials();
|
||||||
}
|
|
||||||
if (_scope != SourceScope.full) {
|
|
||||||
_scope = albumFilter != null ? SourceScope.album : SourceScope.full;
|
|
||||||
}
|
|
||||||
addDirectories(albums: settings.pinnedFilters.whereType<AlbumFilter>().map((v) => v.album).toSet());
|
addDirectories(albums: settings.pinnedFilters.whereType<AlbumFilter>().map((v) => v.album).toSet());
|
||||||
await updateGeneration();
|
await updateGeneration();
|
||||||
unawaited(_loadEntries(
|
unawaited(_loadEntries(
|
||||||
analysisController: analysisController,
|
analysisController: analysisController,
|
||||||
directory: albumFilter?.album,
|
|
||||||
loadTopEntriesFirst: loadTopEntriesFirst,
|
loadTopEntriesFirst: loadTopEntriesFirst,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _areEssentialsLoaded = false;
|
||||||
|
|
||||||
Future<void> _loadEssentials() async {
|
Future<void> _loadEssentials() async {
|
||||||
|
if (_areEssentialsLoaded) return;
|
||||||
|
|
||||||
final stopwatch = Stopwatch()..start();
|
final stopwatch = Stopwatch()..start();
|
||||||
state = SourceState.loading;
|
state = SourceState.loading;
|
||||||
await localMediaDb.init();
|
await localMediaDb.init();
|
||||||
|
@ -63,20 +65,19 @@ class MediaStoreSource extends CollectionSource {
|
||||||
if (currentTimeZoneOffset != null) {
|
if (currentTimeZoneOffset != null) {
|
||||||
final catalogTimeZoneOffset = settings.catalogTimeZoneRawOffsetMillis;
|
final catalogTimeZoneOffset = settings.catalogTimeZoneRawOffsetMillis;
|
||||||
if (currentTimeZoneOffset != catalogTimeZoneOffset) {
|
if (currentTimeZoneOffset != catalogTimeZoneOffset) {
|
||||||
// clear catalog metadata to get correct date/times when moving to a different time zone
|
unawaited(reportService.log('Time zone offset change: $currentTimeZoneOffset -> $catalogTimeZoneOffset. Clear catalog metadata to get correct date/times.'));
|
||||||
debugPrint('$runtimeType clear catalog metadata to get correct date/times');
|
|
||||||
await localMediaDb.clearDates();
|
await localMediaDb.clearDates();
|
||||||
await localMediaDb.clearCatalogMetadata();
|
await localMediaDb.clearCatalogMetadata();
|
||||||
settings.catalogTimeZoneRawOffsetMillis = currentTimeZoneOffset;
|
settings.catalogTimeZoneRawOffsetMillis = currentTimeZoneOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await loadDates();
|
await loadDates();
|
||||||
|
_areEssentialsLoaded = true;
|
||||||
debugPrint('$runtimeType load essentials complete in ${stopwatch.elapsed.inMilliseconds}ms');
|
debugPrint('$runtimeType load essentials complete in ${stopwatch.elapsed.inMilliseconds}ms');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadEntries({
|
Future<void> _loadEntries({
|
||||||
AnalysisController? analysisController,
|
AnalysisController? analysisController,
|
||||||
String? directory,
|
|
||||||
required bool loadTopEntriesFirst,
|
required bool loadTopEntriesFirst,
|
||||||
}) async {
|
}) async {
|
||||||
unawaited(reportService.log('$runtimeType load (known) start'));
|
unawaited(reportService.log('$runtimeType load (known) start'));
|
||||||
|
@ -84,6 +85,9 @@ class MediaStoreSource extends CollectionSource {
|
||||||
state = SourceState.loading;
|
state = SourceState.loading;
|
||||||
clearEntries();
|
clearEntries();
|
||||||
|
|
||||||
|
final scopeAlbumFilters = _targetScope?.whereType<AlbumFilter>();
|
||||||
|
final scopeDirectory = scopeAlbumFilters != null && scopeAlbumFilters.length == 1 ? scopeAlbumFilters.first.album : null;
|
||||||
|
|
||||||
final Set<AvesEntry> topEntries = {};
|
final Set<AvesEntry> topEntries = {};
|
||||||
if (loadTopEntriesFirst) {
|
if (loadTopEntriesFirst) {
|
||||||
final topIds = settings.topEntryIds?.toSet();
|
final topIds = settings.topEntryIds?.toSet();
|
||||||
|
@ -95,7 +99,7 @@ class MediaStoreSource extends CollectionSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
debugPrint('$runtimeType load ${stopwatch.elapsed} fetch known entries');
|
debugPrint('$runtimeType load ${stopwatch.elapsed} fetch known entries');
|
||||||
final knownEntries = await localMediaDb.loadEntries(origin: EntryOrigins.mediaStoreContent, directory: directory);
|
final knownEntries = await localMediaDb.loadEntries(origin: EntryOrigins.mediaStoreContent, directory: scopeDirectory);
|
||||||
final knownLiveEntries = knownEntries.where((entry) => !entry.trashed).toSet();
|
final knownLiveEntries = knownEntries.where((entry) => !entry.trashed).toSet();
|
||||||
|
|
||||||
debugPrint('$runtimeType load ${stopwatch.elapsed} check obsolete entries');
|
debugPrint('$runtimeType load ${stopwatch.elapsed} check obsolete entries');
|
||||||
|
@ -114,18 +118,20 @@ class MediaStoreSource extends CollectionSource {
|
||||||
// add entries without notifying, so that the collection is not refreshed
|
// add entries without notifying, so that the collection is not refreshed
|
||||||
// with items that may be hidden right away because of their metadata
|
// with items that may be hidden right away because of their metadata
|
||||||
addEntries(knownEntries, notify: false);
|
addEntries(knownEntries, notify: false);
|
||||||
|
// but use album notification without waiting for cataloguing
|
||||||
|
// so that it is more reactive when picking an album in view mode
|
||||||
|
notifyAlbumsChanged();
|
||||||
|
|
||||||
await _loadVaultEntries(directory);
|
await _loadVaultEntries(scopeDirectory);
|
||||||
|
|
||||||
debugPrint('$runtimeType load ${stopwatch.elapsed} load metadata');
|
debugPrint('$runtimeType load ${stopwatch.elapsed} load metadata');
|
||||||
if (directory != null) {
|
if (scopeDirectory != null) {
|
||||||
final ids = knownLiveEntries.map((entry) => entry.id).toSet();
|
final ids = knownLiveEntries.map((entry) => entry.id).toSet();
|
||||||
await loadCatalogMetadata(ids: ids);
|
await loadCatalogMetadata(ids: ids);
|
||||||
await loadAddresses(ids: ids);
|
await loadAddresses(ids: ids);
|
||||||
} else {
|
} else {
|
||||||
await loadCatalogMetadata();
|
await loadCatalogMetadata();
|
||||||
await loadAddresses();
|
await loadAddresses();
|
||||||
updateDerivedFilters();
|
|
||||||
|
|
||||||
// trash
|
// trash
|
||||||
await loadTrashDetails();
|
await loadTrashDetails();
|
||||||
|
@ -139,6 +145,7 @@ class MediaStoreSource extends CollectionSource {
|
||||||
onError: (error) => debugPrint('failed to evict expired trash error=$error'),
|
onError: (error) => debugPrint('failed to evict expired trash error=$error'),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
updateDerivedFilters();
|
||||||
|
|
||||||
// clean up obsolete entries
|
// clean up obsolete entries
|
||||||
if (removedEntries.isNotEmpty) {
|
if (removedEntries.isNotEmpty) {
|
||||||
|
@ -146,13 +153,14 @@ class MediaStoreSource extends CollectionSource {
|
||||||
await localMediaDb.removeIds(removedEntries.map((entry) => entry.id).toSet());
|
await localMediaDb.removeIds(removedEntries.map((entry) => entry.id).toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_loadedScope = _targetScope;
|
||||||
unawaited(reportService.log('$runtimeType load (known) done in ${stopwatch.elapsed.inSeconds}s for ${knownEntries.length} known, ${removedEntries.length} removed'));
|
unawaited(reportService.log('$runtimeType load (known) done in ${stopwatch.elapsed.inSeconds}s for ${knownEntries.length} known, ${removedEntries.length} removed'));
|
||||||
|
|
||||||
if (_canAnalyze) {
|
if (_canAnalyze) {
|
||||||
// it can discover new entries only if it can analyze them
|
// it can discover new entries only if it can analyze them
|
||||||
await _loadNewEntries(
|
await _loadNewEntries(
|
||||||
analysisController: analysisController,
|
analysisController: analysisController,
|
||||||
directory: directory,
|
directory: scopeDirectory,
|
||||||
knownLiveEntries: knownLiveEntries,
|
knownLiveEntries: knownLiveEntries,
|
||||||
knownDateByContentId: knownDateByContentId,
|
knownDateByContentId: knownDateByContentId,
|
||||||
);
|
);
|
||||||
|
@ -252,7 +260,7 @@ class MediaStoreSource extends CollectionSource {
|
||||||
// sometimes yields an entry with its temporary path: `/data/sec/camera/!@#$%^..._temp.jpg`
|
// sometimes yields an entry with its temporary path: `/data/sec/camera/!@#$%^..._temp.jpg`
|
||||||
@override
|
@override
|
||||||
Future<Set<String>> refreshUris(Set<String> changedUris, {AnalysisController? analysisController}) async {
|
Future<Set<String>> refreshUris(Set<String> changedUris, {AnalysisController? analysisController}) async {
|
||||||
if (_scope == SourceScope.none || !canRefresh || !isReady) return changedUris;
|
if (!canRefresh || !_areEssentialsLoaded || !isReady) return changedUris;
|
||||||
|
|
||||||
state = SourceState.loading;
|
state = SourceState.loading;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'package:aves/l10n/l10n.dart';
|
||||||
import 'package:aves/model/device.dart';
|
import 'package:aves/model/device.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/source/analysis_controller.dart';
|
import 'package:aves/model/source/analysis_controller.dart';
|
||||||
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
import 'package:aves/model/source/media_store_source.dart';
|
import 'package:aves/model/source/media_store_source.dart';
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:aves/utils/android_file_utils.dart';
|
import 'package:aves/utils/android_file_utils.dart';
|
||||||
|
@ -148,7 +149,7 @@ class Analyzer with WidgetsBindingObserver {
|
||||||
settings.systemLocalesFallback = await deviceService.getLocales();
|
settings.systemLocalesFallback = await deviceService.getLocales();
|
||||||
_l10n = await AppLocalizations.delegate.load(settings.appliedLocale);
|
_l10n = await AppLocalizations.delegate.load(settings.appliedLocale);
|
||||||
_serviceStateNotifier.value = AnalyzerState.running;
|
_serviceStateNotifier.value = AnalyzerState.running;
|
||||||
await _source.init(analysisController: _controller);
|
await _source.init(scope: CollectionSource.fullScope, analysisController: _controller);
|
||||||
|
|
||||||
_notificationUpdateTimer = Timer.periodic(notificationUpdateInterval, (_) async {
|
_notificationUpdateTimer = Timer.periodic(notificationUpdateInterval, (_) async {
|
||||||
if (!isRunning) return;
|
if (!isRunning) return;
|
||||||
|
|
|
@ -97,7 +97,7 @@ Future<AvesEntry?> _getWidgetEntry(int widgetId, bool reuseEntry) async {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
source.canAnalyze = false;
|
source.canAnalyze = false;
|
||||||
await source.init();
|
await source.init(scope: filters);
|
||||||
await readyCompleter.future;
|
await readyCompleter.future;
|
||||||
|
|
||||||
final entries = CollectionLens(source: source, filters: filters).sortedEntries;
|
final entries = CollectionLens(source: source, filters: filters).sortedEntries;
|
||||||
|
|
|
@ -685,12 +685,10 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
|
|
||||||
Future<void> _onAnalysisCompletion() async {
|
Future<void> _onAnalysisCompletion() async {
|
||||||
debugPrint('Analysis completed');
|
debugPrint('Analysis completed');
|
||||||
if (_mediaStoreSource.scope != SourceScope.none) {
|
|
||||||
await _mediaStoreSource.loadCatalogMetadata();
|
await _mediaStoreSource.loadCatalogMetadata();
|
||||||
await _mediaStoreSource.loadAddresses();
|
await _mediaStoreSource.loadAddresses();
|
||||||
_mediaStoreSource.updateDerivedFilters();
|
_mediaStoreSource.updateDerivedFilters();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void _onError(String? error) => reportService.recordError(error, null);
|
void _onError(String? error) => reportService.recordError(error, null);
|
||||||
|
|
||||||
|
|
|
@ -498,7 +498,7 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> with Widge
|
||||||
_checkingStoragePermission = false;
|
_checkingStoragePermission = false;
|
||||||
_isStoragePermissionGranted.then((granted) {
|
_isStoragePermissionGranted.then((granted) {
|
||||||
if (granted) {
|
if (granted) {
|
||||||
widget.collection.source.init();
|
widget.collection.source.init(scope: CollectionSource.fullScope);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,11 +35,11 @@ Future<String?> pickAlbum({
|
||||||
required MoveType? moveType,
|
required MoveType? moveType,
|
||||||
}) async {
|
}) async {
|
||||||
final source = context.read<CollectionSource>();
|
final source = context.read<CollectionSource>();
|
||||||
if (source.scope != SourceScope.full) {
|
if (source.targetScope != CollectionSource.fullScope) {
|
||||||
await reportService.log('Complete source initialization to pick album');
|
await reportService.log('Complete source initialization to pick album');
|
||||||
// source may not be fully initialized in view mode
|
// source may not be fully initialized in view mode
|
||||||
source.canAnalyze = true;
|
source.canAnalyze = true;
|
||||||
await source.init();
|
await source.init(scope: CollectionSource.fullScope);
|
||||||
}
|
}
|
||||||
final filter = await Navigator.maybeOf(context)?.push(
|
final filter = await Navigator.maybeOf(context)?.push(
|
||||||
MaterialPageRoute<AlbumFilter>(
|
MaterialPageRoute<AlbumFilter>(
|
||||||
|
|
|
@ -222,16 +222,17 @@ class _HomePageState extends State<HomePage> {
|
||||||
unawaited(GlobalSearch.registerCallback());
|
unawaited(GlobalSearch.registerCallback());
|
||||||
unawaited(AnalysisService.registerCallback());
|
unawaited(AnalysisService.registerCallback());
|
||||||
final source = context.read<CollectionSource>();
|
final source = context.read<CollectionSource>();
|
||||||
if (source.scope != SourceScope.full) {
|
if (source.loadedScope != CollectionSource.fullScope) {
|
||||||
await reportService.log('Initialize source (init state=${source.scope.name}) to start app with mode=$appMode');
|
await reportService.log('Initialize source to start app with mode=$appMode, loaded scope=${source.loadedScope}');
|
||||||
final loadTopEntriesFirst = settings.homePage == HomePageSetting.collection && settings.homeCustomCollection.isEmpty;
|
final loadTopEntriesFirst = settings.homePage == HomePageSetting.collection && settings.homeCustomCollection.isEmpty;
|
||||||
await source.init(loadTopEntriesFirst: loadTopEntriesFirst);
|
source.canAnalyze = true;
|
||||||
|
await source.init(scope: CollectionSource.fullScope, loadTopEntriesFirst: loadTopEntriesFirst);
|
||||||
}
|
}
|
||||||
case AppMode.screenSaver:
|
case AppMode.screenSaver:
|
||||||
await reportService.log('Initialize source to start screen saver');
|
await reportService.log('Initialize source to start screen saver');
|
||||||
final source = context.read<CollectionSource>();
|
final source = context.read<CollectionSource>();
|
||||||
source.canAnalyze = false;
|
source.canAnalyze = false;
|
||||||
await source.init();
|
await source.init(scope: settings.screenSaverCollectionFilters);
|
||||||
case AppMode.view:
|
case AppMode.view:
|
||||||
if (_isViewerSourceable(_viewerEntry) && _secureUris == null) {
|
if (_isViewerSourceable(_viewerEntry) && _secureUris == null) {
|
||||||
final directory = _viewerEntry?.directory;
|
final directory = _viewerEntry?.directory;
|
||||||
|
@ -240,7 +241,7 @@ class _HomePageState extends State<HomePage> {
|
||||||
await reportService.log('Initialize source to view item in directory $directory');
|
await reportService.log('Initialize source to view item in directory $directory');
|
||||||
final source = context.read<CollectionSource>();
|
final source = context.read<CollectionSource>();
|
||||||
source.canAnalyze = false;
|
source.canAnalyze = false;
|
||||||
await source.init(albumFilter: AlbumFilter(directory, null));
|
await source.init(scope: {AlbumFilter(directory, null)});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await _initViewerEssentials();
|
await _initViewerEssentials();
|
||||||
|
@ -305,19 +306,20 @@ class _HomePageState extends State<HomePage> {
|
||||||
CollectionLens? collection;
|
CollectionLens? collection;
|
||||||
|
|
||||||
final source = context.read<CollectionSource>();
|
final source = context.read<CollectionSource>();
|
||||||
if (source.scope != SourceScope.none) {
|
|
||||||
final album = viewerEntry.directory;
|
final album = viewerEntry.directory;
|
||||||
if (album != null) {
|
if (album != null) {
|
||||||
// wait for collection to pass the `loading` state
|
// wait for collection to pass the `loading` state
|
||||||
final completer = Completer();
|
final completer = Completer();
|
||||||
|
final stateNotifier = source.stateNotifier;
|
||||||
void _onSourceStateChanged() {
|
void _onSourceStateChanged() {
|
||||||
if (source.state != SourceState.loading) {
|
if (stateNotifier.value != SourceState.loading) {
|
||||||
source.stateNotifier.removeListener(_onSourceStateChanged);
|
stateNotifier.removeListener(_onSourceStateChanged);
|
||||||
completer.complete();
|
completer.complete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
source.stateNotifier.addListener(_onSourceStateChanged);
|
stateNotifier.addListener(_onSourceStateChanged);
|
||||||
|
_onSourceStateChanged();
|
||||||
await completer.future;
|
await completer.future;
|
||||||
|
|
||||||
collection = CollectionLens(
|
collection = CollectionLens(
|
||||||
|
@ -338,7 +340,6 @@ class _HomePageState extends State<HomePage> {
|
||||||
collection = null;
|
collection = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return DirectMaterialPageRoute(
|
return DirectMaterialPageRoute(
|
||||||
settings: const RouteSettings(name: EntryViewerPage.routeName),
|
settings: const RouteSettings(name: EntryViewerPage.routeName),
|
||||||
|
|
|
@ -442,9 +442,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
|
||||||
showFeedback(context, FeedbackType.warn, l10n.genericFailureFeedback);
|
showFeedback(context, FeedbackType.warn, l10n.genericFailureFeedback);
|
||||||
} else {
|
} else {
|
||||||
final source = context.read<CollectionSource>();
|
final source = context.read<CollectionSource>();
|
||||||
if (source.scope != SourceScope.none) {
|
|
||||||
await source.removeEntries({targetEntry.uri}, includeTrash: true);
|
await source.removeEntries({targetEntry.uri}, includeTrash: true);
|
||||||
}
|
|
||||||
EntryDeletedNotification({targetEntry}).dispatch(context);
|
EntryDeletedNotification({targetEntry}).dispatch(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ void main() {
|
||||||
readyCompleter.complete();
|
readyCompleter.complete();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await source.init();
|
await source.init(scope: CollectionSource.fullScope);
|
||||||
await readyCompleter.future;
|
await readyCompleter.future;
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
@ -107,9 +107,9 @@ void main() {
|
||||||
(mediaFetchService as FakeMediaFetchService).entries = {refreshEntry};
|
(mediaFetchService as FakeMediaFetchService).entries = {refreshEntry};
|
||||||
|
|
||||||
final source = MediaStoreSource();
|
final source = MediaStoreSource();
|
||||||
unawaited(source.init());
|
unawaited(source.init(scope: CollectionSource.fullScope));
|
||||||
await Future.delayed(const Duration(milliseconds: 10));
|
await Future.delayed(const Duration(milliseconds: 10));
|
||||||
expect(source.scope, SourceScope.full);
|
expect(source.targetScope, CollectionSource.fullScope);
|
||||||
await source.refreshUris({refreshEntry.uri});
|
await source.refreshUris({refreshEntry.uri});
|
||||||
|
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
|
|
Loading…
Reference in a new issue