renaming/reorganizing

This commit is contained in:
Thibault Deckers 2021-01-11 18:46:41 +09:00
parent 8de7896d4e
commit d9fad15e5e
64 changed files with 317 additions and 285 deletions

View file

@ -1,13 +1,13 @@
import 'package:screen/screen.dart'; import 'package:screen/screen.dart';
enum KeepScreenOn { never, fullscreenOnly, always } enum KeepScreenOn { never, viewerOnly, always }
extension ExtraKeepScreenOn on KeepScreenOn { extension ExtraKeepScreenOn on KeepScreenOn {
String get name { String get name {
switch (this) { switch (this) {
case KeepScreenOn.never: case KeepScreenOn.never:
return 'Never'; return 'Never';
case KeepScreenOn.fullscreenOnly: case KeepScreenOn.viewerOnly:
return 'Viewer page only'; return 'Viewer page only';
case KeepScreenOn.always: case KeepScreenOn.always:
return 'Always'; return 'Always';

View file

@ -3,7 +3,7 @@ import 'package:aves/model/settings/coordinate_format.dart';
import 'package:aves/model/settings/entry_background.dart'; import 'package:aves/model/settings/entry_background.dart';
import 'package:aves/model/settings/home_page.dart'; import 'package:aves/model/settings/home_page.dart';
import 'package:aves/model/settings/screen_on.dart'; import 'package:aves/model/settings/screen_on.dart';
import 'package:aves/widgets/fullscreen/info/location_section.dart'; import 'package:aves/widgets/viewer/info/location_section.dart';
import 'package:firebase_analytics/firebase_analytics.dart'; import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart';
@ -99,7 +99,7 @@ class Settings extends ChangeNotifier {
set mustBackTwiceToExit(bool newValue) => setAndNotify(mustBackTwiceToExitKey, newValue); set mustBackTwiceToExit(bool newValue) => setAndNotify(mustBackTwiceToExitKey, newValue);
KeepScreenOn get keepScreenOn => getEnumOrDefault(keepScreenOnKey, KeepScreenOn.fullscreenOnly, KeepScreenOn.values); KeepScreenOn get keepScreenOn => getEnumOrDefault(keepScreenOnKey, KeepScreenOn.viewerOnly, KeepScreenOn.values);
set keepScreenOn(KeepScreenOn newValue) { set keepScreenOn(KeepScreenOn newValue) {
setAndNotify(keepScreenOnKey, newValue.toString()); setAndNotify(keepScreenOnKey, newValue.toString());

View file

@ -7,7 +7,7 @@ import 'package:aves/widgets/collection/grid/list_section_layout.dart';
import 'package:aves/widgets/collection/thumbnail/decorated.dart'; import 'package:aves/widgets/collection/thumbnail/decorated.dart';
import 'package:aves/widgets/common/behaviour/routes.dart'; import 'package:aves/widgets/common/behaviour/routes.dart';
import 'package:aves/widgets/common/scaling.dart'; import 'package:aves/widgets/common/scaling.dart';
import 'package:aves/widgets/fullscreen/fullscreen_page.dart'; import 'package:aves/widgets/viewer/entry_viewer_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -57,7 +57,7 @@ class GridThumbnail extends StatelessWidget {
onTap: () { onTap: () {
if (AvesApp.mode == AppMode.main) { if (AvesApp.mode == AppMode.main) {
if (collection.isBrowsing) { if (collection.isBrowsing) {
_goToFullscreen(context); _goToViewer(context);
} else if (collection.isSelecting) { } else if (collection.isSelecting) {
collection.toggleSelection(entry); collection.toggleSelection(entry);
} }
@ -77,12 +77,12 @@ class GridThumbnail extends StatelessWidget {
); );
} }
void _goToFullscreen(BuildContext context) { void _goToViewer(BuildContext context) {
Navigator.push( Navigator.push(
context, context,
TransparentMaterialPageRoute( TransparentMaterialPageRoute(
settings: RouteSettings(name: MultiFullscreenPage.routeName), settings: RouteSettings(name: MultiEntryViewerPage.routeName),
pageBuilder: (c, a, sa) => MultiFullscreenPage( pageBuilder: (c, a, sa) => MultiEntryViewerPage(
collection: collection, collection: collection,
initialEntry: entry, initialEntry: entry,
), ),

View file

@ -35,11 +35,11 @@ class MagnifierCore extends StatefulWidget {
@override @override
State<StatefulWidget> createState() { State<StatefulWidget> createState() {
return MagnifierCoreState(); return _MagnifierCoreState();
} }
} }
class MagnifierCoreState extends State<MagnifierCore> with TickerProviderStateMixin, MagnifierControllerDelegate, CornerHitDetector { class _MagnifierCoreState extends State<MagnifierCore> with TickerProviderStateMixin, MagnifierControllerDelegate, CornerHitDetector {
Offset _startFocalPoint, _lastViewportFocalPosition; Offset _startFocalPoint, _lastViewportFocalPosition;
double _startScale, _quickScaleLastY, _quickScaleLastDistance; double _startScale, _quickScaleLastY, _quickScaleLastDistance;
bool _doubleTap, _quickScaleMoved; bool _doubleTap, _quickScaleMoved;

View file

@ -106,7 +106,7 @@ class _MagnifierState extends State<Magnifier> {
widget.maxScale ?? ScaleLevel(factor: double.infinity), widget.maxScale ?? ScaleLevel(factor: double.infinity),
widget.initialScale ?? ScaleLevel(ref: ScaleReference.contained), widget.initialScale ?? ScaleLevel(ref: ScaleReference.contained),
constraints.biggest, constraints.biggest,
widget.childSize?.isEmpty == true ? constraints.biggest: widget.childSize, widget.childSize?.isEmpty == true ? constraints.biggest : widget.childSize,
)); ));
return MagnifierCore( return MagnifierCore(

View file

@ -2,7 +2,7 @@ import 'dart:collection';
import 'package:aves/services/android_debug_service.dart'; import 'package:aves/services/android_debug_service.dart';
import 'package:aves/widgets/common/identity/aves_expansion_tile.dart'; import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class DebugAndroidDirSection extends StatefulWidget { class DebugAndroidDirSection extends StatefulWidget {

View file

@ -2,7 +2,7 @@ import 'dart:collection';
import 'package:aves/services/android_debug_service.dart'; import 'package:aves/services/android_debug_service.dart';
import 'package:aves/widgets/common/identity/aves_expansion_tile.dart'; import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class DebugAndroidEnvironmentSection extends StatefulWidget { class DebugAndroidEnvironmentSection extends StatefulWidget {

View file

@ -10,7 +10,7 @@ import 'package:aves/widgets/debug/firebase.dart';
import 'package:aves/widgets/debug/overlay.dart'; import 'package:aves/widgets/debug/overlay.dart';
import 'package:aves/widgets/debug/settings.dart'; import 'package:aves/widgets/debug/settings.dart';
import 'package:aves/widgets/debug/storage.dart'; import 'package:aves/widgets/debug/storage.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
@ -22,10 +22,10 @@ class AppDebugPage extends StatefulWidget {
const AppDebugPage({this.source}); const AppDebugPage({this.source});
@override @override
State<StatefulWidget> createState() => AppDebugPageState(); State<StatefulWidget> createState() => _AppDebugPageState();
} }
class AppDebugPageState extends State<AppDebugPage> { class _AppDebugPageState extends State<AppDebugPage> {
List<ImageEntry> get entries => widget.source.rawEntries; List<ImageEntry> get entries => widget.source.rawEntries;
static OverlayEntry _taskQueueOverlayEntry; static OverlayEntry _taskQueueOverlayEntry;

View file

@ -1,5 +1,5 @@
import 'package:aves/widgets/common/identity/aves_expansion_tile.dart'; import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:firebase_analytics/firebase_analytics.dart'; import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart';

View file

@ -4,7 +4,7 @@ import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
import 'package:aves/widgets/filter_grids/albums_page.dart'; import 'package:aves/widgets/filter_grids/albums_page.dart';
import 'package:aves/widgets/filter_grids/countries_page.dart'; import 'package:aves/widgets/filter_grids/countries_page.dart';
import 'package:aves/widgets/filter_grids/tags_page.dart'; import 'package:aves/widgets/filter_grids/tags_page.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';

View file

@ -2,7 +2,7 @@ import 'package:aves/services/android_file_service.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/utils/file_utils.dart'; import 'package:aves/utils/file_utils.dart';
import 'package:aves/widgets/common/identity/aves_expansion_tile.dart'; import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class DebugStorageSection extends StatefulWidget { class DebugStorageSection extends StatefulWidget {

View file

@ -12,7 +12,7 @@ import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/widgets/collection/collection_page.dart'; import 'package:aves/widgets/collection/collection_page.dart';
import 'package:aves/widgets/common/behaviour/routes.dart'; import 'package:aves/widgets/common/behaviour/routes.dart';
import 'package:aves/widgets/filter_grids/albums_page.dart'; import 'package:aves/widgets/filter_grids/albums_page.dart';
import 'package:aves/widgets/fullscreen/fullscreen_page.dart'; import 'package:aves/widgets/viewer/entry_viewer_page.dart';
import 'package:aves/widgets/search/search_delegate.dart'; import 'package:aves/widgets/search/search_delegate.dart';
import 'package:aves/widgets/search/search_page.dart'; import 'package:aves/widgets/search/search_page.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart';
@ -121,8 +121,8 @@ class _HomePageState extends State<HomePage> {
Route _getRedirectRoute() { Route _getRedirectRoute() {
if (AvesApp.mode == AppMode.view) { if (AvesApp.mode == AppMode.view) {
return DirectMaterialPageRoute( return DirectMaterialPageRoute(
settings: RouteSettings(name: SingleFullscreenPage.routeName), settings: RouteSettings(name: SingleEntryViewerPage.routeName),
builder: (_) => SingleFullscreenPage(entry: _viewerEntry), builder: (_) => SingleEntryViewerPage(entry: _viewerEntry),
); );
} }

View file

@ -1,7 +1,7 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/image_entry.dart';
import 'package:aves/model/image_metadata.dart'; import 'package:aves/model/image_metadata.dart';
import 'package:aves/model/metadata_db.dart'; import 'package:aves/model/metadata_db.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class DbTab extends StatefulWidget { class DbTab extends StatefulWidget {

View file

@ -6,7 +6,7 @@ import 'package:aves/ref/mime_types.dart';
import 'package:aves/services/android_debug_service.dart'; import 'package:aves/services/android_debug_service.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/identity/aves_expansion_tile.dart'; import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class MetadataTab extends StatefulWidget { class MetadataTab extends StatefulWidget {

View file

@ -3,19 +3,19 @@ import 'package:aves/image_providers/uri_picture_provider.dart';
import 'package:aves/main.dart'; import 'package:aves/main.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/image_entry.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/fullscreen/debug/db.dart'; import 'package:aves/widgets/viewer/debug/db.dart';
import 'package:aves/widgets/fullscreen/debug/metadata.dart'; import 'package:aves/widgets/viewer/debug/metadata.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class FullscreenDebugPage extends StatelessWidget { class ViewerDebugPage extends StatelessWidget {
static const routeName = '/fullscreen/debug'; static const routeName = '/viewer/debug';
final ImageEntry entry; final ImageEntry entry;
const FullscreenDebugPage({@required this.entry}); const ViewerDebugPage({@required this.entry});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -9,9 +9,9 @@ import 'package:aves/widgets/common/action_mixins/feedback.dart';
import 'package:aves/widgets/common/action_mixins/permission_aware.dart'; import 'package:aves/widgets/common/action_mixins/permission_aware.dart';
import 'package:aves/widgets/dialogs/aves_dialog.dart'; import 'package:aves/widgets/dialogs/aves_dialog.dart';
import 'package:aves/widgets/dialogs/rename_entry_dialog.dart'; import 'package:aves/widgets/dialogs/rename_entry_dialog.dart';
import 'package:aves/widgets/fullscreen/fullscreen_debug_page.dart'; import 'package:aves/widgets/viewer/debug_page.dart';
import 'package:aves/widgets/fullscreen/printing.dart'; import 'package:aves/widgets/viewer/printer.dart';
import 'package:aves/widgets/fullscreen/source_viewer_page.dart'; import 'package:aves/widgets/viewer/source_viewer_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -168,8 +168,8 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: RouteSettings(name: FullscreenDebugPage.routeName), settings: RouteSettings(name: ViewerDebugPage.routeName),
builder: (context) => FullscreenDebugPage(entry: entry), builder: (context) => ViewerDebugPage(entry: entry),
), ),
); );
} }

View file

@ -3,13 +3,13 @@ import 'package:aves/model/multipage.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/widgets/common/magnifier/pan/gesture_detector_scope.dart'; import 'package:aves/widgets/common/magnifier/pan/gesture_detector_scope.dart';
import 'package:aves/widgets/common/magnifier/pan/scroll_physics.dart'; import 'package:aves/widgets/common/magnifier/pan/scroll_physics.dart';
import 'package:aves/widgets/fullscreen/image_view.dart'; import 'package:aves/widgets/viewer/multipage.dart';
import 'package:aves/widgets/fullscreen/multipage_controller.dart'; import 'package:aves/widgets/viewer/visual/entry_page_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_ijkplayer/flutter_ijkplayer.dart'; import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class MultiImagePage extends StatefulWidget { class MultiEntryScroller extends StatefulWidget {
final CollectionLens collection; final CollectionLens collection;
final PageController pageController; final PageController pageController;
final ValueChanged<int> onPageChanged; final ValueChanged<int> onPageChanged;
@ -18,7 +18,7 @@ class MultiImagePage extends StatefulWidget {
final List<Tuple2<String, MultiPageController>> multiPageControllers; final List<Tuple2<String, MultiPageController>> multiPageControllers;
final void Function(String uri) onViewDisposed; final void Function(String uri) onViewDisposed;
const MultiImagePage({ const MultiEntryScroller({
this.collection, this.collection,
this.pageController, this.pageController,
this.onPageChanged, this.onPageChanged,
@ -29,10 +29,10 @@ class MultiImagePage extends StatefulWidget {
}); });
@override @override
State<StatefulWidget> createState() => MultiImagePageState(); State<StatefulWidget> createState() => _MultiEntryScrollerState();
} }
class MultiImagePageState extends State<MultiImagePage> with AutomaticKeepAliveClientMixin { class _MultiEntryScrollerState extends State<MultiEntryScroller> with AutomaticKeepAliveClientMixin {
List<ImageEntry> get entries => widget.collection.sortedEntries; List<ImageEntry> get entries => widget.collection.sortedEntries;
@override @override
@ -79,8 +79,8 @@ class MultiImagePageState extends State<MultiImagePage> with AutomaticKeepAliveC
); );
} }
ImageView _buildViewer(ImageEntry entry, {MultiPageInfo multiPageInfo, int page = 0}) { EntryPageView _buildViewer(ImageEntry entry, {MultiPageInfo multiPageInfo, int page = 0}) {
return ImageView( return EntryPageView(
key: Key('imageview'), key: Key('imageview'),
entry: entry, entry: entry,
multiPageInfo: multiPageInfo, multiPageInfo: multiPageInfo,
@ -100,13 +100,13 @@ class MultiImagePageState extends State<MultiImagePage> with AutomaticKeepAliveC
bool get wantKeepAlive => true; bool get wantKeepAlive => true;
} }
class SingleImagePage extends StatefulWidget { class SingleEntryScroller extends StatefulWidget {
final ImageEntry entry; final ImageEntry entry;
final VoidCallback onTap; final VoidCallback onTap;
final List<Tuple2<String, IjkMediaController>> videoControllers; final List<Tuple2<String, IjkMediaController>> videoControllers;
final List<Tuple2<String, MultiPageController>> multiPageControllers; final List<Tuple2<String, MultiPageController>> multiPageControllers;
const SingleImagePage({ const SingleEntryScroller({
this.entry, this.entry,
this.onTap, this.onTap,
this.videoControllers, this.videoControllers,
@ -114,10 +114,10 @@ class SingleImagePage extends StatefulWidget {
}); });
@override @override
State<StatefulWidget> createState() => SingleImagePageState(); State<StatefulWidget> createState() => _SingleEntryScrollerState();
} }
class SingleImagePageState extends State<SingleImagePage> with AutomaticKeepAliveClientMixin { class _SingleEntryScrollerState extends State<SingleEntryScroller> with AutomaticKeepAliveClientMixin {
ImageEntry get entry => widget.entry; ImageEntry get entry => widget.entry;
@override @override
@ -150,8 +150,8 @@ class SingleImagePageState extends State<SingleImagePage> with AutomaticKeepAliv
); );
} }
ImageView _buildViewer({MultiPageInfo multiPageInfo, int page = 0}) { EntryPageView _buildViewer({MultiPageInfo multiPageInfo, int page = 0}) {
return ImageView( return EntryPageView(
entry: entry, entry: entry,
multiPageInfo: multiPageInfo, multiPageInfo: multiPageInfo,
page: page, page: page,

View file

@ -1,16 +1,16 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/image_entry.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/widgets/common/providers/media_query_data_provider.dart'; import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
import 'package:aves/widgets/fullscreen/fullscreen_body.dart'; import 'package:aves/widgets/viewer/entry_viewer_stack.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class MultiFullscreenPage extends AnimatedWidget { class MultiEntryViewerPage extends AnimatedWidget {
static const routeName = '/fullscreen'; static const routeName = '/viewer';
final CollectionLens collection; final CollectionLens collection;
final ImageEntry initialEntry; final ImageEntry initialEntry;
const MultiFullscreenPage({ const MultiEntryViewerPage({
Key key, Key key,
this.collection, this.collection,
this.initialEntry, this.initialEntry,
@ -20,7 +20,7 @@ class MultiFullscreenPage extends AnimatedWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MediaQueryDataProvider( return MediaQueryDataProvider(
child: Scaffold( child: Scaffold(
body: FullscreenBody( body: EntryViewerStack(
collection: collection, collection: collection,
initialEntry: initialEntry, initialEntry: initialEntry,
), ),
@ -31,12 +31,12 @@ class MultiFullscreenPage extends AnimatedWidget {
} }
} }
class SingleFullscreenPage extends StatelessWidget { class SingleEntryViewerPage extends StatelessWidget {
static const routeName = '/fullscreen'; static const routeName = '/viewer';
final ImageEntry entry; final ImageEntry entry;
const SingleFullscreenPage({ const SingleEntryViewerPage({
Key key, Key key,
this.entry, this.entry,
}) : super(key: key); }) : super(key: key);
@ -45,7 +45,7 @@ class SingleFullscreenPage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MediaQueryDataProvider( return MediaQueryDataProvider(
child: Scaffold( child: Scaffold(
body: FullscreenBody( body: EntryViewerStack(
initialEntry: entry, initialEntry: entry,
), ),
backgroundColor: Navigator.canPop(context) ? Colors.transparent : Colors.black, backgroundColor: Navigator.canPop(context) ? Colors.transparent : Colors.black,

View file

@ -9,16 +9,16 @@ import 'package:aves/theme/durations.dart';
import 'package:aves/utils/change_notifier.dart'; import 'package:aves/utils/change_notifier.dart';
import 'package:aves/widgets/collection/collection_page.dart'; import 'package:aves/widgets/collection/collection_page.dart';
import 'package:aves/widgets/common/magnifier/pan/scroll_physics.dart'; import 'package:aves/widgets/common/magnifier/pan/scroll_physics.dart';
import 'package:aves/widgets/fullscreen/entry_action_delegate.dart'; import 'package:aves/widgets/viewer/entry_action_delegate.dart';
import 'package:aves/widgets/fullscreen/image_page.dart'; import 'package:aves/widgets/viewer/entry_scroller.dart';
import 'package:aves/widgets/fullscreen/image_view.dart'; import 'package:aves/widgets/viewer/info/info_page.dart';
import 'package:aves/widgets/fullscreen/info/info_page.dart'; import 'package:aves/widgets/viewer/info/notifications.dart';
import 'package:aves/widgets/fullscreen/info/notifications.dart'; import 'package:aves/widgets/viewer/multipage.dart';
import 'package:aves/widgets/fullscreen/multipage_controller.dart'; import 'package:aves/widgets/viewer/overlay/bottom.dart';
import 'package:aves/widgets/fullscreen/overlay/bottom.dart'; import 'package:aves/widgets/viewer/overlay/panorama.dart';
import 'package:aves/widgets/fullscreen/overlay/panorama.dart'; import 'package:aves/widgets/viewer/overlay/top.dart';
import 'package:aves/widgets/fullscreen/overlay/top.dart'; import 'package:aves/widgets/viewer/overlay/video.dart';
import 'package:aves/widgets/fullscreen/overlay/video.dart'; import 'package:aves/widgets/viewer/visual/state.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
@ -28,21 +28,21 @@ import 'package:provider/provider.dart';
import 'package:screen/screen.dart'; import 'package:screen/screen.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class FullscreenBody extends StatefulWidget { class EntryViewerStack extends StatefulWidget {
final CollectionLens collection; final CollectionLens collection;
final ImageEntry initialEntry; final ImageEntry initialEntry;
const FullscreenBody({ const EntryViewerStack({
Key key, Key key,
this.collection, this.collection,
this.initialEntry, this.initialEntry,
}) : super(key: key); }) : super(key: key);
@override @override
FullscreenBodyState createState() => FullscreenBodyState(); _EntryViewerStackState createState() => _EntryViewerStackState();
} }
class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProviderStateMixin, WidgetsBindingObserver { class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerProviderStateMixin, WidgetsBindingObserver {
final ValueNotifier<ImageEntry> _entryNotifier = ValueNotifier(null); final ValueNotifier<ImageEntry> _entryNotifier = ValueNotifier(null);
int _currentHorizontalPage; int _currentHorizontalPage;
ValueNotifier<int> _currentVerticalPage; ValueNotifier<int> _currentVerticalPage;
@ -106,13 +106,13 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
_registerWidget(widget); _registerWidget(widget);
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
WidgetsBinding.instance.addPostFrameCallback((_) => _initOverlay()); WidgetsBinding.instance.addPostFrameCallback((_) => _initOverlay());
if (settings.keepScreenOn == KeepScreenOn.fullscreenOnly) { if (settings.keepScreenOn == KeepScreenOn.viewerOnly) {
Screen.keepOn(true); Screen.keepOn(true);
} }
} }
@override @override
void didUpdateWidget(covariant FullscreenBody oldWidget) { void didUpdateWidget(covariant EntryViewerStack oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
_unregisterWidget(oldWidget); _unregisterWidget(oldWidget);
_registerWidget(widget); _registerWidget(widget);
@ -132,11 +132,11 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
super.dispose(); super.dispose();
} }
void _registerWidget(FullscreenBody widget) { void _registerWidget(EntryViewerStack widget) {
widget.collection?.addListener(_onCollectionChange); widget.collection?.addListener(_onCollectionChange);
} }
void _unregisterWidget(FullscreenBody widget) { void _unregisterWidget(EntryViewerStack widget) {
widget.collection?.removeListener(_onCollectionChange); widget.collection?.removeListener(_onCollectionChange);
} }
@ -170,7 +170,7 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
}, },
child: Stack( child: Stack(
children: [ children: [
FullscreenVerticalPageView( ViewerVerticalPageView(
collection: collection, collection: collection,
entryNotifier: _entryNotifier, entryNotifier: _entryNotifier,
videoControllers: _videoControllers, videoControllers: _videoControllers,
@ -205,7 +205,7 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
final multiPageController = _getMultiPageController(entry); final multiPageController = _getMultiPageController(entry);
final viewStateNotifier = _viewStateNotifiers.firstWhere((kv) => kv.item1 == entry.uri, orElse: () => null)?.item2; final viewStateNotifier = _viewStateNotifiers.firstWhere((kv) => kv.item1 == entry.uri, orElse: () => null)?.item2;
return FullscreenTopOverlay( return ViewerTopOverlay(
entry: entry, entry: entry,
scale: _topOverlayScale, scale: _topOverlayScale,
canToggleFavourite: hasCollection, canToggleFavourite: hasCollection,
@ -264,7 +264,7 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
), ),
SlideTransition( SlideTransition(
position: _bottomOverlayOffset, position: _bottomOverlayOffset,
child: FullscreenBottomOverlay( child: ViewerBottomOverlay(
entries: entries, entries: entries,
index: _currentHorizontalPage, index: _currentHorizontalPage,
showPosition: hasCollection, showPosition: hasCollection,
@ -372,11 +372,11 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
void _onLeave() { void _onLeave() {
if (Navigator.canPop(context)) { if (Navigator.canPop(context)) {
_showSystemUI(); _showSystemUI();
if (settings.keepScreenOn == KeepScreenOn.fullscreenOnly) { if (settings.keepScreenOn == KeepScreenOn.viewerOnly) {
Screen.keepOn(false); Screen.keepOn(false);
} }
} else { } else {
// exit app when trying to pop a fullscreen page that is a viewer for a single entry // exit app when trying to pop a viewer page for a single entry
SystemNavigator.pop(); SystemNavigator.pop();
} }
} }
@ -472,7 +472,7 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
void _pauseVideoControllers() => _videoControllers.forEach((e) => e.item2.pause()); void _pauseVideoControllers() => _videoControllers.forEach((e) => e.item2.pause());
} }
class FullscreenVerticalPageView extends StatefulWidget { class ViewerVerticalPageView extends StatefulWidget {
final CollectionLens collection; final CollectionLens collection;
final ValueNotifier<ImageEntry> entryNotifier; final ValueNotifier<ImageEntry> entryNotifier;
final List<Tuple2<String, IjkMediaController>> videoControllers; final List<Tuple2<String, IjkMediaController>> videoControllers;
@ -482,7 +482,7 @@ class FullscreenVerticalPageView extends StatefulWidget {
final VoidCallback onImageTap, onImagePageRequested; final VoidCallback onImageTap, onImagePageRequested;
final void Function(String uri) onViewDisposed; final void Function(String uri) onViewDisposed;
const FullscreenVerticalPageView({ const ViewerVerticalPageView({
@required this.collection, @required this.collection,
@required this.entryNotifier, @required this.entryNotifier,
@required this.videoControllers, @required this.videoControllers,
@ -497,10 +497,10 @@ class FullscreenVerticalPageView extends StatefulWidget {
}); });
@override @override
_FullscreenVerticalPageViewState createState() => _FullscreenVerticalPageViewState(); _ViewerVerticalPageViewState createState() => _ViewerVerticalPageViewState();
} }
class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView> { class _ViewerVerticalPageViewState extends State<ViewerVerticalPageView> {
final ValueNotifier<Color> _backgroundColorNotifier = ValueNotifier(Colors.black); final ValueNotifier<Color> _backgroundColorNotifier = ValueNotifier(Colors.black);
final ValueNotifier<bool> _infoPageVisibleNotifier = ValueNotifier(false); final ValueNotifier<bool> _infoPageVisibleNotifier = ValueNotifier(false);
ImageEntry _oldEntry; ImageEntry _oldEntry;
@ -518,7 +518,7 @@ class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView>
} }
@override @override
void didUpdateWidget(covariant FullscreenVerticalPageView oldWidget) { void didUpdateWidget(covariant ViewerVerticalPageView oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
_unregisterWidget(oldWidget); _unregisterWidget(oldWidget);
_registerWidget(widget); _registerWidget(widget);
@ -530,13 +530,13 @@ class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView>
super.dispose(); super.dispose();
} }
void _registerWidget(FullscreenVerticalPageView widget) { void _registerWidget(ViewerVerticalPageView widget) {
widget.verticalPager.addListener(_onVerticalPageControllerChanged); widget.verticalPager.addListener(_onVerticalPageControllerChanged);
widget.entryNotifier.addListener(_onEntryChanged); widget.entryNotifier.addListener(_onEntryChanged);
if (_oldEntry != entry) _onEntryChanged(); if (_oldEntry != entry) _onEntryChanged();
} }
void _unregisterWidget(FullscreenVerticalPageView widget) { void _unregisterWidget(ViewerVerticalPageView widget) {
widget.verticalPager.removeListener(_onVerticalPageControllerChanged); widget.verticalPager.removeListener(_onVerticalPageControllerChanged);
widget.entryNotifier.removeListener(_onEntryChanged); widget.entryNotifier.removeListener(_onEntryChanged);
_oldEntry?.imageChangeNotifier?.removeListener(_onImageChanged); _oldEntry?.imageChangeNotifier?.removeListener(_onImageChanged);
@ -545,10 +545,10 @@ class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final pages = [ final pages = [
// fake page for opacity transition between collection and fullscreen views // fake page for opacity transition between collection and viewer
SizedBox(), SizedBox(),
hasCollection hasCollection
? MultiImagePage( ? MultiEntryScroller(
collection: collection, collection: collection,
pageController: widget.horizontalPager, pageController: widget.horizontalPager,
onTap: widget.onImageTap, onTap: widget.onImageTap,
@ -557,7 +557,7 @@ class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView>
multiPageControllers: widget.multiPageControllers, multiPageControllers: widget.multiPageControllers,
onViewDisposed: widget.onViewDisposed, onViewDisposed: widget.onViewDisposed,
) )
: SingleImagePage( : SingleEntryScroller(
entry: entry, entry: entry,
onTap: widget.onImageTap, onTap: widget.onImageTap,
videoControllers: widget.videoControllers, videoControllers: widget.videoControllers,

View file

@ -9,7 +9,7 @@ import 'package:aves/ref/mime_types.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/constants.dart';
import 'package:aves/utils/file_utils.dart'; import 'package:aves/utils/file_utils.dart';
import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';

View file

@ -1,8 +1,8 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/image_entry.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/app_bar_title.dart'; import 'package:aves/widgets/common/app_bar_title.dart';
import 'package:aves/widgets/fullscreen/info/info_search.dart'; import 'package:aves/widgets/viewer/info/info_search.dart';
import 'package:aves/widgets/fullscreen/info/metadata/metadata_section.dart'; import 'package:aves/widgets/viewer/info/metadata/metadata_section.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class InfoAppBar extends StatelessWidget { class InfoAppBar extends StatelessWidget {

View file

@ -3,11 +3,11 @@ import 'package:aves/model/image_entry.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/widgets/common/providers/media_query_data_provider.dart'; import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
import 'package:aves/widgets/fullscreen/info/basic_section.dart'; import 'package:aves/widgets/viewer/info/basic_section.dart';
import 'package:aves/widgets/fullscreen/info/info_app_bar.dart'; import 'package:aves/widgets/viewer/info/info_app_bar.dart';
import 'package:aves/widgets/fullscreen/info/location_section.dart'; import 'package:aves/widgets/viewer/info/location_section.dart';
import 'package:aves/widgets/fullscreen/info/metadata/metadata_section.dart'; import 'package:aves/widgets/viewer/info/metadata/metadata_section.dart';
import 'package:aves/widgets/fullscreen/info/notifications.dart'; import 'package:aves/widgets/viewer/info/notifications.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
@ -25,10 +25,10 @@ class InfoPage extends StatefulWidget {
}) : super(key: key); }) : super(key: key);
@override @override
State<StatefulWidget> createState() => InfoPageState(); State<StatefulWidget> createState() => _InfoPageState();
} }
class InfoPageState extends State<InfoPage> { class _InfoPageState extends State<InfoPage> {
final ScrollController _scrollController = ScrollController(); final ScrollController _scrollController = ScrollController();
bool _scrollStartFromTop = false; bool _scrollStartFromTop = false;

View file

@ -1,8 +1,8 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/image_entry.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/collection/empty.dart'; import 'package:aves/widgets/collection/empty.dart';
import 'package:aves/widgets/fullscreen/info/metadata/metadata_dir_tile.dart'; import 'package:aves/widgets/viewer/info/metadata/metadata_dir_tile.dart';
import 'package:aves/widgets/fullscreen/info/metadata/metadata_section.dart'; import 'package:aves/widgets/viewer/info/metadata/metadata_section.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View file

@ -6,11 +6,11 @@ import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:aves/widgets/fullscreen/info/maps/common.dart'; import 'package:aves/widgets/viewer/info/maps/common.dart';
import 'package:aves/widgets/fullscreen/info/maps/google_map.dart'; import 'package:aves/widgets/viewer/info/maps/google_map.dart';
import 'package:aves/widgets/fullscreen/info/maps/leaflet_map.dart'; import 'package:aves/widgets/viewer/info/maps/leaflet_map.dart';
import 'package:aves/widgets/fullscreen/info/maps/marker.dart'; import 'package:aves/widgets/viewer/info/maps/marker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';

View file

@ -6,8 +6,8 @@ import 'package:aves/widgets/common/fx/blurred.dart';
import 'package:aves/widgets/common/fx/borders.dart'; import 'package:aves/widgets/common/fx/borders.dart';
import 'package:aves/widgets/dialogs/aves_dialog.dart'; import 'package:aves/widgets/dialogs/aves_dialog.dart';
import 'package:aves/widgets/dialogs/aves_selection_dialog.dart'; import 'package:aves/widgets/dialogs/aves_selection_dialog.dart';
import 'package:aves/widgets/fullscreen/info/location_section.dart'; import 'package:aves/widgets/viewer/info/location_section.dart';
import 'package:aves/widgets/fullscreen/overlay/common.dart'; import 'package:aves/widgets/viewer/overlay/common.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';

View file

@ -2,9 +2,9 @@ import 'dart:async';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/widgets/fullscreen/info/location_section.dart'; import 'package:aves/widgets/viewer/info/location_section.dart';
import 'package:aves/widgets/fullscreen/info/maps/common.dart'; import 'package:aves/widgets/viewer/info/maps/common.dart';
import 'package:aves/widgets/fullscreen/info/maps/marker.dart'; import 'package:aves/widgets/viewer/info/maps/marker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
@ -27,10 +27,10 @@ class EntryGoogleMap extends StatefulWidget {
super(key: key); super(key: key);
@override @override
State<StatefulWidget> createState() => EntryGoogleMapState(); State<StatefulWidget> createState() => _EntryGoogleMapState();
} }
class EntryGoogleMapState extends State<EntryGoogleMap> with AutomaticKeepAliveClientMixin { class _EntryGoogleMapState extends State<EntryGoogleMap> with AutomaticKeepAliveClientMixin {
GoogleMapController _controller; GoogleMapController _controller;
Completer<Uint8List> _markerLoaderCompleter; Completer<Uint8List> _markerLoaderCompleter;

View file

@ -1,6 +1,6 @@
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/widgets/fullscreen/info/maps/common.dart'; import 'package:aves/widgets/viewer/info/maps/common.dart';
import 'package:aves/widgets/fullscreen/info/maps/scale_layer.dart'; import 'package:aves/widgets/viewer/info/maps/scale_layer.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:flutter_markdown/flutter_markdown.dart';
@ -28,10 +28,10 @@ class EntryLeafletMap extends StatefulWidget {
}) : super(key: key); }) : super(key: key);
@override @override
State<StatefulWidget> createState() => EntryLeafletMapState(); State<StatefulWidget> createState() => _EntryLeafletMapState();
} }
class EntryLeafletMapState extends State<EntryLeafletMap> with AutomaticKeepAliveClientMixin, TickerProviderStateMixin { class _EntryLeafletMapState extends State<EntryLeafletMap> with AutomaticKeepAliveClientMixin, TickerProviderStateMixin {
final MapController _mapController = MapController(); final MapController _mapController = MapController();
@override @override

View file

@ -7,11 +7,11 @@ import 'package:aves/theme/icons.dart';
import 'package:aves/utils/color_utils.dart'; import 'package:aves/utils/color_utils.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/identity/aves_expansion_tile.dart'; import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:aves/widgets/fullscreen/info/metadata/metadata_section.dart'; import 'package:aves/widgets/viewer/info/metadata/metadata_section.dart';
import 'package:aves/widgets/fullscreen/info/metadata/metadata_thumbnail.dart'; import 'package:aves/widgets/viewer/info/metadata/metadata_thumbnail.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_tile.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_tile.dart';
import 'package:aves/widgets/fullscreen/source_viewer_page.dart'; import 'package:aves/widgets/viewer/source_viewer_page.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View file

@ -5,8 +5,8 @@ import 'package:aves/services/metadata_service.dart';
import 'package:aves/services/svg_metadata_service.dart'; import 'package:aves/services/svg_metadata_service.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:aves/widgets/fullscreen/info/metadata/metadata_dir_tile.dart'; import 'package:aves/widgets/viewer/info/metadata/metadata_dir_tile.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View file

@ -3,7 +3,7 @@ import 'package:aves/ref/xmp.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/constants.dart';
import 'package:aves/utils/string_utils.dart'; import 'package:aves/utils/string_utils.dart';
import 'package:aves/widgets/common/identity/highlight_title.dart'; import 'package:aves/widgets/common/identity/highlight_title.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View file

@ -1,5 +1,5 @@
import 'package:aves/ref/exif.dart'; import 'package:aves/ref/exif.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_namespaces.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
// cf https://github.com/adobe/xmp-docs/blob/master/XMPNamespaces/exif.md // cf https://github.com/adobe/xmp-docs/blob/master/XMPNamespaces/exif.md
class XmpExifNamespace extends XmpNamespace { class XmpExifNamespace extends XmpNamespace {

View file

@ -1,5 +1,5 @@
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_namespaces.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
abstract class XmpGoogleNamespace extends XmpNamespace { abstract class XmpGoogleNamespace extends XmpNamespace {

View file

@ -1,5 +1,5 @@
import 'package:aves/widgets/fullscreen/info/metadata/xmp_namespaces.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_structs.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_structs.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class XmpIptcCoreNamespace extends XmpNamespace { class XmpIptcCoreNamespace extends XmpNamespace {

View file

@ -1,6 +1,6 @@
// cf photoshop:ColorMode // cf photoshop:ColorMode
// cf https://github.com/adobe/xmp-docs/blob/master/XMPNamespaces/photoshop.md // cf https://github.com/adobe/xmp-docs/blob/master/XMPNamespaces/photoshop.md
import 'package:aves/widgets/fullscreen/info/metadata/xmp_namespaces.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
class XmpPhotoshopNamespace extends XmpNamespace { class XmpPhotoshopNamespace extends XmpNamespace {
static const ns = 'photoshop'; static const ns = 'photoshop';

View file

@ -1,5 +1,5 @@
import 'package:aves/ref/exif.dart'; import 'package:aves/ref/exif.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_namespaces.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
// cf https://github.com/adobe/xmp-docs/blob/master/XMPNamespaces/tiff.md // cf https://github.com/adobe/xmp-docs/blob/master/XMPNamespaces/tiff.md
class XmpTiffNamespace extends XmpNamespace { class XmpTiffNamespace extends XmpNamespace {

View file

@ -1,7 +1,7 @@
import 'package:aves/ref/mime_types.dart'; import 'package:aves/ref/mime_types.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_namespaces.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_structs.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_structs.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class XmpBasicNamespace extends XmpNamespace { class XmpBasicNamespace extends XmpNamespace {

View file

@ -5,7 +5,7 @@ import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/basic/multi_cross_fader.dart'; import 'package:aves/widgets/common/basic/multi_cross_fader.dart';
import 'package:aves/widgets/common/identity/highlight_title.dart'; import 'package:aves/widgets/common/identity/highlight_title.dart';
import 'package:aves/widgets/fullscreen/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class XmpStructArrayCard extends StatefulWidget { class XmpStructArrayCard extends StatefulWidget {

View file

@ -9,14 +9,14 @@ import 'package:aves/widgets/common/action_mixins/feedback.dart';
import 'package:aves/widgets/common/behaviour/routes.dart'; import 'package:aves/widgets/common/behaviour/routes.dart';
import 'package:aves/widgets/common/identity/aves_expansion_tile.dart'; import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
import 'package:aves/widgets/dialogs/aves_dialog.dart'; import 'package:aves/widgets/dialogs/aves_dialog.dart';
import 'package:aves/widgets/fullscreen/fullscreen_page.dart'; import 'package:aves/widgets/viewer/entry_viewer_page.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_namespaces.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_ns/exif.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_ns/exif.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_ns/google.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_ns/google.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_ns/iptc.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_ns/iptc.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_ns/photoshop.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_ns/photoshop.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_ns/tiff.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_ns/tiff.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_ns/xmp.dart'; import 'package:aves/widgets/viewer/info/metadata/xmp_ns/xmp.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pedantic/pedantic.dart'; import 'package:pedantic/pedantic.dart';
@ -127,8 +127,8 @@ class _XmpDirTileState extends State<XmpDirTile> with FeedbackMixin {
unawaited(Navigator.push( unawaited(Navigator.push(
context, context,
TransparentMaterialPageRoute( TransparentMaterialPageRoute(
settings: RouteSettings(name: SingleFullscreenPage.routeName), settings: RouteSettings(name: SingleEntryViewerPage.routeName),
pageBuilder: (c, a, sa) => SingleFullscreenPage(entry: embedEntry), pageBuilder: (c, a, sa) => SingleEntryViewerPage(entry: embedEntry),
), ),
)); ));
} }

View file

@ -10,23 +10,23 @@ import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/fx/blurred.dart'; import 'package:aves/widgets/common/fx/blurred.dart';
import 'package:aves/widgets/fullscreen/multipage_controller.dart'; import 'package:aves/widgets/viewer/multipage.dart';
import 'package:aves/widgets/fullscreen/overlay/common.dart'; import 'package:aves/widgets/viewer/overlay/common.dart';
import 'package:aves/widgets/fullscreen/overlay/multipage.dart'; import 'package:aves/widgets/viewer/overlay/multipage.dart';
import 'package:decorated_icon/decorated_icon.dart'; import 'package:decorated_icon/decorated_icon.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class FullscreenBottomOverlay extends StatefulWidget { class ViewerBottomOverlay extends StatefulWidget {
final List<ImageEntry> entries; final List<ImageEntry> entries;
final int index; final int index;
final bool showPosition; final bool showPosition;
final EdgeInsets viewInsets, viewPadding; final EdgeInsets viewInsets, viewPadding;
final MultiPageController multiPageController; final MultiPageController multiPageController;
const FullscreenBottomOverlay({ const ViewerBottomOverlay({
Key key, Key key,
@required this.entries, @required this.entries,
@required this.index, @required this.index,
@ -37,10 +37,10 @@ class FullscreenBottomOverlay extends StatefulWidget {
}) : super(key: key); }) : super(key: key);
@override @override
State<StatefulWidget> createState() => _FullscreenBottomOverlayState(); State<StatefulWidget> createState() => _ViewerBottomOverlayState();
} }
class _FullscreenBottomOverlayState extends State<FullscreenBottomOverlay> { class _ViewerBottomOverlayState extends State<ViewerBottomOverlay> {
Future<OverlayMetadata> _detailLoader; Future<OverlayMetadata> _detailLoader;
ImageEntry _lastEntry; ImageEntry _lastEntry;
OverlayMetadata _lastDetails; OverlayMetadata _lastDetails;
@ -58,7 +58,7 @@ class _FullscreenBottomOverlayState extends State<FullscreenBottomOverlay> {
} }
@override @override
void didUpdateWidget(covariant FullscreenBottomOverlay oldWidget) { void didUpdateWidget(covariant ViewerBottomOverlay oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
if (entry != _lastEntry) { if (entry != _lastEntry) {
_initDetailLoader(); _initDetailLoader();

View file

@ -2,8 +2,8 @@ import 'dart:math';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/image_entry.dart';
import 'package:aves/model/multipage.dart'; import 'package:aves/model/multipage.dart';
import 'package:aves/widgets/fullscreen/image_view.dart'; import 'package:aves/widgets/viewer/multipage.dart';
import 'package:aves/widgets/fullscreen/multipage_controller.dart'; import 'package:aves/widgets/viewer/visual/state.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View file

@ -4,7 +4,7 @@ import 'package:aves/model/image_entry.dart';
import 'package:aves/model/multipage.dart'; import 'package:aves/model/multipage.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/widgets/collection/thumbnail/raster.dart'; import 'package:aves/widgets/collection/thumbnail/raster.dart';
import 'package:aves/widgets/fullscreen/multipage_controller.dart'; import 'package:aves/widgets/viewer/multipage.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View file

@ -1,6 +1,6 @@
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/image_entry.dart';
import 'package:aves/widgets/fullscreen/overlay/common.dart'; import 'package:aves/widgets/viewer/overlay/common.dart';
import 'package:aves/widgets/fullscreen/panorama_page.dart'; import 'package:aves/widgets/viewer/panorama_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class PanoramaOverlay extends StatelessWidget { class PanoramaOverlay extends StatelessWidget {

View file

@ -8,17 +8,17 @@ import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/basic/menu_row.dart'; import 'package:aves/widgets/common/basic/menu_row.dart';
import 'package:aves/widgets/common/fx/sweeper.dart'; import 'package:aves/widgets/common/fx/sweeper.dart';
import 'package:aves/widgets/fullscreen/image_view.dart'; import 'package:aves/widgets/viewer/multipage.dart';
import 'package:aves/widgets/fullscreen/multipage_controller.dart'; import 'package:aves/widgets/viewer/overlay/common.dart';
import 'package:aves/widgets/fullscreen/overlay/common.dart'; import 'package:aves/widgets/viewer/overlay/minimap.dart';
import 'package:aves/widgets/fullscreen/overlay/minimap.dart'; import 'package:aves/widgets/viewer/visual/state.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class FullscreenTopOverlay extends StatelessWidget { class ViewerTopOverlay extends StatelessWidget {
final ImageEntry entry; final ImageEntry entry;
final Animation<double> scale; final Animation<double> scale;
final EdgeInsets viewInsets, viewPadding; final EdgeInsets viewInsets, viewPadding;
@ -33,7 +33,7 @@ class FullscreenTopOverlay extends StatelessWidget {
static const int portraitActionCount = 2; static const int portraitActionCount = 2;
const FullscreenTopOverlay({ const ViewerTopOverlay({
Key key, Key key,
@required this.entry, @required this.entry,
@required this.scale, @required this.scale,

View file

@ -7,7 +7,7 @@ import 'package:aves/theme/icons.dart';
import 'package:aves/utils/time_utils.dart'; import 'package:aves/utils/time_utils.dart';
import 'package:aves/widgets/common/fx/blurred.dart'; import 'package:aves/widgets/common/fx/blurred.dart';
import 'package:aves/widgets/common/fx/borders.dart'; import 'package:aves/widgets/common/fx/borders.dart';
import 'package:aves/widgets/fullscreen/overlay/common.dart'; import 'package:aves/widgets/viewer/overlay/common.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_ijkplayer/flutter_ijkplayer.dart'; import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
@ -24,10 +24,10 @@ class VideoControlOverlay extends StatefulWidget {
}) : super(key: key); }) : super(key: key);
@override @override
State<StatefulWidget> createState() => VideoControlOverlayState(); State<StatefulWidget> createState() => _VideoControlOverlayState();
} }
class VideoControlOverlayState extends State<VideoControlOverlay> with SingleTickerProviderStateMixin { class _VideoControlOverlayState extends State<VideoControlOverlay> with SingleTickerProviderStateMixin {
final GlobalKey _progressBarKey = GlobalKey(); final GlobalKey _progressBarKey = GlobalKey();
bool _playingOnDragStart = false; bool _playingOnDragStart = false;
AnimationController _playPauseAnimation; AnimationController _playPauseAnimation;

View file

@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
import 'package:panorama/panorama.dart'; import 'package:panorama/panorama.dart';
class PanoramaPage extends StatelessWidget { class PanoramaPage extends StatelessWidget {
static const routeName = '/fullscreen/panorama'; static const routeName = '/viewer/panorama';
final ImageEntry entry; final ImageEntry entry;

View file

@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_highlight/themes/darcula.dart'; import 'package:flutter_highlight/themes/darcula.dart';
class SourceViewerPage extends StatefulWidget { class SourceViewerPage extends StatefulWidget {
static const routeName = '/fullscreen/source'; static const routeName = '/viewer/source';
final Future<String> Function() loader; final Future<String> Function() loader;

View file

@ -5,24 +5,24 @@ import 'package:aves/model/image_entry.dart';
import 'package:aves/model/multipage.dart'; import 'package:aves/model/multipage.dart';
import 'package:aves/model/settings/entry_background.dart'; import 'package:aves/model/settings/entry_background.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/collection/empty.dart';
import 'package:aves/widgets/common/fx/checkered_decoration.dart';
import 'package:aves/widgets/common/magnifier/controller/controller.dart'; import 'package:aves/widgets/common/magnifier/controller/controller.dart';
import 'package:aves/widgets/common/magnifier/controller/state.dart'; import 'package:aves/widgets/common/magnifier/controller/state.dart';
import 'package:aves/widgets/common/magnifier/magnifier.dart'; import 'package:aves/widgets/common/magnifier/magnifier.dart';
import 'package:aves/widgets/common/magnifier/scale/scale_boundaries.dart'; import 'package:aves/widgets/common/magnifier/scale/scale_boundaries.dart';
import 'package:aves/widgets/common/magnifier/scale/scale_level.dart'; import 'package:aves/widgets/common/magnifier/scale/scale_level.dart';
import 'package:aves/widgets/common/magnifier/scale/state.dart'; import 'package:aves/widgets/common/magnifier/scale/state.dart';
import 'package:aves/widgets/fullscreen/tiled_view.dart'; import 'package:aves/widgets/viewer/visual/error.dart';
import 'package:aves/widgets/fullscreen/video_view.dart'; import 'package:aves/widgets/viewer/visual/raster.dart';
import 'package:aves/widgets/viewer/visual/state.dart';
import 'package:aves/widgets/viewer/visual/vector.dart';
import 'package:aves/widgets/viewer/visual/video.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_ijkplayer/flutter_ijkplayer.dart'; import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class ImageView extends StatefulWidget { class EntryPageView extends StatefulWidget {
final ImageEntry entry; final ImageEntry entry;
final MultiPageInfo multiPageInfo; final MultiPageInfo multiPageInfo;
final int page; final int page;
@ -32,8 +32,11 @@ class ImageView extends StatefulWidget {
final VoidCallback onDisposed; final VoidCallback onDisposed;
static const decorationCheckSize = 20.0; static const decorationCheckSize = 20.0;
static const initialScale = ScaleLevel(ref: ScaleReference.contained);
static const minScale = ScaleLevel(ref: ScaleReference.contained);
static const maxScale = ScaleLevel(factor: 2.0);
const ImageView({ const EntryPageView({
Key key, Key key,
@required this.entry, @required this.entry,
this.multiPageInfo, this.multiPageInfo,
@ -45,18 +48,14 @@ class ImageView extends StatefulWidget {
}) : super(key: key); }) : super(key: key);
@override @override
_ImageViewState createState() => _ImageViewState(); _EntryPageViewState createState() => _EntryPageViewState();
} }
class _ImageViewState extends State<ImageView> { class _EntryPageViewState extends State<EntryPageView> {
final MagnifierController _magnifierController = MagnifierController(); final MagnifierController _magnifierController = MagnifierController();
final ValueNotifier<ViewState> _viewStateNotifier = ValueNotifier(ViewState.zero); final ValueNotifier<ViewState> _viewStateNotifier = ValueNotifier(ViewState.zero);
final List<StreamSubscription> _subscriptions = []; final List<StreamSubscription> _subscriptions = [];
static const initialScale = ScaleLevel(ref: ScaleReference.contained);
static const minScale = ScaleLevel(ref: ScaleReference.contained);
static const maxScale = ScaleLevel(factor: 2.0);
ImageEntry get entry => widget.entry; ImageEntry get entry => widget.entry;
MultiPageInfo get multiPageInfo => widget.multiPageInfo; MultiPageInfo get multiPageInfo => widget.multiPageInfo;
@ -95,7 +94,7 @@ class _ImageViewState extends State<ImageView> {
} else if (entry.canDecode) { } else if (entry.canDecode) {
child = _buildRasterView(); child = _buildRasterView();
} }
child ??= ErrorChild(onTap: () => onTap?.call(null)); child ??= ErrorView(onTap: () => onTap?.call(null));
// no hero for videos, as a typical video first frame is different from its thumbnail // no hero for videos, as a typical video first frame is different from its thumbnail
return widget.heroTag != null && !entry.isVideo return widget.heroTag != null && !entry.isVideo
@ -116,13 +115,13 @@ class _ImageViewState extends State<ImageView> {
multiPageInfo: multiPageInfo, multiPageInfo: multiPageInfo,
page: page, page: page,
viewStateNotifier: _viewStateNotifier, viewStateNotifier: _viewStateNotifier,
errorBuilder: (context, error, stackTrace) => ErrorChild(onTap: () => onTap?.call(null)), errorBuilder: (context, error, stackTrace) => ErrorView(onTap: () => onTap?.call(null)),
), ),
childSize: pageDisplaySize, childSize: pageDisplaySize,
controller: _magnifierController, controller: _magnifierController,
maxScale: maxScale, maxScale: EntryPageView.maxScale,
minScale: minScale, minScale: EntryPageView.minScale,
initialScale: initialScale, initialScale: EntryPageView.initialScale,
onTap: (c, d, s, childPosition) => onTap?.call(childPosition), onTap: (c, d, s, childPosition) => onTap?.call(childPosition),
applyScale: false, applyScale: false,
); );
@ -142,43 +141,16 @@ class _ImageViewState extends State<ImageView> {
), ),
childSize: pageDisplaySize, childSize: pageDisplaySize,
controller: _magnifierController, controller: _magnifierController,
minScale: minScale, minScale: EntryPageView.minScale,
initialScale: initialScale, initialScale: EntryPageView.initialScale,
scaleStateCycle: _vectorScaleStateCycle, scaleStateCycle: _vectorScaleStateCycle,
onTap: (c, d, s, childPosition) => onTap?.call(childPosition), onTap: (c, d, s, childPosition) => onTap?.call(childPosition),
); );
if (background == EntryBackground.checkered) { if (background == EntryBackground.checkered) {
child = ValueListenableBuilder<ViewState>( child = VectorViewCheckeredBackground(
valueListenable: _viewStateNotifier, displaySize: pageDisplaySize,
builder: (context, viewState, child) { viewStateNotifier: _viewStateNotifier,
final viewportSize = viewState.viewportSize;
if (viewportSize == null) return child;
final side = viewportSize.shortestSide;
final checkSize = side / ((side / ImageView.decorationCheckSize).round());
final viewSize = pageDisplaySize * viewState.scale;
final decorationSize = applyBoxFit(BoxFit.none, viewSize, viewportSize).source;
final offset = ((decorationSize - viewportSize) as Offset) / 2;
return Stack(
alignment: Alignment.center,
children: [
Positioned(
width: decorationSize.width,
height: decorationSize.height,
child: DecoratedBox(
decoration: CheckeredDecoration(
checkSize: checkSize,
offset: offset,
),
),
),
child,
],
);
},
child: child, child: child,
); );
} }
@ -196,9 +168,9 @@ class _ImageViewState extends State<ImageView> {
: SizedBox(), : SizedBox(),
childSize: pageDisplaySize, childSize: pageDisplaySize,
controller: _magnifierController, controller: _magnifierController,
maxScale: maxScale, maxScale: EntryPageView.maxScale,
minScale: minScale, minScale: EntryPageView.minScale,
initialScale: initialScale, initialScale: EntryPageView.initialScale,
onTap: (c, d, s, childPosition) => onTap?.call(childPosition), onTap: (c, d, s, childPosition) => onTap?.call(childPosition),
); );
} }
@ -227,50 +199,4 @@ class _ImageViewState extends State<ImageView> {
} }
} }
class ViewState {
final Offset position;
final double scale;
final Size viewportSize;
static const ViewState zero = ViewState(Offset.zero, 0, null);
const ViewState(this.position, this.scale, this.viewportSize);
@override
String toString() => '$runtimeType#${shortHash(this)}{position=$position, scale=$scale, viewportSize=$viewportSize}';
}
class ViewStateNotification extends Notification {
final String uri;
final ViewState viewState;
const ViewStateNotification(this.uri, this.viewState);
@override
String toString() => '$runtimeType#${shortHash(this)}{uri=$uri, viewState=$viewState}';
}
class ErrorChild extends StatelessWidget {
final VoidCallback onTap;
const ErrorChild({@required this.onTap});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => onTap?.call(),
// use a `Container` with a dummy color to make it expand
// so that we can also detect taps around the title `Text`
child: Container(
color: Colors.transparent,
child: EmptyContent(
icon: AIcons.error,
text: 'Oops!',
alignment: Alignment.center,
),
),
);
}
}
typedef MagnifierTapCallback = void Function(Offset childPosition); typedef MagnifierTapCallback = void Function(Offset childPosition);

View file

@ -0,0 +1,27 @@
import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/collection/empty.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class ErrorView extends StatelessWidget {
final VoidCallback onTap;
const ErrorView({@required this.onTap});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => onTap?.call(),
// use a `Container` with a dummy color to make it expand
// so that we can also detect taps around the title `Text`
child: Container(
color: Colors.transparent,
child: EmptyContent(
icon: AIcons.error,
text: 'Oops!',
alignment: Alignment.center,
),
),
);
}
}

View file

@ -9,7 +9,8 @@ import 'package:aves/model/settings/entry_background.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/utils/math_utils.dart'; import 'package:aves/utils/math_utils.dart';
import 'package:aves/widgets/common/fx/checkered_decoration.dart'; import 'package:aves/widgets/common/fx/checkered_decoration.dart';
import 'package:aves/widgets/fullscreen/image_view.dart'; import 'package:aves/widgets/viewer/visual/entry_page_view.dart';
import 'package:aves/widgets/viewer/visual/state.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
@ -221,7 +222,7 @@ class _TiledImageViewState extends State<TiledImageView> {
final background = settings.rasterBackground; final background = settings.rasterBackground;
if (background == EntryBackground.checkered) { if (background == EntryBackground.checkered) {
final side = viewportSize.shortestSide; final side = viewportSize.shortestSide;
final checkSize = side / ((side / ImageView.decorationCheckSize).round()); final checkSize = side / ((side / EntryPageView.decorationCheckSize).round());
final offset = ((decorationSize - viewportSize) as Offset) / 2; final offset = ((decorationSize - viewportSize) as Offset) / 2;
decoration = CheckeredDecoration( decoration = CheckeredDecoration(
checkSize: checkSize, checkSize: checkSize,

View file

@ -0,0 +1,25 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
class ViewState {
final Offset position;
final double scale;
final Size viewportSize;
static const ViewState zero = ViewState(Offset.zero, 0, null);
const ViewState(this.position, this.scale, this.viewportSize);
@override
String toString() => '$runtimeType#${shortHash(this)}{position=$position, scale=$scale, viewportSize=$viewportSize}';
}
class ViewStateNotification extends Notification {
final String uri;
final ViewState viewState;
const ViewStateNotification(this.uri, this.viewState);
@override
String toString() => '$runtimeType#${shortHash(this)}{uri=$uri, viewState=$viewState}';
}

View file

@ -0,0 +1,53 @@
import 'package:aves/widgets/common/fx/checkered_decoration.dart';
import 'package:aves/widgets/viewer/visual/entry_page_view.dart';
import 'package:aves/widgets/viewer/visual/state.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class VectorViewCheckeredBackground extends StatelessWidget {
final Size displaySize;
final ValueNotifier<ViewState> viewStateNotifier;
final Widget child;
const VectorViewCheckeredBackground({
@required this.displaySize,
@required this.viewStateNotifier,
@required this.child,
});
@override
Widget build(BuildContext context) {
return ValueListenableBuilder<ViewState>(
valueListenable: viewStateNotifier,
builder: (context, viewState, child) {
final viewportSize = viewState.viewportSize;
if (viewportSize == null) return child;
final side = viewportSize.shortestSide;
final checkSize = side / ((side / EntryPageView.decorationCheckSize).round());
final viewSize = displaySize * viewState.scale;
final decorationSize = applyBoxFit(BoxFit.none, viewSize, viewportSize).source;
final offset = ((decorationSize - viewportSize) as Offset) / 2;
return Stack(
alignment: Alignment.center,
children: [
Positioned(
width: decorationSize.width,
height: decorationSize.height,
child: DecoratedBox(
decoration: CheckeredDecoration(
checkSize: checkSize,
offset: offset,
),
),
),
child,
],
);
},
child: child,
);
}
}

View file

@ -17,10 +17,10 @@ class AvesVideo extends StatefulWidget {
}) : super(key: key); }) : super(key: key);
@override @override
State<StatefulWidget> createState() => AvesVideoState(); State<StatefulWidget> createState() => _AvesVideoState();
} }
class AvesVideoState extends State<AvesVideo> { class _AvesVideoState extends State<AvesVideo> {
final List<StreamSubscription> _subscriptions = []; final List<StreamSubscription> _subscriptions = [];
ImageEntry get entry => widget.entry; ImageEntry get entry => widget.entry;

View file

@ -1,5 +1,5 @@
import 'package:test/test.dart';
import 'package:aves/utils/string_utils.dart'; import 'package:aves/utils/string_utils.dart';
import 'package:test/test.dart';
void main() { void main() {
test('Sentence case', () { test('Sentence case', () {

View file

@ -1,5 +1,5 @@
import 'package:test/test.dart';
import 'package:aves/utils/time_utils.dart'; import 'package:aves/utils/time_utils.dart';
import 'package:test/test.dart';
void main() { void main() {
test('Comparison extension functions', () { test('Comparison extension functions', () {

View file

@ -36,7 +36,7 @@ void main() {
groupCollection(); groupCollection();
selectFirstAlbum(); selectFirstAlbum();
searchAlbum(); searchAlbum();
showFullscreen(); showViewer();
toggleOverlay(); toggleOverlay();
zoom(); zoom();
showInfoMetadata(); showInfoMetadata();
@ -145,8 +145,8 @@ void searchAlbum() {
}); });
} }
void showFullscreen() { void showViewer() {
test('[collection] show fullscreen', () async { test('[collection] show viewer', () async {
await driver.tap(find.byType('DecoratedThumbnail')); await driver.tap(find.byType('DecoratedThumbnail'));
await driver.waitUntilNoTransientCallbacks(); await driver.waitUntilNoTransientCallbacks();
await Future.delayed(Duration(seconds: 2)); await Future.delayed(Duration(seconds: 2));
@ -154,7 +154,7 @@ void showFullscreen() {
} }
void toggleOverlay() { void toggleOverlay() {
test('[fullscreen] toggle overlay', () async { test('[viewer] toggle overlay', () async {
final imageView = find.byValueKey('imageview'); final imageView = find.byValueKey('imageview');
print('* hide overlay'); print('* hide overlay');
@ -168,7 +168,7 @@ void toggleOverlay() {
} }
void zoom() { void zoom() {
test('[fullscreen] zoom cycle', () async { test('[viewer] zoom cycle', () async {
final imageView = find.byValueKey('imageview'); final imageView = find.byValueKey('imageview');
await driver.doubleTap(imageView); await driver.doubleTap(imageView);
@ -183,7 +183,7 @@ void zoom() {
} }
void showInfoMetadata() { void showInfoMetadata() {
test('[fullscreen] show info', () async { test('[viewer] show info', () async {
final verticalPageView = find.byValueKey('vertical-pageview'); final verticalPageView = find.byValueKey('vertical-pageview');
print('* scroll down to info'); print('* scroll down to info');
@ -214,7 +214,7 @@ void showInfoMetadata() {
} }
void scrollOffImage() { void scrollOffImage() {
test('[fullscreen] scroll off', () async { test('[viewer] scroll off', () async {
await driver.scroll(find.byValueKey('imageview'), 0, 800, Duration(milliseconds: 600)); await driver.scroll(find.byValueKey('imageview'), 0, 800, Duration(milliseconds: 600));
await Future.delayed(Duration(seconds: 1)); await Future.delayed(Duration(seconds: 1));
}); });