From 574c4503fd93ba32789f8c5aab0f68cf4a12dd66 Mon Sep 17 00:00:00 2001 From: Shawn Date: Tue, 20 Dec 2022 10:23:20 -0700 Subject: [PATCH] Latest polish tweaks --- .../{simple_header.dart => app_header.dart} | 26 ++++++++----- .../artifact_carousel_screen.dart | 6 +-- .../artifact_search_screen.dart | 4 +- .../screens/collection/collection_screen.dart | 4 +- .../editorial/widgets/_top_illustration.dart | 2 +- lib/ui/screens/timeline/timeline_screen.dart | 4 +- .../wonder_events/widgets/_events_list.dart | 4 +- .../screens/wonder_events/wonder_events.dart | 37 +++++++++++++------ .../common/animated_clouds.dart | 19 ++++++---- .../common/illustration_piece.dart | 28 ++++++++------ pubspec.lock | 4 +- pubspec.yaml | 2 +- 12 files changed, 86 insertions(+), 54 deletions(-) rename lib/ui/common/controls/{simple_header.dart => app_header.dart} (73%) diff --git a/lib/ui/common/controls/simple_header.dart b/lib/ui/common/controls/app_header.dart similarity index 73% rename from lib/ui/common/controls/simple_header.dart rename to lib/ui/common/controls/app_header.dart index 3b56101e..eabb6565 100644 --- a/lib/ui/common/controls/simple_header.dart +++ b/lib/ui/common/controls/app_header.dart @@ -1,10 +1,16 @@ import 'package:wonders/common_libs.dart'; -class SimpleHeader extends StatelessWidget { - const SimpleHeader(this.title, - {Key? key, this.subtitle, this.showBackBtn = true, this.isTransparent = false, this.onBack, this.trailing}) +class AppHeader extends StatelessWidget { + const AppHeader( + {Key? key, + this.title, + this.subtitle, + this.showBackBtn = true, + this.isTransparent = false, + this.onBack, + this.trailing}) : super(key: key); - final String title; + final String? title; final String? subtitle; final bool showBackBtn; final bool isTransparent; @@ -40,11 +46,13 @@ class SimpleHeader extends StatelessWidget { child: Column( mainAxisSize: MainAxisSize.min, children: [ - Text( - title.toUpperCase(), - textHeightBehavior: TextHeightBehavior(applyHeightToFirstAscent: false), - style: $styles.text.h4.copyWith(color: $styles.colors.offWhite, fontWeight: FontWeight.w500), - ), + if (title != null) + Text( + title!.toUpperCase(), + textHeightBehavior: TextHeightBehavior(applyHeightToFirstAscent: false), + style: + $styles.text.h4.copyWith(color: $styles.colors.offWhite, fontWeight: FontWeight.w500), + ), if (subtitle != null) Text( subtitle!.toUpperCase(), diff --git a/lib/ui/screens/artifact/artifact_carousel/artifact_carousel_screen.dart b/lib/ui/screens/artifact/artifact_carousel/artifact_carousel_screen.dart index b55c34c8..08c9ac46 100644 --- a/lib/ui/screens/artifact/artifact_carousel/artifact_carousel_screen.dart +++ b/lib/ui/screens/artifact/artifact_carousel/artifact_carousel_screen.dart @@ -4,7 +4,7 @@ import 'package:wonders/common_libs.dart'; import 'package:wonders/logic/data/highlight_data.dart'; import 'package:wonders/ui/common/app_icons.dart'; import 'package:wonders/ui/common/controls/app_page_indicator.dart'; -import 'package:wonders/ui/common/controls/simple_header.dart'; +import 'package:wonders/ui/common/controls/app_header.dart'; import 'package:wonders/ui/common/static_text_scale.dart'; part 'widgets/_blurred_image_bg.dart'; @@ -122,8 +122,8 @@ class _ArtifactScreenState extends State { ), /// Header - SimpleHeader( - $strings.artifactsTitleArtifacts, + AppHeader( + title: $strings.artifactsTitleArtifacts, showBackBtn: false, isTransparent: true, trailing: (context) => CircleBtn( diff --git a/lib/ui/screens/artifact/artifact_search/artifact_search_screen.dart b/lib/ui/screens/artifact/artifact_search/artifact_search_screen.dart index 7fd4bec7..8ea4eb58 100644 --- a/lib/ui/screens/artifact/artifact_search/artifact_search_screen.dart +++ b/lib/ui/screens/artifact/artifact_search/artifact_search_screen.dart @@ -3,7 +3,7 @@ import 'package:wonders/common_libs.dart'; import 'package:wonders/logic/data/wonder_data.dart'; import 'package:wonders/logic/data/wonders_data/search/search_data.dart'; import 'package:wonders/ui/common/app_icons.dart'; -import 'package:wonders/ui/common/controls/simple_header.dart'; +import 'package:wonders/ui/common/controls/app_header.dart'; import 'package:wonders/ui/common/static_text_scale.dart'; import 'package:wonders/ui/common/utils/app_haptics.dart'; import 'package:wonders/ui/screens/artifact/artifact_search/time_range_selector/expanding_time_range_selector.dart'; @@ -85,7 +85,7 @@ class _ArtifactSearchScreenState extends State with GetItS child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - SimpleHeader($strings.artifactsSearchTitleBrowse, subtitle: wonder.title), + AppHeader(title: $strings.artifactsSearchTitleBrowse, subtitle: wonder.title), Gap($styles.insets.xs), Padding( padding: EdgeInsets.symmetric(horizontal: $styles.insets.sm), diff --git a/lib/ui/screens/collection/collection_screen.dart b/lib/ui/screens/collection/collection_screen.dart index ca4fc66d..c194f2ce 100644 --- a/lib/ui/screens/collection/collection_screen.dart +++ b/lib/ui/screens/collection/collection_screen.dart @@ -5,7 +5,7 @@ import 'package:wonders/logic/collectibles_logic.dart'; import 'package:wonders/logic/data/collectible_data.dart'; import 'package:wonders/logic/data/wonder_data.dart'; import 'package:wonders/ui/common/centered_box.dart'; -import 'package:wonders/ui/common/controls/simple_header.dart'; +import 'package:wonders/ui/common/controls/app_header.dart'; import 'package:wonders/ui/common/modals/app_modals.dart'; part 'widgets/_collectible_image.dart'; @@ -63,7 +63,7 @@ class _CollectionScreenState extends State with GetItStateMixi children: [ Expanded( child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - SimpleHeader($strings.collectionTitleCollection), + AppHeader(title: $strings.collectionTitleCollection), _NewlyDiscoveredItemsBtn(count: discovered, onPressed: _scrollToTarget), Flexible( child: _CollectionList( diff --git a/lib/ui/screens/editorial/widgets/_top_illustration.dart b/lib/ui/screens/editorial/widgets/_top_illustration.dart index 5e716fc5..08ad0da3 100644 --- a/lib/ui/screens/editorial/widgets/_top_illustration.dart +++ b/lib/ui/screens/editorial/widgets/_top_illustration.dart @@ -11,7 +11,7 @@ class _TopIllustration extends StatelessWidget { WonderIllustration(type, config: WonderIllustrationConfig.bg(enableAnims: false, shortMode: true)), Positioned.fill( bottom: 50, - child: AnimatedClouds(wonderType: type, enableAnimations: false, opacity: .5), + child: AnimatedClouds(wonderType: type, enableAnimations: false, opacity: .5, cloudSize: 400), ), Transform.translate( // Small bump down to make sure we cover the edge between the editorial page and the sky. diff --git a/lib/ui/screens/timeline/timeline_screen.dart b/lib/ui/screens/timeline/timeline_screen.dart index e61281d4..5d21fbc8 100644 --- a/lib/ui/screens/timeline/timeline_screen.dart +++ b/lib/ui/screens/timeline/timeline_screen.dart @@ -9,7 +9,7 @@ import 'package:wonders/logic/data/timeline_data.dart'; import 'package:wonders/logic/data/wonder_data.dart'; import 'package:wonders/ui/common/blend_mask.dart'; import 'package:wonders/ui/common/centered_box.dart'; -import 'package:wonders/ui/common/controls/simple_header.dart'; +import 'package:wonders/ui/common/controls/app_header.dart'; import 'package:wonders/ui/common/dashed_line.dart'; import 'package:wonders/ui/common/list_gradient.dart'; import 'package:wonders/ui/common/timeline_event_card.dart'; @@ -55,7 +55,7 @@ class _TimelineScreenState extends State { padding: EdgeInsets.only(bottom: 0), child: Column( children: [ - SimpleHeader($strings.timelineTitleGlobalTimeline), + AppHeader(title: $strings.timelineTitleGlobalTimeline), /// Vertically scrolling timeline, manages a ScrollController. Expanded( diff --git a/lib/ui/screens/wonder_events/widgets/_events_list.dart b/lib/ui/screens/wonder_events/widgets/_events_list.dart index 9f8a128a..c0d606d3 100644 --- a/lib/ui/screens/wonder_events/widgets/_events_list.dart +++ b/lib/ui/screens/wonder_events/widgets/_events_list.dart @@ -56,7 +56,6 @@ class _EventsListState extends State<_EventsList> { } return Stack( children: [ - //TODO: Remove scrollbar on portrait SingleChildScrollView( controller: _scroller, child: Column( @@ -101,7 +100,8 @@ class _EventsListState extends State<_EventsList> { ); } - /// Wraps the list in a scroll listener + /// Wraps the list in a scroll listener that fades in an underlay as the content + /// is scrolled Widget _buildScrollingListWithBlur() { return AnimatedBuilder( animation: _scroller, diff --git a/lib/ui/screens/wonder_events/wonder_events.dart b/lib/ui/screens/wonder_events/wonder_events.dart index 4e6f7603..d4c3192a 100644 --- a/lib/ui/screens/wonder_events/wonder_events.dart +++ b/lib/ui/screens/wonder_events/wonder_events.dart @@ -4,6 +4,7 @@ import 'package:wonders/logic/data/wonder_data.dart'; import 'package:wonders/ui/common/app_backdrop.dart'; import 'package:wonders/ui/common/app_icons.dart'; import 'package:wonders/ui/common/centered_box.dart'; +import 'package:wonders/ui/common/controls/app_header.dart'; import 'package:wonders/ui/common/curved_clippers.dart'; import 'package:wonders/ui/common/hidden_collectible.dart'; import 'package:wonders/ui/common/list_gradient.dart'; @@ -35,17 +36,20 @@ class WonderEvents extends StatelessWidget { /// Main view switches between portrait and landscape views Positioned.fill( top: $styles.insets.lg, - child: context.isLandscape ? _buildLandscape() : _buildPortrait(), + child: context.isLandscape ? _buildLandscape(context) : _buildPortrait(), ), - /// Floating TimelineBtn - Positioned( - right: $styles.insets.lg, - top: $styles.insets.lg, - child: CircleIconBtn( + /// Header w/ TimelineBtn + TopCenter( + child: AppHeader( + showBackBtn: false, + isTransparent: true, + trailing: (_) => CircleIconBtn( icon: AppIcons.timeline, onPressed: handleTimelineBtnPressed, - semanticLabel: $strings.eventsListButtonOpenGlobal)), + semanticLabel: $strings.eventsListButtonOpenGlobal), + ), + ), ], ), ), @@ -54,7 +58,7 @@ class WonderEvents extends StatelessWidget { } /// Landscape layout is a row, with the WonderImage on left and EventsList on the right - Widget _buildLandscape() { + Widget _buildLandscape(BuildContext context) { return Row( children: [ /// WonderImage w/ Timeline btn @@ -66,10 +70,19 @@ class WonderEvents extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Gap($styles.insets.lg), - Expanded(child: Center(child: _WonderImageWithTimeline(data: _data, height: 500))), + Expanded( + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + _WonderImageWithTimeline(data: _data, height: min(500, context.heightPx - 300)), + Gap($styles.insets.lg), + SizedBox(width: 300, child: _TimelineBtn(type: type)), + ], + ), + ), + ), Gap($styles.insets.lg), - SizedBox(width: 300, child: _TimelineBtn(type: type)), - Gap($styles.insets.xl), ], ), ), @@ -78,7 +91,7 @@ class WonderEvents extends StatelessWidget { /// EventsList Expanded( child: CenteredBox( - width: $styles.sizes.maxContentWidth1, + width: $styles.sizes.maxContentWidth2, child: _EventsList( data: _data, topHeight: 100, diff --git a/lib/ui/wonder_illustrations/common/animated_clouds.dart b/lib/ui/wonder_illustrations/common/animated_clouds.dart index 7fa15ec6..2c4b3897 100644 --- a/lib/ui/wonder_illustrations/common/animated_clouds.dart +++ b/lib/ui/wonder_illustrations/common/animated_clouds.dart @@ -3,16 +3,18 @@ import 'dart:async'; import 'package:wonders/common_libs.dart'; import 'package:wonders/ui/common/utils/context_utils.dart'; -//TODO: Make the clouds fade out and in +// TODO: Clouds should fade in and out // Shows a set of clouds that animated onto stage. // When value-key is changed, a new set of clouds will animate into place and the old ones will animate out. // Uses a random seed system, to make sure we get the same set of clouds for each wonder, without actually having to hand-position them. class AnimatedClouds extends StatefulWidget with GetItStatefulWidgetMixin { - AnimatedClouds({Key? key, this.enableAnimations = true, required this.wonderType, required this.opacity}) + AnimatedClouds( + {Key? key, this.enableAnimations = true, required this.wonderType, required this.opacity, this.cloudSize = 500}) : super(key: key); final WonderType wonderType; final bool enableAnimations; final double opacity; + final double cloudSize; @override State createState() => _AnimatedCloudsState(); } @@ -76,7 +78,7 @@ class _AnimatedCloudsState extends State with SingleTickerProvid @override Widget build(BuildContext context) { // Old clouds animate from 0 to startOffset, new clouds do the opposite. - Widget buildCloud(c, {required bool isOld, required int startOffset}) { + Widget buildCloud(_Cloud c, {required bool isOld, required int startOffset}) { // Use a positive, or negative start offset, based on index final stOffset = _clouds.indexOf(c) % 2 == 0 ? -startOffset : startOffset; // If old, we will end at the stOffset and start at 0, if new, start at stOffset, and end at 0 @@ -84,7 +86,7 @@ class _AnimatedCloudsState extends State with SingleTickerProvid return Positioned( top: c.pos.dy, left: isOld ? c.pos.dx - stOffset * curvedValue : c.pos.dx + stOffset * (1 - curvedValue), - child: c, + child: Opacity(opacity: isOld ? 1 - _anim.value : _anim.value, child: c), ); } @@ -123,19 +125,22 @@ class _AnimatedCloudsState extends State with SingleTickerProvid flipX: rnd.getBool(), flipY: rnd.getBool(), opacity: widget.opacity, + size: widget.cloudSize, ); }).toList(); } } class _Cloud extends StatelessWidget { + const _Cloud(this.pos, + {this.scale = 1, this.flipX = false, this.flipY = false, required this.opacity, required this.size}); + final Offset pos; final double scale; final bool flipX; final bool flipY; final double opacity; - - const _Cloud(this.pos, {this.scale = 1, this.flipX = false, this.flipY = false, required this.opacity}); + final double size; @override Widget build(BuildContext context) => Transform.scale( @@ -144,7 +149,7 @@ class _Cloud extends StatelessWidget { child: Image.asset( ImagePaths.cloud, opacity: AlwaysStoppedAnimation(.4 * opacity), - width: 400 * scale, + width: size * scale, fit: BoxFit.fitWidth, ), ); diff --git a/lib/ui/wonder_illustrations/common/illustration_piece.dart b/lib/ui/wonder_illustrations/common/illustration_piece.dart index 00159175..93f1a1f6 100644 --- a/lib/ui/wonder_illustrations/common/illustration_piece.dart +++ b/lib/ui/wonder_illustrations/common/illustration_piece.dart @@ -69,6 +69,7 @@ class _IllustrationPieceState extends State { final wonderBuilder = context.watch(); final type = wonderBuilder.widget.wonderType; final imgPath = '${type.assetPath}/${widget.fileName}'; + // Dynamically determine the aspect ratio of the image, so we can more easily position it if (aspectRatio == null) { aspectRatio == 0; // indicates load has started, so we don't run twice rootBundle.load(imgPath).then((img) async { @@ -111,21 +112,26 @@ class _IllustrationPieceState extends State { height * widget.fractionalOffset!.dy, ); } + Widget? content; + if (uiImage != null) { + content = Transform.translate( + offset: finalTranslation, + child: Transform.scale( + scale: 1 + (widget.zoomAmt * config.zoom) + introZoom, + child: SizedBox( + height: height, + width: height * aspectRatio!, + child: img, + ), + ), + ); + } + return Stack( children: [ if (widget.bottom != null) Positioned.fill(child: widget.bottom!.call(context)), if (uiImage != null) ...[ - Transform.translate( - offset: finalTranslation, - child: Transform.scale( - scale: 1 + (widget.zoomAmt * config.zoom) + introZoom, - child: SizedBox( - height: height, - width: height * aspectRatio!, - child: !widget.enableHero ? img : Hero(tag: '$type-${widget.fileName}', child: img), - ), - ), - ), + widget.enableHero ? Hero(tag: '$type-${widget.fileName}', child: content!) : content!, ], if (widget.top != null) Positioned.fill(child: widget.top!.call(context)), ], diff --git a/pubspec.lock b/pubspec.lock index e23bd9d3..e94d8b1c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -571,10 +571,10 @@ packages: dependency: "direct main" description: name: image_fade - sha256: "6ec32003f451f3341f1b8ebd899b97e94f80ce0d66b13e59ade41ae03c34b464" + sha256: "7296c9c53cd5de98e675ef1e27bdaa4035d6c3a45cf5b86094b2e545689b4ea6" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.6.2" image_gallery_saver: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 564b51c0..5d45b31d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -34,7 +34,7 @@ dependencies: google_maps_flutter_web: ^0.4.0+1 go_router: ^4.2.8 http: ^0.13.5 - image_fade: ^0.6.1 + image_fade: ^0.6.2 image_gallery_saver: ^1.7.1 internet_connection_checker: ^0.0.1+3 intl: ^0.17.0