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';
enum KeepScreenOn { never, fullscreenOnly, always }
enum KeepScreenOn { never, viewerOnly, always }
extension ExtraKeepScreenOn on KeepScreenOn {
String get name {
switch (this) {
case KeepScreenOn.never:
return 'Never';
case KeepScreenOn.fullscreenOnly:
case KeepScreenOn.viewerOnly:
return 'Viewer page only';
case KeepScreenOn.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/home_page.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_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
@ -99,7 +99,7 @@ class Settings extends ChangeNotifier {
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) {
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/common/behaviour/routes.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:provider/provider.dart';
@ -57,7 +57,7 @@ class GridThumbnail extends StatelessWidget {
onTap: () {
if (AvesApp.mode == AppMode.main) {
if (collection.isBrowsing) {
_goToFullscreen(context);
_goToViewer(context);
} else if (collection.isSelecting) {
collection.toggleSelection(entry);
}
@ -77,12 +77,12 @@ class GridThumbnail extends StatelessWidget {
);
}
void _goToFullscreen(BuildContext context) {
void _goToViewer(BuildContext context) {
Navigator.push(
context,
TransparentMaterialPageRoute(
settings: RouteSettings(name: MultiFullscreenPage.routeName),
pageBuilder: (c, a, sa) => MultiFullscreenPage(
settings: RouteSettings(name: MultiEntryViewerPage.routeName),
pageBuilder: (c, a, sa) => MultiEntryViewerPage(
collection: collection,
initialEntry: entry,
),

View file

@ -35,11 +35,11 @@ class MagnifierCore extends StatefulWidget {
@override
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;
double _startScale, _quickScaleLastY, _quickScaleLastDistance;
bool _doubleTap, _quickScaleMoved;

View file

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

View file

@ -2,7 +2,7 @@ import 'dart:collection';
import 'package:aves/services/android_debug_service.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';
class DebugAndroidDirSection extends StatefulWidget {

View file

@ -2,7 +2,7 @@ import 'dart:collection';
import 'package:aves/services/android_debug_service.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';
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/settings.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/scheduler.dart';
@ -22,10 +22,10 @@ class AppDebugPage extends StatefulWidget {
const AppDebugPage({this.source});
@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;
static OverlayEntry _taskQueueOverlayEntry;

View file

@ -1,5 +1,5 @@
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_core/firebase_core.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/countries_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: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/file_utils.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';
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/common/behaviour/routes.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_page.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
@ -121,8 +121,8 @@ class _HomePageState extends State<HomePage> {
Route _getRedirectRoute() {
if (AvesApp.mode == AppMode.view) {
return DirectMaterialPageRoute(
settings: RouteSettings(name: SingleFullscreenPage.routeName),
builder: (_) => SingleFullscreenPage(entry: _viewerEntry),
settings: RouteSettings(name: SingleEntryViewerPage.routeName),
builder: (_) => SingleEntryViewerPage(entry: _viewerEntry),
);
}

View file

@ -1,7 +1,7 @@
import 'package:aves/model/image_entry.dart';
import 'package:aves/model/image_metadata.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';
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/utils/constants.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';
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/model/image_entry.dart';
import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/fullscreen/debug/db.dart';
import 'package:aves/widgets/fullscreen/debug/metadata.dart';
import 'package:aves/widgets/fullscreen/info/common.dart';
import 'package:aves/widgets/viewer/debug/db.dart';
import 'package:aves/widgets/viewer/debug/metadata.dart';
import 'package:aves/widgets/viewer/info/common.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:tuple/tuple.dart';
class FullscreenDebugPage extends StatelessWidget {
static const routeName = '/fullscreen/debug';
class ViewerDebugPage extends StatelessWidget {
static const routeName = '/viewer/debug';
final ImageEntry entry;
const FullscreenDebugPage({@required this.entry});
const ViewerDebugPage({@required this.entry});
@override
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/dialogs/aves_dialog.dart';
import 'package:aves/widgets/dialogs/rename_entry_dialog.dart';
import 'package:aves/widgets/fullscreen/fullscreen_debug_page.dart';
import 'package:aves/widgets/fullscreen/printing.dart';
import 'package:aves/widgets/fullscreen/source_viewer_page.dart';
import 'package:aves/widgets/viewer/debug_page.dart';
import 'package:aves/widgets/viewer/printer.dart';
import 'package:aves/widgets/viewer/source_viewer_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
@ -168,8 +168,8 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin {
Navigator.push(
context,
MaterialPageRoute(
settings: RouteSettings(name: FullscreenDebugPage.routeName),
builder: (context) => FullscreenDebugPage(entry: entry),
settings: RouteSettings(name: ViewerDebugPage.routeName),
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/widgets/common/magnifier/pan/gesture_detector_scope.dart';
import 'package:aves/widgets/common/magnifier/pan/scroll_physics.dart';
import 'package:aves/widgets/fullscreen/image_view.dart';
import 'package:aves/widgets/fullscreen/multipage_controller.dart';
import 'package:aves/widgets/viewer/multipage.dart';
import 'package:aves/widgets/viewer/visual/entry_page_view.dart';
import 'package:flutter/material.dart';
import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
import 'package:tuple/tuple.dart';
class MultiImagePage extends StatefulWidget {
class MultiEntryScroller extends StatefulWidget {
final CollectionLens collection;
final PageController pageController;
final ValueChanged<int> onPageChanged;
@ -18,7 +18,7 @@ class MultiImagePage extends StatefulWidget {
final List<Tuple2<String, MultiPageController>> multiPageControllers;
final void Function(String uri) onViewDisposed;
const MultiImagePage({
const MultiEntryScroller({
this.collection,
this.pageController,
this.onPageChanged,
@ -29,10 +29,10 @@ class MultiImagePage extends StatefulWidget {
});
@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;
@override
@ -79,8 +79,8 @@ class MultiImagePageState extends State<MultiImagePage> with AutomaticKeepAliveC
);
}
ImageView _buildViewer(ImageEntry entry, {MultiPageInfo multiPageInfo, int page = 0}) {
return ImageView(
EntryPageView _buildViewer(ImageEntry entry, {MultiPageInfo multiPageInfo, int page = 0}) {
return EntryPageView(
key: Key('imageview'),
entry: entry,
multiPageInfo: multiPageInfo,
@ -100,13 +100,13 @@ class MultiImagePageState extends State<MultiImagePage> with AutomaticKeepAliveC
bool get wantKeepAlive => true;
}
class SingleImagePage extends StatefulWidget {
class SingleEntryScroller extends StatefulWidget {
final ImageEntry entry;
final VoidCallback onTap;
final List<Tuple2<String, IjkMediaController>> videoControllers;
final List<Tuple2<String, MultiPageController>> multiPageControllers;
const SingleImagePage({
const SingleEntryScroller({
this.entry,
this.onTap,
this.videoControllers,
@ -114,10 +114,10 @@ class SingleImagePage extends StatefulWidget {
});
@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;
@override
@ -150,8 +150,8 @@ class SingleImagePageState extends State<SingleImagePage> with AutomaticKeepAliv
);
}
ImageView _buildViewer({MultiPageInfo multiPageInfo, int page = 0}) {
return ImageView(
EntryPageView _buildViewer({MultiPageInfo multiPageInfo, int page = 0}) {
return EntryPageView(
entry: entry,
multiPageInfo: multiPageInfo,
page: page,

View file

@ -1,16 +1,16 @@
import 'package:aves/model/image_entry.dart';
import 'package:aves/model/source/collection_lens.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';
class MultiFullscreenPage extends AnimatedWidget {
static const routeName = '/fullscreen';
class MultiEntryViewerPage extends AnimatedWidget {
static const routeName = '/viewer';
final CollectionLens collection;
final ImageEntry initialEntry;
const MultiFullscreenPage({
const MultiEntryViewerPage({
Key key,
this.collection,
this.initialEntry,
@ -20,7 +20,7 @@ class MultiFullscreenPage extends AnimatedWidget {
Widget build(BuildContext context) {
return MediaQueryDataProvider(
child: Scaffold(
body: FullscreenBody(
body: EntryViewerStack(
collection: collection,
initialEntry: initialEntry,
),
@ -31,12 +31,12 @@ class MultiFullscreenPage extends AnimatedWidget {
}
}
class SingleFullscreenPage extends StatelessWidget {
static const routeName = '/fullscreen';
class SingleEntryViewerPage extends StatelessWidget {
static const routeName = '/viewer';
final ImageEntry entry;
const SingleFullscreenPage({
const SingleEntryViewerPage({
Key key,
this.entry,
}) : super(key: key);
@ -45,7 +45,7 @@ class SingleFullscreenPage extends StatelessWidget {
Widget build(BuildContext context) {
return MediaQueryDataProvider(
child: Scaffold(
body: FullscreenBody(
body: EntryViewerStack(
initialEntry: entry,
),
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/widgets/collection/collection_page.dart';
import 'package:aves/widgets/common/magnifier/pan/scroll_physics.dart';
import 'package:aves/widgets/fullscreen/entry_action_delegate.dart';
import 'package:aves/widgets/fullscreen/image_page.dart';
import 'package:aves/widgets/fullscreen/image_view.dart';
import 'package:aves/widgets/fullscreen/info/info_page.dart';
import 'package:aves/widgets/fullscreen/info/notifications.dart';
import 'package:aves/widgets/fullscreen/multipage_controller.dart';
import 'package:aves/widgets/fullscreen/overlay/bottom.dart';
import 'package:aves/widgets/fullscreen/overlay/panorama.dart';
import 'package:aves/widgets/fullscreen/overlay/top.dart';
import 'package:aves/widgets/fullscreen/overlay/video.dart';
import 'package:aves/widgets/viewer/entry_action_delegate.dart';
import 'package:aves/widgets/viewer/entry_scroller.dart';
import 'package:aves/widgets/viewer/info/info_page.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/panorama.dart';
import 'package:aves/widgets/viewer/overlay/top.dart';
import 'package:aves/widgets/viewer/overlay/video.dart';
import 'package:aves/widgets/viewer/visual/state.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
@ -28,21 +28,21 @@ import 'package:provider/provider.dart';
import 'package:screen/screen.dart';
import 'package:tuple/tuple.dart';
class FullscreenBody extends StatefulWidget {
class EntryViewerStack extends StatefulWidget {
final CollectionLens collection;
final ImageEntry initialEntry;
const FullscreenBody({
const EntryViewerStack({
Key key,
this.collection,
this.initialEntry,
}) : super(key: key);
@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);
int _currentHorizontalPage;
ValueNotifier<int> _currentVerticalPage;
@ -106,13 +106,13 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
_registerWidget(widget);
WidgetsBinding.instance.addObserver(this);
WidgetsBinding.instance.addPostFrameCallback((_) => _initOverlay());
if (settings.keepScreenOn == KeepScreenOn.fullscreenOnly) {
if (settings.keepScreenOn == KeepScreenOn.viewerOnly) {
Screen.keepOn(true);
}
}
@override
void didUpdateWidget(covariant FullscreenBody oldWidget) {
void didUpdateWidget(covariant EntryViewerStack oldWidget) {
super.didUpdateWidget(oldWidget);
_unregisterWidget(oldWidget);
_registerWidget(widget);
@ -132,11 +132,11 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
super.dispose();
}
void _registerWidget(FullscreenBody widget) {
void _registerWidget(EntryViewerStack widget) {
widget.collection?.addListener(_onCollectionChange);
}
void _unregisterWidget(FullscreenBody widget) {
void _unregisterWidget(EntryViewerStack widget) {
widget.collection?.removeListener(_onCollectionChange);
}
@ -170,7 +170,7 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
},
child: Stack(
children: [
FullscreenVerticalPageView(
ViewerVerticalPageView(
collection: collection,
entryNotifier: _entryNotifier,
videoControllers: _videoControllers,
@ -205,7 +205,7 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
final multiPageController = _getMultiPageController(entry);
final viewStateNotifier = _viewStateNotifiers.firstWhere((kv) => kv.item1 == entry.uri, orElse: () => null)?.item2;
return FullscreenTopOverlay(
return ViewerTopOverlay(
entry: entry,
scale: _topOverlayScale,
canToggleFavourite: hasCollection,
@ -264,7 +264,7 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
),
SlideTransition(
position: _bottomOverlayOffset,
child: FullscreenBottomOverlay(
child: ViewerBottomOverlay(
entries: entries,
index: _currentHorizontalPage,
showPosition: hasCollection,
@ -372,11 +372,11 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
void _onLeave() {
if (Navigator.canPop(context)) {
_showSystemUI();
if (settings.keepScreenOn == KeepScreenOn.fullscreenOnly) {
if (settings.keepScreenOn == KeepScreenOn.viewerOnly) {
Screen.keepOn(false);
}
} 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();
}
}
@ -472,7 +472,7 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
void _pauseVideoControllers() => _videoControllers.forEach((e) => e.item2.pause());
}
class FullscreenVerticalPageView extends StatefulWidget {
class ViewerVerticalPageView extends StatefulWidget {
final CollectionLens collection;
final ValueNotifier<ImageEntry> entryNotifier;
final List<Tuple2<String, IjkMediaController>> videoControllers;
@ -482,7 +482,7 @@ class FullscreenVerticalPageView extends StatefulWidget {
final VoidCallback onImageTap, onImagePageRequested;
final void Function(String uri) onViewDisposed;
const FullscreenVerticalPageView({
const ViewerVerticalPageView({
@required this.collection,
@required this.entryNotifier,
@required this.videoControllers,
@ -497,10 +497,10 @@ class FullscreenVerticalPageView extends StatefulWidget {
});
@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<bool> _infoPageVisibleNotifier = ValueNotifier(false);
ImageEntry _oldEntry;
@ -518,7 +518,7 @@ class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView>
}
@override
void didUpdateWidget(covariant FullscreenVerticalPageView oldWidget) {
void didUpdateWidget(covariant ViewerVerticalPageView oldWidget) {
super.didUpdateWidget(oldWidget);
_unregisterWidget(oldWidget);
_registerWidget(widget);
@ -530,13 +530,13 @@ class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView>
super.dispose();
}
void _registerWidget(FullscreenVerticalPageView widget) {
void _registerWidget(ViewerVerticalPageView widget) {
widget.verticalPager.addListener(_onVerticalPageControllerChanged);
widget.entryNotifier.addListener(_onEntryChanged);
if (_oldEntry != entry) _onEntryChanged();
}
void _unregisterWidget(FullscreenVerticalPageView widget) {
void _unregisterWidget(ViewerVerticalPageView widget) {
widget.verticalPager.removeListener(_onVerticalPageControllerChanged);
widget.entryNotifier.removeListener(_onEntryChanged);
_oldEntry?.imageChangeNotifier?.removeListener(_onImageChanged);
@ -545,10 +545,10 @@ class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView>
@override
Widget build(BuildContext context) {
final pages = [
// fake page for opacity transition between collection and fullscreen views
// fake page for opacity transition between collection and viewer
SizedBox(),
hasCollection
? MultiImagePage(
? MultiEntryScroller(
collection: collection,
pageController: widget.horizontalPager,
onTap: widget.onImageTap,
@ -557,7 +557,7 @@ class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView>
multiPageControllers: widget.multiPageControllers,
onViewDisposed: widget.onViewDisposed,
)
: SingleImagePage(
: SingleEntryScroller(
entry: entry,
onTap: widget.onImageTap,
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/file_utils.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:flutter/material.dart';
import 'package:intl/intl.dart';

View file

@ -1,8 +1,8 @@
import 'package:aves/model/image_entry.dart';
import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/app_bar_title.dart';
import 'package:aves/widgets/fullscreen/info/info_search.dart';
import 'package:aves/widgets/fullscreen/info/metadata/metadata_section.dart';
import 'package:aves/widgets/viewer/info/info_search.dart';
import 'package:aves/widgets/viewer/info/metadata/metadata_section.dart';
import 'package:flutter/material.dart';
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/theme/durations.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/fullscreen/info/info_app_bar.dart';
import 'package:aves/widgets/fullscreen/info/location_section.dart';
import 'package:aves/widgets/fullscreen/info/metadata/metadata_section.dart';
import 'package:aves/widgets/fullscreen/info/notifications.dart';
import 'package:aves/widgets/viewer/info/basic_section.dart';
import 'package:aves/widgets/viewer/info/info_app_bar.dart';
import 'package:aves/widgets/viewer/info/location_section.dart';
import 'package:aves/widgets/viewer/info/metadata/metadata_section.dart';
import 'package:aves/widgets/viewer/info/notifications.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
@ -25,10 +25,10 @@ class InfoPage extends StatefulWidget {
}) : super(key: key);
@override
State<StatefulWidget> createState() => InfoPageState();
State<StatefulWidget> createState() => _InfoPageState();
}
class InfoPageState extends State<InfoPage> {
class _InfoPageState extends State<InfoPage> {
final ScrollController _scrollController = ScrollController();
bool _scrollStartFromTop = false;

View file

@ -1,8 +1,8 @@
import 'package:aves/model/image_entry.dart';
import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/collection/empty.dart';
import 'package:aves/widgets/fullscreen/info/metadata/metadata_dir_tile.dart';
import 'package:aves/widgets/fullscreen/info/metadata/metadata_section.dart';
import 'package:aves/widgets/viewer/info/metadata/metadata_dir_tile.dart';
import 'package:aves/widgets/viewer/info/metadata/metadata_section.dart';
import 'package:collection/collection.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/icons.dart';
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
import 'package:aves/widgets/fullscreen/info/common.dart';
import 'package:aves/widgets/fullscreen/info/maps/common.dart';
import 'package:aves/widgets/fullscreen/info/maps/google_map.dart';
import 'package:aves/widgets/fullscreen/info/maps/leaflet_map.dart';
import 'package:aves/widgets/fullscreen/info/maps/marker.dart';
import 'package:aves/widgets/viewer/info/common.dart';
import 'package:aves/widgets/viewer/info/maps/common.dart';
import 'package:aves/widgets/viewer/info/maps/google_map.dart';
import 'package:aves/widgets/viewer/info/maps/leaflet_map.dart';
import 'package:aves/widgets/viewer/info/maps/marker.dart';
import 'package:flutter/material.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/dialogs/aves_dialog.dart';
import 'package:aves/widgets/dialogs/aves_selection_dialog.dart';
import 'package:aves/widgets/fullscreen/info/location_section.dart';
import 'package:aves/widgets/fullscreen/overlay/common.dart';
import 'package:aves/widgets/viewer/info/location_section.dart';
import 'package:aves/widgets/viewer/overlay/common.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';

View file

@ -2,9 +2,9 @@ import 'dart:async';
import 'dart:typed_data';
import 'package:aves/model/settings/settings.dart';
import 'package:aves/widgets/fullscreen/info/location_section.dart';
import 'package:aves/widgets/fullscreen/info/maps/common.dart';
import 'package:aves/widgets/fullscreen/info/maps/marker.dart';
import 'package:aves/widgets/viewer/info/location_section.dart';
import 'package:aves/widgets/viewer/info/maps/common.dart';
import 'package:aves/widgets/viewer/info/maps/marker.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:tuple/tuple.dart';
@ -27,10 +27,10 @@ class EntryGoogleMap extends StatefulWidget {
super(key: key);
@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;
Completer<Uint8List> _markerLoaderCompleter;

View file

@ -1,6 +1,6 @@
import 'package:aves/model/settings/settings.dart';
import 'package:aves/widgets/fullscreen/info/maps/common.dart';
import 'package:aves/widgets/fullscreen/info/maps/scale_layer.dart';
import 'package:aves/widgets/viewer/info/maps/common.dart';
import 'package:aves/widgets/viewer/info/maps/scale_layer.dart';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
@ -28,10 +28,10 @@ class EntryLeafletMap extends StatefulWidget {
}) : super(key: key);
@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();
@override

View file

@ -7,11 +7,11 @@ import 'package:aves/theme/icons.dart';
import 'package:aves/utils/color_utils.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
import 'package:aves/widgets/fullscreen/info/common.dart';
import 'package:aves/widgets/fullscreen/info/metadata/metadata_section.dart';
import 'package:aves/widgets/fullscreen/info/metadata/metadata_thumbnail.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_tile.dart';
import 'package:aves/widgets/fullscreen/source_viewer_page.dart';
import 'package:aves/widgets/viewer/info/common.dart';
import 'package:aves/widgets/viewer/info/metadata/metadata_section.dart';
import 'package:aves/widgets/viewer/info/metadata/metadata_thumbnail.dart';
import 'package:aves/widgets/viewer/info/metadata/xmp_tile.dart';
import 'package:aves/widgets/viewer/source_viewer_page.dart';
import 'package:flutter/foundation.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/theme/durations.dart';
import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/fullscreen/info/common.dart';
import 'package:aves/widgets/fullscreen/info/metadata/metadata_dir_tile.dart';
import 'package:aves/widgets/viewer/info/common.dart';
import 'package:aves/widgets/viewer/info/metadata/metadata_dir_tile.dart';
import 'package:collection/collection.dart';
import 'package:flutter/foundation.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/string_utils.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:flutter/foundation.dart';
import 'package:flutter/material.dart';

View file

@ -1,5 +1,5 @@
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
class XmpExifNamespace extends XmpNamespace {

View file

@ -1,5 +1,5 @@
import 'package:aves/widgets/fullscreen/info/common.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_namespaces.dart';
import 'package:aves/widgets/viewer/info/common.dart';
import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
import 'package:tuple/tuple.dart';
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/fullscreen/info/metadata/xmp_structs.dart';
import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
import 'package:aves/widgets/viewer/info/metadata/xmp_structs.dart';
import 'package:flutter/material.dart';
class XmpIptcCoreNamespace extends XmpNamespace {

View file

@ -1,6 +1,6 @@
// cf photoshop:ColorMode
// 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 {
static const ns = 'photoshop';

View file

@ -1,5 +1,5 @@
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
class XmpTiffNamespace extends XmpNamespace {

View file

@ -1,7 +1,7 @@
import 'package:aves/ref/mime_types.dart';
import 'package:aves/widgets/fullscreen/info/common.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_namespaces.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_structs.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:flutter/material.dart';
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/widgets/common/basic/multi_cross_fader.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';
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/identity/aves_expansion_tile.dart';
import 'package:aves/widgets/dialogs/aves_dialog.dart';
import 'package:aves/widgets/fullscreen/fullscreen_page.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_namespaces.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_ns/exif.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_ns/google.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_ns/iptc.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_ns/photoshop.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_ns/tiff.dart';
import 'package:aves/widgets/fullscreen/info/metadata/xmp_ns/xmp.dart';
import 'package:aves/widgets/viewer/entry_viewer_page.dart';
import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
import 'package:aves/widgets/viewer/info/metadata/xmp_ns/exif.dart';
import 'package:aves/widgets/viewer/info/metadata/xmp_ns/google.dart';
import 'package:aves/widgets/viewer/info/metadata/xmp_ns/iptc.dart';
import 'package:aves/widgets/viewer/info/metadata/xmp_ns/photoshop.dart';
import 'package:aves/widgets/viewer/info/metadata/xmp_ns/tiff.dart';
import 'package:aves/widgets/viewer/info/metadata/xmp_ns/xmp.dart';
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:pedantic/pedantic.dart';
@ -127,8 +127,8 @@ class _XmpDirTileState extends State<XmpDirTile> with FeedbackMixin {
unawaited(Navigator.push(
context,
TransparentMaterialPageRoute(
settings: RouteSettings(name: SingleFullscreenPage.routeName),
pageBuilder: (c, a, sa) => SingleFullscreenPage(entry: embedEntry),
settings: RouteSettings(name: SingleEntryViewerPage.routeName),
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/utils/constants.dart';
import 'package:aves/widgets/common/fx/blurred.dart';
import 'package:aves/widgets/fullscreen/multipage_controller.dart';
import 'package:aves/widgets/fullscreen/overlay/common.dart';
import 'package:aves/widgets/fullscreen/overlay/multipage.dart';
import 'package:aves/widgets/viewer/multipage.dart';
import 'package:aves/widgets/viewer/overlay/common.dart';
import 'package:aves/widgets/viewer/overlay/multipage.dart';
import 'package:decorated_icon/decorated_icon.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
class FullscreenBottomOverlay extends StatefulWidget {
class ViewerBottomOverlay extends StatefulWidget {
final List<ImageEntry> entries;
final int index;
final bool showPosition;
final EdgeInsets viewInsets, viewPadding;
final MultiPageController multiPageController;
const FullscreenBottomOverlay({
const ViewerBottomOverlay({
Key key,
@required this.entries,
@required this.index,
@ -37,10 +37,10 @@ class FullscreenBottomOverlay extends StatefulWidget {
}) : super(key: key);
@override
State<StatefulWidget> createState() => _FullscreenBottomOverlayState();
State<StatefulWidget> createState() => _ViewerBottomOverlayState();
}
class _FullscreenBottomOverlayState extends State<FullscreenBottomOverlay> {
class _ViewerBottomOverlayState extends State<ViewerBottomOverlay> {
Future<OverlayMetadata> _detailLoader;
ImageEntry _lastEntry;
OverlayMetadata _lastDetails;
@ -58,7 +58,7 @@ class _FullscreenBottomOverlayState extends State<FullscreenBottomOverlay> {
}
@override
void didUpdateWidget(covariant FullscreenBottomOverlay oldWidget) {
void didUpdateWidget(covariant ViewerBottomOverlay oldWidget) {
super.didUpdateWidget(oldWidget);
if (entry != _lastEntry) {
_initDetailLoader();

View file

@ -2,8 +2,8 @@ import 'dart:math';
import 'package:aves/model/image_entry.dart';
import 'package:aves/model/multipage.dart';
import 'package:aves/widgets/fullscreen/image_view.dart';
import 'package:aves/widgets/fullscreen/multipage_controller.dart';
import 'package:aves/widgets/viewer/multipage.dart';
import 'package:aves/widgets/viewer/visual/state.dart';
import 'package:flutter/foundation.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/theme/durations.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/material.dart';

View file

@ -1,6 +1,6 @@
import 'package:aves/model/image_entry.dart';
import 'package:aves/widgets/fullscreen/overlay/common.dart';
import 'package:aves/widgets/fullscreen/panorama_page.dart';
import 'package:aves/widgets/viewer/overlay/common.dart';
import 'package:aves/widgets/viewer/panorama_page.dart';
import 'package:flutter/material.dart';
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/widgets/common/basic/menu_row.dart';
import 'package:aves/widgets/common/fx/sweeper.dart';
import 'package:aves/widgets/fullscreen/image_view.dart';
import 'package:aves/widgets/fullscreen/multipage_controller.dart';
import 'package:aves/widgets/fullscreen/overlay/common.dart';
import 'package:aves/widgets/fullscreen/overlay/minimap.dart';
import 'package:aves/widgets/viewer/multipage.dart';
import 'package:aves/widgets/viewer/overlay/common.dart';
import 'package:aves/widgets/viewer/overlay/minimap.dart';
import 'package:aves/widgets/viewer/visual/state.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
class FullscreenTopOverlay extends StatelessWidget {
class ViewerTopOverlay extends StatelessWidget {
final ImageEntry entry;
final Animation<double> scale;
final EdgeInsets viewInsets, viewPadding;
@ -33,7 +33,7 @@ class FullscreenTopOverlay extends StatelessWidget {
static const int portraitActionCount = 2;
const FullscreenTopOverlay({
const ViewerTopOverlay({
Key key,
@required this.entry,
@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/widgets/common/fx/blurred.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_ijkplayer/flutter_ijkplayer.dart';
@ -24,10 +24,10 @@ class VideoControlOverlay extends StatefulWidget {
}) : super(key: key);
@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();
bool _playingOnDragStart = false;
AnimationController _playPauseAnimation;

View file

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

View file

@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_highlight/themes/darcula.dart';
class SourceViewerPage extends StatefulWidget {
static const routeName = '/fullscreen/source';
static const routeName = '/viewer/source';
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/settings/entry_background.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/state.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_level.dart';
import 'package:aves/widgets/common/magnifier/scale/state.dart';
import 'package:aves/widgets/fullscreen/tiled_view.dart';
import 'package:aves/widgets/fullscreen/video_view.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';
import 'package:aves/widgets/viewer/visual/vector.dart';
import 'package:aves/widgets/viewer/visual/video.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:tuple/tuple.dart';
class ImageView extends StatefulWidget {
class EntryPageView extends StatefulWidget {
final ImageEntry entry;
final MultiPageInfo multiPageInfo;
final int page;
@ -32,8 +32,11 @@ class ImageView extends StatefulWidget {
final VoidCallback onDisposed;
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,
@required this.entry,
this.multiPageInfo,
@ -45,18 +48,14 @@ class ImageView extends StatefulWidget {
}) : super(key: key);
@override
_ImageViewState createState() => _ImageViewState();
_EntryPageViewState createState() => _EntryPageViewState();
}
class _ImageViewState extends State<ImageView> {
class _EntryPageViewState extends State<EntryPageView> {
final MagnifierController _magnifierController = MagnifierController();
final ValueNotifier<ViewState> _viewStateNotifier = ValueNotifier(ViewState.zero);
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;
MultiPageInfo get multiPageInfo => widget.multiPageInfo;
@ -95,7 +94,7 @@ class _ImageViewState extends State<ImageView> {
} else if (entry.canDecode) {
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
return widget.heroTag != null && !entry.isVideo
@ -116,13 +115,13 @@ class _ImageViewState extends State<ImageView> {
multiPageInfo: multiPageInfo,
page: page,
viewStateNotifier: _viewStateNotifier,
errorBuilder: (context, error, stackTrace) => ErrorChild(onTap: () => onTap?.call(null)),
errorBuilder: (context, error, stackTrace) => ErrorView(onTap: () => onTap?.call(null)),
),
childSize: pageDisplaySize,
controller: _magnifierController,
maxScale: maxScale,
minScale: minScale,
initialScale: initialScale,
maxScale: EntryPageView.maxScale,
minScale: EntryPageView.minScale,
initialScale: EntryPageView.initialScale,
onTap: (c, d, s, childPosition) => onTap?.call(childPosition),
applyScale: false,
);
@ -142,43 +141,16 @@ class _ImageViewState extends State<ImageView> {
),
childSize: pageDisplaySize,
controller: _magnifierController,
minScale: minScale,
initialScale: initialScale,
minScale: EntryPageView.minScale,
initialScale: EntryPageView.initialScale,
scaleStateCycle: _vectorScaleStateCycle,
onTap: (c, d, s, childPosition) => onTap?.call(childPosition),
);
if (background == EntryBackground.checkered) {
child = 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 / 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 = VectorViewCheckeredBackground(
displaySize: pageDisplaySize,
viewStateNotifier: _viewStateNotifier,
child: child,
);
}
@ -196,9 +168,9 @@ class _ImageViewState extends State<ImageView> {
: SizedBox(),
childSize: pageDisplaySize,
controller: _magnifierController,
maxScale: maxScale,
minScale: minScale,
initialScale: initialScale,
maxScale: EntryPageView.maxScale,
minScale: EntryPageView.minScale,
initialScale: EntryPageView.initialScale,
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);

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/utils/math_utils.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/material.dart';
import 'package:tuple/tuple.dart';
@ -221,7 +222,7 @@ class _TiledImageViewState extends State<TiledImageView> {
final background = settings.rasterBackground;
if (background == EntryBackground.checkered) {
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;
decoration = CheckeredDecoration(
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);
@override
State<StatefulWidget> createState() => AvesVideoState();
State<StatefulWidget> createState() => _AvesVideoState();
}
class AvesVideoState extends State<AvesVideo> {
class _AvesVideoState extends State<AvesVideo> {
final List<StreamSubscription> _subscriptions = [];
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:test/test.dart';
void main() {
test('Sentence case', () {

View file

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

View file

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