info: navigate by country
This commit is contained in:
parent
2e5a2e7c91
commit
77c9d86ea3
5 changed files with 99 additions and 57 deletions
|
@ -138,9 +138,9 @@ class _AllCollectionDrawerState extends State<AllCollectionDrawer> {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final tags = source.sortedTags;
|
||||
final countries = source.sortedCountries;
|
||||
final tags = source.sortedTags;
|
||||
|
||||
final drawerItems = [
|
||||
header,
|
||||
gifEntry,
|
||||
|
@ -175,28 +175,6 @@ class _AllCollectionDrawerState extends State<AllCollectionDrawer> {
|
|||
],
|
||||
),
|
||||
),
|
||||
if (tags.isNotEmpty)
|
||||
SafeArea(
|
||||
top: false,
|
||||
bottom: false,
|
||||
child: ExpansionTile(
|
||||
leading: const Icon(OMIcons.label),
|
||||
title: Row(
|
||||
children: [
|
||||
const Text('Tags'),
|
||||
const Spacer(),
|
||||
Text(
|
||||
'${tags.length}',
|
||||
style: TextStyle(
|
||||
color: (_tagsExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
onExpansionChanged: (expanded) => setState(() => _tagsExpanded = expanded),
|
||||
children: tags.map(buildTagEntry).toList(),
|
||||
),
|
||||
),
|
||||
if (countries.isNotEmpty)
|
||||
SafeArea(
|
||||
top: false,
|
||||
|
@ -219,6 +197,28 @@ class _AllCollectionDrawerState extends State<AllCollectionDrawer> {
|
|||
children: countries.map(buildCountryEntry).toList(),
|
||||
),
|
||||
),
|
||||
if (tags.isNotEmpty)
|
||||
SafeArea(
|
||||
top: false,
|
||||
bottom: false,
|
||||
child: ExpansionTile(
|
||||
leading: const Icon(OMIcons.label),
|
||||
title: Row(
|
||||
children: [
|
||||
const Text('Tags'),
|
||||
const Spacer(),
|
||||
Text(
|
||||
'${tags.length}',
|
||||
style: TextStyle(
|
||||
color: (_tagsExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
onExpansionChanged: (expanded) => setState(() => _tagsExpanded = expanded),
|
||||
children: tags.map(buildTagEntry).toList(),
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
return Drawer(
|
||||
|
|
|
@ -32,6 +32,8 @@ class InfoPageState extends State<InfoPage> {
|
|||
ScrollController _scrollController = ScrollController();
|
||||
bool _scrollStartFromTop = false;
|
||||
|
||||
CollectionLens get collection => widget.collection;
|
||||
|
||||
ImageEntry get entry => widget.entry;
|
||||
|
||||
@override
|
||||
|
@ -68,6 +70,7 @@ class InfoPageState extends State<InfoPage> {
|
|||
final locationAtTop = split && entry.hasGps;
|
||||
|
||||
final locationSection = LocationSection(
|
||||
collection: collection,
|
||||
entry: entry,
|
||||
showTitle: !locationAtTop,
|
||||
visibleNotifier: widget.visibleNotifier,
|
||||
|
@ -92,7 +95,7 @@ class InfoPageState extends State<InfoPage> {
|
|||
),
|
||||
);
|
||||
final tagSliver = XmpTagSectionSliver(
|
||||
collection: widget.collection,
|
||||
collection: collection,
|
||||
entry: entry,
|
||||
);
|
||||
final metadataSliver = MetadataSectionSliver(
|
||||
|
|
|
@ -1,19 +1,25 @@
|
|||
import 'package:aves/model/collection_filters.dart';
|
||||
import 'package:aves/model/collection_lens.dart';
|
||||
import 'package:aves/model/image_entry.dart';
|
||||
import 'package:aves/model/settings.dart';
|
||||
import 'package:aves/utils/android_app_service.dart';
|
||||
import 'package:aves/utils/geo_utils.dart';
|
||||
import 'package:aves/widgets/album/filtered_collection_page.dart';
|
||||
import 'package:aves/widgets/fullscreen/info/info_page.dart';
|
||||
import 'package:aves/widgets/fullscreen/info/navigation_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:outline_material_icons/outline_material_icons.dart';
|
||||
|
||||
class LocationSection extends StatefulWidget {
|
||||
final CollectionLens collection;
|
||||
final ImageEntry entry;
|
||||
final bool showTitle;
|
||||
final ValueNotifier<bool> visibleNotifier;
|
||||
|
||||
const LocationSection({
|
||||
Key key,
|
||||
@required this.collection,
|
||||
@required this.entry,
|
||||
@required this.showTitle,
|
||||
@required this.visibleNotifier,
|
||||
|
@ -26,6 +32,8 @@ class LocationSection extends StatefulWidget {
|
|||
class _LocationSectionState extends State<LocationSection> {
|
||||
String _loadedUri;
|
||||
|
||||
CollectionLens get collection => widget.collection;
|
||||
|
||||
ImageEntry get entry => widget.entry;
|
||||
|
||||
@override
|
||||
|
@ -64,12 +72,14 @@ class _LocationSectionState extends State<LocationSection> {
|
|||
final showMap = (_loadedUri == entry.uri) || (entry.hasGps && widget.visibleNotifier.value);
|
||||
if (showMap) {
|
||||
_loadedUri = entry.uri;
|
||||
String location;
|
||||
String location = '';
|
||||
if (entry.isLocated) {
|
||||
location = entry.addressDetails.addressLine;
|
||||
} else if (entry.hasGps) {
|
||||
location = toDMS(entry.latLng).join(', ');
|
||||
}
|
||||
final country = entry.addressDetails?.countryName ?? '';
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
@ -92,6 +102,19 @@ class _LocationSectionState extends State<LocationSection> {
|
|||
padding: const EdgeInsets.only(top: 8),
|
||||
child: InfoRowGroup({'Address': location}),
|
||||
),
|
||||
if (country.isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: NavigationButton.buttonBorderWidth / 2) + const EdgeInsets.only(top: 8),
|
||||
child: Wrap(
|
||||
spacing: 8,
|
||||
children: [
|
||||
NavigationButton(
|
||||
label: country,
|
||||
onPressed: () => _goToCountry(context, country),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
|
@ -101,6 +124,20 @@ class _LocationSectionState extends State<LocationSection> {
|
|||
}
|
||||
|
||||
void _handleChange() => setState(() {});
|
||||
|
||||
void _goToCountry(BuildContext context, String country) {
|
||||
if (collection == null) return;
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => FilteredCollectionPage(
|
||||
collection: collection,
|
||||
filter: CountryFilter(country),
|
||||
title: country,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ImageMap extends StatefulWidget {
|
||||
|
|
29
lib/widgets/fullscreen/info/navigation_button.dart
Normal file
29
lib/widgets/fullscreen/info/navigation_button.dart
Normal file
|
@ -0,0 +1,29 @@
|
|||
import 'package:aves/utils/color_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class NavigationButton extends StatelessWidget {
|
||||
final String label;
|
||||
final VoidCallback onPressed;
|
||||
|
||||
const NavigationButton({
|
||||
@required this.label,
|
||||
@required this.onPressed,
|
||||
});
|
||||
|
||||
static const double buttonBorderWidth = 2;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return OutlineButton(
|
||||
onPressed: onPressed,
|
||||
borderSide: BorderSide(
|
||||
color: stringToColor(label),
|
||||
width: buttonBorderWidth,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(42),
|
||||
),
|
||||
child: Text(label),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
import 'package:aves/model/collection_filters.dart';
|
||||
import 'package:aves/model/collection_lens.dart';
|
||||
import 'package:aves/model/image_entry.dart';
|
||||
import 'package:aves/utils/color_utils.dart';
|
||||
import 'package:aves/widgets/album/filtered_collection_page.dart';
|
||||
import 'package:aves/widgets/fullscreen/info/info_page.dart';
|
||||
import 'package:aves/widgets/fullscreen/info/navigation_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class XmpTagSectionSliver extends AnimatedWidget {
|
||||
|
@ -26,12 +26,12 @@ class XmpTagSectionSliver extends AnimatedWidget {
|
|||
: [
|
||||
const SectionRow('Tags'),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: TagButton.buttonBorderWidth / 2),
|
||||
padding: const EdgeInsets.symmetric(horizontal: NavigationButton.buttonBorderWidth / 2),
|
||||
child: Wrap(
|
||||
spacing: 8,
|
||||
children: tags
|
||||
.map((tag) => TagButton(
|
||||
tag: tag,
|
||||
.map((tag) => NavigationButton(
|
||||
label: tag,
|
||||
onPressed: () => _goToTag(context, tag),
|
||||
))
|
||||
.toList(),
|
||||
|
@ -56,30 +56,3 @@ class XmpTagSectionSliver extends AnimatedWidget {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TagButton extends StatelessWidget {
|
||||
final String tag;
|
||||
final VoidCallback onPressed;
|
||||
|
||||
const TagButton({
|
||||
@required this.tag,
|
||||
@required this.onPressed,
|
||||
});
|
||||
|
||||
static const double buttonBorderWidth = 2;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return OutlineButton(
|
||||
onPressed: onPressed,
|
||||
borderSide: BorderSide(
|
||||
color: stringToColor(tag),
|
||||
width: buttonBorderWidth,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(42),
|
||||
),
|
||||
child: Text(tag),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue