info: back to image on top overscroll or button

This commit is contained in:
Thibault Deckers 2019-07-30 00:55:18 +09:00
parent 9c8df80a48
commit 8f94af28d3
3 changed files with 89 additions and 46 deletions

View file

@ -73,8 +73,20 @@ class FullscreenPageState extends State<FullscreenPage> with SingleTickerProvide
onPageChanged: (page) => setState(() => _currentHorizontalPage = page),
onScaleChanged: (state) => setState(() => _isInitialScale = state == PhotoViewScaleState.initial),
),
InfoPage(
entry: entries[_currentHorizontalPage],
NotificationListener(
onNotification: (notification) {
if (notification is BackUpNotification) {
_verticalPager.animateToPage(
0,
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
}
return false;
},
child: InfoPage(
entry: entries[_currentHorizontalPage],
),
),
],
),

View file

@ -15,6 +15,7 @@ class InfoPage extends StatefulWidget {
class InfoPageState extends State<InfoPage> {
Future<Map> _metadataLoader;
bool _scrollStartFromTop = false;
ImageEntry get entry => widget.entry;
@ -39,50 +40,74 @@ class InfoPageState extends State<InfoPage> {
final date = entry.getBestDate();
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_upward),
onPressed: () => BackUpNotification().dispatch(context),
tooltip: 'Back to image',
),
title: Text('Info'),
),
body: ListView(
padding: EdgeInsets.all(8.0),
children: [
SectionRow('File'),
InfoRow('Title', entry.title),
InfoRow('Date', '${DateFormat.yMMMd().format(date)} ${DateFormat.Hm().format(date)}'),
InfoRow('Resolution', '${entry.width} × ${entry.height} (${entry.getMegaPixels()} MP)'),
InfoRow('Size', formatFilesize(entry.sizeBytes)),
InfoRow('Path', entry.path),
SectionRow('Location'),
SectionRow('XMP Tags'),
SectionRow('Metadata'),
FutureBuilder(
future: _metadataLoader,
builder: (futureContext, AsyncSnapshot<Map> snapshot) {
if (snapshot.hasError) {
return Text(snapshot.error);
body: NotificationListener(
onNotification: (notification) {
if (notification is ScrollNotification) {
if (notification is ScrollStartNotification) {
final metrics = notification.metrics;
_scrollStartFromTop = metrics.pixels == metrics.minScrollExtent;
}
if (_scrollStartFromTop) {
if (notification is ScrollEndNotification) {
_scrollStartFromTop = false;
} else if (notification is OverscrollNotification) {
if (notification.overscroll < 0) {
BackUpNotification().dispatch(context);
_scrollStartFromTop = false;
}
}
if (snapshot.connectionState != ConnectionState.done) {
return CircularProgressIndicator();
}
final metadataMap = snapshot.data.cast<String, Map>();
final directoryNames = metadataMap.keys.toList()..sort();
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: directoryNames.expand(
(directoryName) {
final directory = metadataMap[directoryName];
final tagKeys = directory.keys.toList()..sort();
return [
Padding(
padding: EdgeInsets.symmetric(vertical: 4.0),
child: Text(directoryName, style: TextStyle(fontSize: 18)),
),
...tagKeys.map((tagKey) => InfoRow(tagKey, directory[tagKey])),
SizedBox(height: 16),
];
},
).toList());
},
),
],
}
}
return false;
},
child: ListView(
padding: EdgeInsets.all(8.0),
children: [
SectionRow('File'),
InfoRow('Title', entry.title),
InfoRow('Date', '${DateFormat.yMMMd().format(date)} ${DateFormat.Hm().format(date)}'),
InfoRow('Resolution', '${entry.width} × ${entry.height} (${entry.getMegaPixels()} MP)'),
InfoRow('Size', formatFilesize(entry.sizeBytes)),
InfoRow('Path', entry.path),
SectionRow('Metadata'),
FutureBuilder(
future: _metadataLoader,
builder: (futureContext, AsyncSnapshot<Map> snapshot) {
if (snapshot.hasError) {
return Text(snapshot.error);
}
if (snapshot.connectionState != ConnectionState.done) {
return CircularProgressIndicator();
}
final metadataMap = snapshot.data.cast<String, Map>();
final directoryNames = metadataMap.keys.toList()..sort();
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: directoryNames.expand(
(directoryName) {
final directory = metadataMap[directoryName];
final tagKeys = directory.keys.toList()..sort();
return [
Padding(
padding: EdgeInsets.symmetric(vertical: 4.0),
child: Text(directoryName, style: TextStyle(fontSize: 18)),
),
...tagKeys.map((tagKey) => InfoRow(tagKey, directory[tagKey])),
SizedBox(height: 16),
];
},
).toList());
},
),
],
),
),
);
}
@ -96,7 +121,7 @@ class SectionRow extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 4.0),
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Row(
children: [
Expanded(child: Divider(color: Colors.white70)),
@ -131,3 +156,5 @@ class InfoRow extends StatelessWidget {
);
}
}
class BackUpNotification extends Notification {}

View file

@ -2,8 +2,8 @@ import 'dart:math';
import 'dart:ui';
import 'package:aves/model/android_app_service.dart';
import 'package:aves/model/metadata_service.dart';
import 'package:aves/model/image_entry.dart';
import 'package:aves/model/metadata_service.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
@ -43,7 +43,11 @@ class FullscreenTopOverlay extends StatelessWidget {
title: Text('${index + 1}/${entries.length}'),
actions: [
// IconButton(icon: Icon(Icons.delete), onPressed: delete),
IconButton(icon: Icon(Icons.share), onPressed: share),
IconButton(
icon: Icon(Icons.share),
onPressed: share,
tooltip: 'Share',
),
],
elevation: 0,
backgroundColor: kOverlayBackground,