app bar: show cataloguing/locating progress

This commit is contained in:
Thibault Deckers 2020-06-05 15:51:08 +09:00
parent 755e75dc6a
commit 1be8853e63
4 changed files with 76 additions and 36 deletions

View file

@ -116,7 +116,7 @@ class _HomePageState extends State<HomePage> {
Future<void> _initViewerEntry({@required String uri, @required String mimeType}) async {
_viewerEntry = await ImageFileService.getImageEntry(uri, mimeType);
// cataloging is essential for geolocation and video rotation
// cataloguing is essential for geolocation and video rotation
await _viewerEntry.catalog();
unawaited(_viewerEntry.locate());
}

View file

@ -250,7 +250,7 @@ class CollectionSource {
}
}
enum SourceState { loading, cataloging, locating, ready }
enum SourceState { loading, cataloguing, locating, ready }
class AddressMetadataChangedEvent {}

View file

@ -3,6 +3,7 @@ import 'dart:async';
import 'package:aves/main.dart';
import 'package:aves/model/collection_lens.dart';
import 'package:aves/model/collection_source.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/model/settings.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/album/filter_bar.dart';
@ -135,23 +136,6 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
ValueListenableBuilder<SourceState>(
valueListenable: collection.source.stateNotifier,
builder: (context, sourceState, child) {
String subtitle;
switch (sourceState) {
case SourceState.loading:
subtitle = 'Loading';
break;
case SourceState.cataloging:
subtitle = 'Cataloging';
break;
case SourceState.locating:
subtitle = 'Locating';
break;
case SourceState.ready:
default:
break;
}
final subtitleStyle = Theme.of(context).textTheme.caption;
final progressIndicatorSize = subtitleStyle.fontSize;
return AnimatedSwitcher(
duration: Duration(milliseconds: (300 * timeDilation).toInt()),
transitionBuilder: (child, animation) => FadeTransition(
@ -161,23 +145,10 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
sizeFactor: animation,
),
),
child: subtitle == null
child: sourceState == SourceState.ready
? const SizedBox.shrink()
: Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: const EdgeInsets.all(1),
width: progressIndicatorSize,
height: progressIndicatorSize,
margin: const EdgeInsetsDirectional.only(end: 8),
child: const CircularProgressIndicator(strokeWidth: 1),
),
Text(
'$subtitle',
style: subtitleStyle,
),
],
: SourceStateSubtitle(
source: collection.source,
),
);
},
@ -387,3 +358,72 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
}
enum CollectionAction { copy, move, select, selectAll, selectNone, stats, groupByAlbum, groupByMonth, groupByDay, sortByDate, sortBySize, sortByName }
class SourceStateSubtitle extends StatefulWidget {
final CollectionSource source;
const SourceStateSubtitle({@required this.source});
@override
_SourceStateSubtitleState createState() => _SourceStateSubtitleState();
}
class _SourceStateSubtitleState extends State<SourceStateSubtitle> {
Timer _progressTimer;
CollectionSource get source => widget.source;
SourceState get sourceState => source.stateNotifier.value;
List<ImageEntry> get entries => source.entries;
@override
void initState() {
super.initState();
_progressTimer = Timer.periodic(const Duration(milliseconds: 1000), (timer) => setState(() {}));
}
@override
void dispose() {
_progressTimer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
String subtitle;
double progress;
switch (sourceState) {
case SourceState.loading:
subtitle = 'Loading';
break;
case SourceState.cataloguing:
subtitle = 'Cataloguing';
progress = entries.where((entry) => entry.isCatalogued).length.toDouble() / entries.length;
break;
case SourceState.locating:
subtitle = 'Locating';
progress = entries.where((entry) => entry.isLocated).length.toDouble() / entries.length;
break;
case SourceState.ready:
default:
break;
}
final subtitleStyle = Theme.of(context).textTheme.caption;
return subtitle == null
? const SizedBox.shrink()
: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(subtitle, style: subtitleStyle),
if (progress != null && progress > 0) ...[
const SizedBox(width: 8),
Text(
NumberFormat.percentPattern().format(progress),
style: subtitleStyle.copyWith(color: Colors.white30),
),
]
],
);
}
}

View file

@ -49,7 +49,7 @@ class MediaStoreSource {
source.addAll(allEntries);
// TODO reduce setup time until here
source.updateAlbums(); // <50ms
source.stateNotifier.value = SourceState.cataloging;
source.stateNotifier.value = SourceState.cataloguing;
await source.loadCatalogMetadata(); // 400ms for 5400 entries
await source.catalogEntries(); // <50ms
source.stateNotifier.value = SourceState.locating;