viewer: hide overlay when pressing play

This commit is contained in:
Thibault Deckers 2021-04-16 13:00:14 +09:00
parent a0f8b32440
commit fee9386d3d
11 changed files with 80 additions and 71 deletions

View file

@ -14,7 +14,6 @@ class MultiEntryScroller extends StatefulWidget {
final CollectionLens collection;
final PageController pageController;
final ValueChanged<int> onPageChanged;
final VoidCallback onTap;
final List<Tuple2<String, AvesVideoController>> videoControllers;
final List<Tuple2<String, MultiPageController>> multiPageControllers;
final void Function(String uri) onViewDisposed;
@ -23,7 +22,6 @@ class MultiEntryScroller extends StatefulWidget {
this.collection,
this.pageController,
this.onPageChanged,
this.onTap,
this.videoControllers,
this.multiPageControllers,
this.onViewDisposed,
@ -89,7 +87,6 @@ class _MultiEntryScrollerState extends State<MultiEntryScroller> with AutomaticK
mainEntry: entry,
page: page,
viewportSize: mqSize,
onTap: widget.onTap == null ? null : (_) => widget.onTap(),
videoControllers: widget.videoControllers,
onDisposed: () => widget.onViewDisposed?.call(entry.uri),
);
@ -107,13 +104,11 @@ class _MultiEntryScrollerState extends State<MultiEntryScroller> with AutomaticK
class SingleEntryScroller extends StatefulWidget {
final AvesEntry entry;
final VoidCallback onTap;
final List<Tuple2<String, AvesVideoController>> videoControllers;
final List<Tuple2<String, MultiPageController>> multiPageControllers;
const SingleEntryScroller({
this.entry,
this.onTap,
this.videoControllers,
this.multiPageControllers,
});
@ -163,7 +158,6 @@ class _SingleEntryScrollerState extends State<SingleEntryScroller> with Automati
mainEntry: entry,
page: page,
viewportSize: mqSize,
onTap: widget.onTap == null ? null : (_) => widget.onTap(),
videoControllers: widget.videoControllers,
);
},

View file

