viewer: hide overlay when pressing play
This commit is contained in:
parent
a0f8b32440
commit
fee9386d3d
11 changed files with 80 additions and 71 deletions
|
@ -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,
|
||||
);
|
||||
},
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
|
|
|
@ -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(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}';
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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}';
|
||||
}
|
||||
|
|
3
lib/widgets/viewer/overlay/notifications.dart
Normal file
3
lib/widgets/viewer/overlay/notifications.dart
Normal file
|
@ -0,0 +1,3 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class ToggleOverlayNotification extends Notification {}
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue