From 09de6bb76ba52dc33a47593723040412212fd121 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sat, 30 Jan 2021 13:00:32 +0900 Subject: [PATCH] info: fixed owner for current entry --- lib/widgets/viewer/info/basic_section.dart | 68 ++++++++++++++++++---- lib/widgets/viewer/info/common.dart | 2 +- lib/widgets/viewer/info/info_page.dart | 16 +++-- 3 files changed, 71 insertions(+), 15 deletions(-) diff --git a/lib/widgets/viewer/info/basic_section.dart b/lib/widgets/viewer/info/basic_section.dart index b900b4b7c..acfd8119d 100644 --- a/lib/widgets/viewer/info/basic_section.dart +++ b/lib/widgets/viewer/info/basic_section.dart @@ -20,12 +20,14 @@ import 'package:intl/intl.dart'; class BasicSection extends StatelessWidget { final AvesEntry entry; final CollectionLens collection; + final ValueNotifier visibleNotifier; final FilterCallback onFilter; const BasicSection({ Key key, @required this.entry, this.collection, + @required this.visibleNotifier, @required this.onFilter, }) : super(key: key); @@ -58,7 +60,10 @@ class BasicSection extends StatelessWidget { 'URI': uri, if (path != null) 'Path': path, }), - OwnerProp(entry: entry), + OwnerProp( + entry: entry, + visibleNotifier: visibleNotifier, + ), _buildChips(), ], ); @@ -109,9 +114,11 @@ class BasicSection extends StatelessWidget { class OwnerProp extends StatefulWidget { final AvesEntry entry; + final ValueNotifier visibleNotifier; const OwnerProp({ @required this.entry, + @required this.visibleNotifier, }); @override @@ -119,24 +126,53 @@ class OwnerProp extends StatefulWidget { } class _OwnerPropState extends State { - Future _loader; + final ValueNotifier _loadedUri = ValueNotifier(null); + String _ownerPackage; + + AvesEntry get entry => widget.entry; + + bool get isVisible => widget.visibleNotifier.value; static const iconSize = 20.0; @override void initState() { super.initState(); - _loader = MetadataService.getContentResolverProp(widget.entry, 'owner_package_name'); + _registerWidget(widget); + _getOwner(); + } + + @override + void didUpdateWidget(covariant OwnerProp oldWidget) { + super.didUpdateWidget(oldWidget); + _unregisterWidget(oldWidget); + _registerWidget(widget); + _getOwner(); + } + + @override + void dispose() { + _unregisterWidget(widget); + super.dispose(); + } + + void _registerWidget(OwnerProp widget) { + widget.visibleNotifier.addListener(_getOwner); + } + + void _unregisterWidget(OwnerProp widget) { + widget.visibleNotifier.removeListener(_getOwner); } @override Widget build(BuildContext context) { - return FutureBuilder( - future: _loader, - builder: (context, snapshot) { - final packageName = snapshot.data; - if (packageName == null) return SizedBox(); - final appName = androidFileUtils.getCurrentAppName(packageName) ?? packageName; + return ValueListenableBuilder( + valueListenable: _loadedUri, + builder: (context, uri, child) { + if (_ownerPackage == null) return SizedBox(); + final appName = androidFileUtils.getCurrentAppName(_ownerPackage) ?? _ownerPackage; + // as of Flutter v1.22.6, `SelectableText` cannot contain `WidgetSpan` + // so be use a basic `Text` instead return Text.rich( TextSpan( children: [ @@ -150,7 +186,7 @@ class _OwnerPropState extends State { padding: EdgeInsets.symmetric(horizontal: 4), child: Image( image: AppIconImage( - packageName: packageName, + packageName: _ownerPackage, size: iconSize, ), width: iconSize, @@ -168,4 +204,16 @@ class _OwnerPropState extends State { }, ); } + + Future _getOwner() async { + if (entry == null) return; + if (_loadedUri.value == entry.uri) return; + if (isVisible) { + _ownerPackage = await MetadataService.getContentResolverProp(widget.entry, 'owner_package_name'); + _loadedUri.value = entry.uri; + } else { + _ownerPackage = null; + _loadedUri.value = null; + } + } } diff --git a/lib/widgets/viewer/info/common.dart b/lib/widgets/viewer/info/common.dart index 5b0ff8243..5d99e65f5 100644 --- a/lib/widgets/viewer/info/common.dart +++ b/lib/widgets/viewer/info/common.dart @@ -116,7 +116,7 @@ class _InfoRowGroupState extends State { value = '$value\n'; } - // as of Flutter v1.22.4, `SelectableText` cannot contain `WidgetSpan` + // as of Flutter v1.22.6, `SelectableText` cannot contain `WidgetSpan` // so we add padding using multiple hair spaces instead final thisSpaceSize = max(0.0, (baseValueX - keySizes[key])) + InfoRowGroup.keyValuePadding; final spaceCount = (100 * thisSpaceSize / baseSpaceWidth).round(); diff --git a/lib/widgets/viewer/info/info_page.dart b/lib/widgets/viewer/info/info_page.dart index 3adede21f..112bb6310 100644 --- a/lib/widgets/viewer/info/info_page.dart +++ b/lib/widgets/viewer/info/info_page.dart @@ -156,14 +156,22 @@ class _InfoPageContentState extends State<_InfoPageContent> { AvesEntry get entry => widget.entry; + ValueNotifier get visibleNotifier => widget.visibleNotifier; + @override Widget build(BuildContext context) { + final basicSection = BasicSection( + entry: entry, + collection: collection, + visibleNotifier: visibleNotifier, + onFilter: _goToCollection, + ); final locationAtTop = widget.split && entry.hasGps; final locationSection = LocationSection( collection: collection, entry: entry, showTitle: !locationAtTop, - visibleNotifier: widget.visibleNotifier, + visibleNotifier: visibleNotifier, onFilter: _goToCollection, ); final basicAndLocationSliver = locationAtTop @@ -171,7 +179,7 @@ class _InfoPageContentState extends State<_InfoPageContent> { child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded(child: BasicSection(entry: entry, collection: collection, onFilter: _goToCollection)), + Expanded(child: basicSection), SizedBox(width: 8), Expanded(child: locationSection), ], @@ -180,7 +188,7 @@ class _InfoPageContentState extends State<_InfoPageContent> { : SliverList( delegate: SliverChildListDelegate.fixed( [ - BasicSection(entry: entry, collection: collection, onFilter: _goToCollection), + basicSection, locationSection, ], ), @@ -188,7 +196,7 @@ class _InfoPageContentState extends State<_InfoPageContent> { final metadataSliver = MetadataSectionSliver( entry: entry, metadataNotifier: _metadataNotifier, - visibleNotifier: widget.visibleNotifier, + visibleNotifier: visibleNotifier, ); return CustomScrollView(