@ -20,7 +20,7 @@ class ViewerVerticalPageView extends StatefulWidget {
final List<Tuple2<String, MultiPageController>> multiPageControllers;
final PageController horizontalPager, verticalPager;
final void Function(int page) onVerticalPageChanged, onHorizontalPageChanged;
final VoidCallback onImageTap, onImagePageRequested;
final VoidCallback onImagePageRequested;
final void Function(String uri) onViewDisposed;
const ViewerVerticalPageView({
@ -32,7 +32,6 @@ class ViewerVerticalPageView extends StatefulWidget {
@required this.horizontalPager,
@required this.onVerticalPageChanged,
@required this.onHorizontalPageChanged,
this.onImageTap,
@required this.onImagePageRequested,
@required this.onViewDisposed,
});
@ -92,7 +91,6 @@ class _ViewerVerticalPageViewState extends State<ViewerVerticalPageView> {
? MultiEntryScroller(
collection: collection,
pageController: widget.horizontalPager,
onTap: widget.onImageTap,
onPageChanged: widget.onHorizontalPageChanged,
videoControllers: widget.videoControllers,
multiPageControllers: widget.multiPageControllers,
@ -100,7 +98,6 @@ class _ViewerVerticalPageViewState extends State<ViewerVerticalPageView> {
)
: SingleEntryScroller(
entry: entry,
onTap: widget.onImageTap,
videoControllers: widget.videoControllers,
multiPageControllers: widget.multiPageControllers,
),

View file

@ -19,6 +19,7 @@ import 'package:aves/widgets/viewer/hero.dart';
import 'package:aves/widgets/viewer/info/notifications.dart';
import 'package:aves/widgets/viewer/multipage.dart';
import 'package:aves/widgets/viewer/overlay/bottom.dart';
import 'package:aves/widgets/viewer/overlay/notifications.dart';
import 'package:aves/widgets/viewer/overlay/panorama.dart';
import 'package:aves/widgets/viewer/overlay/top.dart';
import 'package:aves/widgets/viewer/overlay/video.dart';
@ -175,7 +176,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
value: _heroInfoNotifier,
child: NotificationListener(
onNotification: (notification) {
if (notification is FilterNotification) {
if (notification is FilterSelectedNotification) {
_goToCollection(notification.filter);
} else if (notification is ViewStateNotification) {
_updateViewState(notification.uri, notification.viewState);
@ -184,25 +185,33 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
}
return false;
},
child: Stack(
children: [
ViewerVerticalPageView(
collection: collection,
entryNotifier: _entryNotifier,
videoControllers: _videoControllers,
multiPageControllers: _multiPageControllers,
verticalPager: _verticalPager,
horizontalPager: _horizontalPager,
onVerticalPageChanged: _onVerticalPageChanged,
onHorizontalPageChanged: _onHorizontalPageChanged,
onImageTap: () => _overlayVisible.value = !_overlayVisible.value,
onImagePageRequested: () => _goToVerticalPage(imagePage),
onViewDisposed: (uri) => _updateViewState(uri, null),
),
_buildTopOverlay(),
_buildBottomOverlay(),
BottomGestureAreaProtector(),
],
child: NotificationListener(
onNotification: (notification) {
if (notification is ToggleOverlayNotification) {
_overlayVisible.value = !_overlayVisible.value;
return true;
}
return false;
},
child: Stack(
children: [
ViewerVerticalPageView(
collection: collection,
entryNotifier: _entryNotifier,
videoControllers: _videoControllers,
multiPageControllers: _multiPageControllers,
verticalPager: _verticalPager,
horizontalPager: _horizontalPager,
onVerticalPageChanged: _onVerticalPageChanged,
onHorizontalPageChanged: _onHorizontalPageChanged,
onImagePageRequested: () => _goToVerticalPage(imagePage),
onViewDisposed: (uri) => _updateViewState(uri, null),
),
_buildTopOverlay(),
_buildBottomOverlay(),
BottomGestureAreaProtector(),
],
),
),
),
),

View file

@ -222,6 +222,6 @@ class _InfoPageContentState extends State<_InfoPageContent> {
void _goToCollection(CollectionFilter filter) {
if (collection == null) return;
FilterNotification(filter).dispatch(context);
FilterSelectedNotification(filter).dispatch(context);
}
}

View file

@ -116,34 +116,3 @@ class XmpProp {
@override
String toString() => '$runtimeType#${shortHash(this)}{path=$path, value=$value}';
}
enum EmbeddedDataSource { videoCover, xmp }
class OpenEmbeddedDataNotification extends Notification {
final EmbeddedDataSource source;
final String propPath;
final String mimeType;
const OpenEmbeddedDataNotification._private({
@required this.source,
this.propPath,
this.mimeType,
});
factory OpenEmbeddedDataNotification.videoCover() => OpenEmbeddedDataNotification._private(
source: EmbeddedDataSource.videoCover,
);
factory OpenEmbeddedDataNotification.xmp({
@required String propPath,
@required String mimeType,
}) =>
OpenEmbeddedDataNotification._private(
source: EmbeddedDataSource.xmp,
propPath: propPath,
mimeType: mimeType,
);
@override
String toString() => '$runtimeType#${shortHash(this)}{source=$source, propPath=$propPath, mimeType=$mimeType}';
}

View file

@ -1,6 +1,7 @@
import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/viewer/info/common.dart';
import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
import 'package:aves/widgets/viewer/info/notifications.dart';
import 'package:tuple/tuple.dart';
abstract class XmpGoogleNamespace extends XmpNamespace {

View file

@ -3,6 +3,7 @@ import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/viewer/info/common.dart';
import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
import 'package:aves/widgets/viewer/info/metadata/xmp_structs.dart';
import 'package:aves/widgets/viewer/info/notifications.dart';
import 'package:flutter/material.dart';
class XmpBasicNamespace extends XmpNamespace {

View file

@ -5,10 +5,10 @@ import 'package:flutter/material.dart';
class BackUpNotification extends Notification {}
class FilterNotification extends Notification {
class FilterSelectedNotification extends Notification {
final CollectionFilter filter;
const FilterNotification(this.filter);
const FilterSelectedNotification(this.filter);
}
class EntryDeletedNotification extends Notification {
@ -27,3 +27,34 @@ class OpenTempEntryNotification extends Notification {
@override
String toString() => '$runtimeType#${shortHash(this)}{entry=$entry}';
}
enum EmbeddedDataSource { videoCover, xmp }
class OpenEmbeddedDataNotification extends Notification {
final EmbeddedDataSource source;
final String propPath;
final String mimeType;
const OpenEmbeddedDataNotification._private({
@required this.source,
this.propPath,
this.mimeType,
});
factory OpenEmbeddedDataNotification.videoCover() => OpenEmbeddedDataNotification._private(
source: EmbeddedDataSource.videoCover,
);
factory OpenEmbeddedDataNotification.xmp({
@required String propPath,
@required String mimeType,
}) =>
OpenEmbeddedDataNotification._private(
source: EmbeddedDataSource.xmp,
propPath: propPath,
mimeType: mimeType,
);
@override
String toString() => '$runtimeType#${shortHash(this)}{source=$source, propPath=$propPath, mimeType=$mimeType}';
}

View file

@ -0,0 +1,3 @@
import 'package:flutter/material.dart';
class ToggleOverlayNotification extends Notification {}

View file

@ -10,6 +10,7 @@ import 'package:aves/widgets/common/fx/blurred.dart';
import 'package:aves/widgets/common/fx/borders.dart';
import 'package:aves/widgets/common/video/controller.dart';
import 'package:aves/widgets/viewer/overlay/common.dart';
import 'package:aves/widgets/viewer/overlay/notifications.dart';
import 'package:flutter/material.dart';
class VideoControlOverlay extends StatefulWidget {
@ -209,6 +210,10 @@ class _VideoControlOverlayState extends State<VideoControlOverlay> with SingleTi
} else {
await controller.setDataSource(entry.uri);
}
// hide overlay
await Future.delayed(Durations.iconAnimation);
ToggleOverlayNotification().dispatch(context);
}
void _updatePlayPauseIcon() {

View file

@ -14,6 +14,7 @@ import 'package:aves/widgets/common/magnifier/scale/scale_level.dart';
import 'package:aves/widgets/common/magnifier/scale/state.dart';
import 'package:aves/widgets/common/video/controller.dart';
import 'package:aves/widgets/viewer/hero.dart';
import 'package:aves/widgets/viewer/overlay/notifications.dart';
import 'package:aves/widgets/viewer/visual/error.dart';
import 'package:aves/widgets/viewer/visual/raster.dart';
import 'package:aves/widgets/viewer/visual/state.dart';
@ -30,7 +31,6 @@ class EntryPageView extends StatefulWidget {
final AvesEntry entry;
final SinglePageInfo page;
final Size viewportSize;
final MagnifierTapCallback onTap;
final List<Tuple2<String, AvesVideoController>> videoControllers;
final VoidCallback onDisposed;
@ -41,7 +41,6 @@ class EntryPageView extends StatefulWidget {
this.mainEntry,
this.page,
this.viewportSize,
@required this.onTap,
@required this.videoControllers,
this.onDisposed,
}) : entry = mainEntry.getPageEntry(page) ?? mainEntry,
@ -62,8 +61,6 @@ class _EntryPageViewState extends State<EntryPageView> {
Size get viewportSize => widget.viewportSize;
MagnifierTapCallback get onTap => widget.onTap;
static const initialScale = ScaleLevel(ref: ScaleReference.contained);
static const minScale = ScaleLevel(ref: ScaleReference.contained);
static const maxScale = ScaleLevel(factor: 2.0);
@ -138,7 +135,7 @@ class _EntryPageViewState extends State<EntryPageView> {
}
child ??= ErrorView(
entry: entry,
onTap: onTap == null ? null : () => onTap(null),
onTap: _onTap,
);
return child;
},
@ -162,7 +159,7 @@ class _EntryPageViewState extends State<EntryPageView> {
viewStateNotifier: _viewStateNotifier,
errorBuilder: (context, error, stackTrace) => ErrorView(
entry: entry,
onTap: () => onTap?.call(null),
onTap: _onTap,
),
),
);
@ -221,11 +218,13 @@ class _EntryPageViewState extends State<EntryPageView> {
initialScale: initialScale,
scaleStateCycle: scaleStateCycle,
applyScale: applyScale,
onTap: onTap == null ? null : (c, d, s, childPosition) => onTap(childPosition),
onTap: (c, d, s, o) => _onTap(),
child: child,
);
}
void _onTap() => ToggleOverlayNotification().dispatch(context);
void _onViewStateChanged(MagnifierState v) {
final current = _viewStateNotifier.value;
final viewState = ViewState(v.position, v.scale, current.viewportSize);