From dcf35f61c6f295e52c81dc6e257ad15a655d25ed Mon Sep 17 00:00:00 2001 From: Ming Ming Date: Tue, 27 Apr 2021 17:54:11 +0800 Subject: [PATCH] Drop successive scan dir request Happens when external events are fired quickly in succession --- lib/bloc/scan_dir.dart | 43 +++++++++++++++++++++++++++++++------ lib/widget/home_photos.dart | 12 ++++++++++- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/lib/bloc/scan_dir.dart b/lib/bloc/scan_dir.dart index b7e7eb32..189e6ebb 100644 --- a/lib/bloc/scan_dir.dart +++ b/lib/bloc/scan_dir.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; import 'package:kiwi/kiwi.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; @@ -13,8 +14,8 @@ abstract class ScanDirBlocEvent { const ScanDirBlocEvent(); } -class ScanDirBlocQuery extends ScanDirBlocEvent { - const ScanDirBlocQuery(this.account, this.roots); +class ScanDirBlocQueryBase extends ScanDirBlocEvent { + const ScanDirBlocQueryBase(this.account, this.roots); @override toString() { @@ -28,6 +29,22 @@ class ScanDirBlocQuery extends ScanDirBlocEvent { final List roots; } +class ScanDirBlocQuery extends ScanDirBlocQueryBase with EquatableMixin { + const ScanDirBlocQuery(Account account, List roots) + : super(account, roots); + + @override + get props => [ + account, + roots, + ]; +} + +class ScanDirBlocRefresh extends ScanDirBlocQueryBase { + const ScanDirBlocRefresh(Account account, List roots) + : super(account, roots); +} + /// An external event has happened and may affect the state of this bloc class _ScanDirBlocExternalEvent extends ScanDirBlocEvent { const _ScanDirBlocExternalEvent(); @@ -122,10 +139,22 @@ class ScanDirBloc extends Bloc { } } + @override + transformEvents(Stream events, transitionFn) { + return super.transformEvents(events.distinct((a, b) { + // only handle ScanDirBlocQuery + final r = a is ScanDirBlocQuery && b is ScanDirBlocQuery && a == b; + if (r) { + _log.fine("[transformEvents] Skip identical ScanDirBlocQuery event"); + } + return r; + }), transitionFn); + } + @override mapEventToState(ScanDirBlocEvent event) async* { _log.info("[mapEventToState] $event"); - if (event is ScanDirBlocQuery) { + if (event is ScanDirBlocQueryBase) { yield* _onEventQuery(event); } else if (event is _ScanDirBlocExternalEvent) { yield* _onExternalEvent(event); @@ -139,7 +168,7 @@ class ScanDirBloc extends Bloc { return super.close(); } - Stream _onEventQuery(ScanDirBlocQuery ev) async* { + Stream _onEventQuery(ScanDirBlocQueryBase ev) async* { yield ScanDirBlocLoading(ev.account, state.files); bool hasContent = state.files.isNotEmpty; @@ -193,14 +222,14 @@ class ScanDirBloc extends Bloc { } Stream _queryOffline( - ScanDirBlocQuery ev, ScanDirBlocState Function() getState) => + ScanDirBlocQueryBase ev, ScanDirBlocState Function() getState) => _queryWithFileDataSource(ev, getState, FileAppDbDataSource()); Stream _queryOnline( - ScanDirBlocQuery ev, ScanDirBlocState Function() getState) => + ScanDirBlocQueryBase ev, ScanDirBlocState Function() getState) => _queryWithFileDataSource(ev, getState, FileCachedDataSource()); - Stream _queryWithFileDataSource(ScanDirBlocQuery ev, + Stream _queryWithFileDataSource(ScanDirBlocQueryBase ev, ScanDirBlocState Function() getState, FileDataSource dataSrc) async* { try { for (final r in ev.roots) { diff --git a/lib/widget/home_photos.dart b/lib/widget/home_photos.dart index 84b5a5a1..911fb5ae 100644 --- a/lib/widget/home_photos.dart +++ b/lib/widget/home_photos.dart @@ -322,7 +322,7 @@ class _HomePhotosState extends State } void _onRefreshSelected() { - _reqQuery(); + _reqRefresh(); if (Pref.inst().isEnableExif()) { KiwiContainer() .resolve() @@ -374,6 +374,16 @@ class _HomePhotosState extends State .toList())); } + void _reqRefresh() { + _bloc.add(ScanDirBlocRefresh( + widget.account, + widget.account.roots + .map((e) => File( + path: + "${api_util.getWebdavRootUrlRelative(widget.account)}/$e")) + .toList())); + } + int get _thumbSize { switch (_thumbZoomLevel) { case 1: