Latest polish tweaks

This commit is contained in:
Shawn 2022-12-20 10:23:20 -07:00
parent 52f8d67e2d
commit 574c4503fd
12 changed files with 86 additions and 54 deletions

View File

@ -1,10 +1,16 @@
import 'package:wonders/common_libs.dart'; import 'package:wonders/common_libs.dart';
class SimpleHeader extends StatelessWidget { class AppHeader extends StatelessWidget {
const SimpleHeader(this.title, const AppHeader(
{Key? key, this.subtitle, this.showBackBtn = true, this.isTransparent = false, this.onBack, this.trailing}) {Key? key,
this.title,
this.subtitle,
this.showBackBtn = true,
this.isTransparent = false,
this.onBack,
this.trailing})
: super(key: key); : super(key: key);
final String title; final String? title;
final String? subtitle; final String? subtitle;
final bool showBackBtn; final bool showBackBtn;
final bool isTransparent; final bool isTransparent;
@ -40,10 +46,12 @@ class SimpleHeader extends StatelessWidget {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
if (title != null)
Text( Text(
title.toUpperCase(), title!.toUpperCase(),
textHeightBehavior: TextHeightBehavior(applyHeightToFirstAscent: false), textHeightBehavior: TextHeightBehavior(applyHeightToFirstAscent: false),
style: $styles.text.h4.copyWith(color: $styles.colors.offWhite, fontWeight: FontWeight.w500), style:
$styles.text.h4.copyWith(color: $styles.colors.offWhite, fontWeight: FontWeight.w500),
), ),
if (subtitle != null) if (subtitle != null)
Text( Text(

View File

@ -4,7 +4,7 @@ import 'package:wonders/common_libs.dart';
import 'package:wonders/logic/data/highlight_data.dart'; import 'package:wonders/logic/data/highlight_data.dart';
import 'package:wonders/ui/common/app_icons.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/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'; import 'package:wonders/ui/common/static_text_scale.dart';
part 'widgets/_blurred_image_bg.dart'; part 'widgets/_blurred_image_bg.dart';
@ -122,8 +122,8 @@ class _ArtifactScreenState extends State<ArtifactCarouselScreen> {
), ),
/// Header /// Header
SimpleHeader( AppHeader(
$strings.artifactsTitleArtifacts, title: $strings.artifactsTitleArtifacts,
showBackBtn: false, showBackBtn: false,
isTransparent: true, isTransparent: true,
trailing: (context) => CircleBtn( trailing: (context) => CircleBtn(

View File

@ -3,7 +3,7 @@ import 'package:wonders/common_libs.dart';
import 'package:wonders/logic/data/wonder_data.dart'; import 'package:wonders/logic/data/wonder_data.dart';
import 'package:wonders/logic/data/wonders_data/search/search_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/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/static_text_scale.dart';
import 'package:wonders/ui/common/utils/app_haptics.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'; import 'package:wonders/ui/screens/artifact/artifact_search/time_range_selector/expanding_time_range_selector.dart';
@ -85,7 +85,7 @@ class _ArtifactSearchScreenState extends State<ArtifactSearchScreen> with GetItS
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
SimpleHeader($strings.artifactsSearchTitleBrowse, subtitle: wonder.title), AppHeader(title: $strings.artifactsSearchTitleBrowse, subtitle: wonder.title),
Gap($styles.insets.xs), Gap($styles.insets.xs),
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: $styles.insets.sm), padding: EdgeInsets.symmetric(horizontal: $styles.insets.sm),

View File

@ -5,7 +5,7 @@ import 'package:wonders/logic/collectibles_logic.dart';
import 'package:wonders/logic/data/collectible_data.dart'; import 'package:wonders/logic/data/collectible_data.dart';
import 'package:wonders/logic/data/wonder_data.dart'; import 'package:wonders/logic/data/wonder_data.dart';
import 'package:wonders/ui/common/centered_box.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'; import 'package:wonders/ui/common/modals/app_modals.dart';
part 'widgets/_collectible_image.dart'; part 'widgets/_collectible_image.dart';
@ -63,7 +63,7 @@ class _CollectionScreenState extends State<CollectionScreen> with GetItStateMixi
children: [ children: [
Expanded( Expanded(
child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [ child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
SimpleHeader($strings.collectionTitleCollection), AppHeader(title: $strings.collectionTitleCollection),
_NewlyDiscoveredItemsBtn(count: discovered, onPressed: _scrollToTarget), _NewlyDiscoveredItemsBtn(count: discovered, onPressed: _scrollToTarget),
Flexible( Flexible(
child: _CollectionList( child: _CollectionList(

View File

@ -11,7 +11,7 @@ class _TopIllustration extends StatelessWidget {
WonderIllustration(type, config: WonderIllustrationConfig.bg(enableAnims: false, shortMode: true)), WonderIllustration(type, config: WonderIllustrationConfig.bg(enableAnims: false, shortMode: true)),
Positioned.fill( Positioned.fill(
bottom: 50, bottom: 50,
child: AnimatedClouds(wonderType: type, enableAnimations: false, opacity: .5), child: AnimatedClouds(wonderType: type, enableAnimations: false, opacity: .5, cloudSize: 400),
), ),
Transform.translate( Transform.translate(
// Small bump down to make sure we cover the edge between the editorial page and the sky. // Small bump down to make sure we cover the edge between the editorial page and the sky.

View File

@ -9,7 +9,7 @@ import 'package:wonders/logic/data/timeline_data.dart';
import 'package:wonders/logic/data/wonder_data.dart'; import 'package:wonders/logic/data/wonder_data.dart';
import 'package:wonders/ui/common/blend_mask.dart'; import 'package:wonders/ui/common/blend_mask.dart';
import 'package:wonders/ui/common/centered_box.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/dashed_line.dart';
import 'package:wonders/ui/common/list_gradient.dart'; import 'package:wonders/ui/common/list_gradient.dart';
import 'package:wonders/ui/common/timeline_event_card.dart'; import 'package:wonders/ui/common/timeline_event_card.dart';
@ -55,7 +55,7 @@ class _TimelineScreenState extends State<TimelineScreen> {
padding: EdgeInsets.only(bottom: 0), padding: EdgeInsets.only(bottom: 0),
child: Column( child: Column(
children: [ children: [
SimpleHeader($strings.timelineTitleGlobalTimeline), AppHeader(title: $strings.timelineTitleGlobalTimeline),
/// Vertically scrolling timeline, manages a ScrollController. /// Vertically scrolling timeline, manages a ScrollController.
Expanded( Expanded(

View File

@ -56,7 +56,6 @@ class _EventsListState extends State<_EventsList> {
} }
return Stack( return Stack(
children: [ children: [
//TODO: Remove scrollbar on portrait
SingleChildScrollView( SingleChildScrollView(
controller: _scroller, controller: _scroller,
child: Column( 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() { Widget _buildScrollingListWithBlur() {
return AnimatedBuilder( return AnimatedBuilder(
animation: _scroller, animation: _scroller,

View File

@ -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_backdrop.dart';
import 'package:wonders/ui/common/app_icons.dart'; import 'package:wonders/ui/common/app_icons.dart';
import 'package:wonders/ui/common/centered_box.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/curved_clippers.dart';
import 'package:wonders/ui/common/hidden_collectible.dart'; import 'package:wonders/ui/common/hidden_collectible.dart';
import 'package:wonders/ui/common/list_gradient.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 /// Main view switches between portrait and landscape views
Positioned.fill( Positioned.fill(
top: $styles.insets.lg, top: $styles.insets.lg,
child: context.isLandscape ? _buildLandscape() : _buildPortrait(), child: context.isLandscape ? _buildLandscape(context) : _buildPortrait(),
), ),
/// Floating TimelineBtn /// Header w/ TimelineBtn
Positioned( TopCenter(
right: $styles.insets.lg, child: AppHeader(
top: $styles.insets.lg, showBackBtn: false,
child: CircleIconBtn( isTransparent: true,
trailing: (_) => CircleIconBtn(
icon: AppIcons.timeline, icon: AppIcons.timeline,
onPressed: handleTimelineBtnPressed, 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 /// Landscape layout is a row, with the WonderImage on left and EventsList on the right
Widget _buildLandscape() { Widget _buildLandscape(BuildContext context) {
return Row( return Row(
children: [ children: [
/// WonderImage w/ Timeline btn /// WonderImage w/ Timeline btn
@ -66,10 +70,19 @@ class WonderEvents extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Gap($styles.insets.lg), 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), Gap($styles.insets.lg),
SizedBox(width: 300, child: _TimelineBtn(type: type)), SizedBox(width: 300, child: _TimelineBtn(type: type)),
Gap($styles.insets.xl), ],
),
),
),
Gap($styles.insets.lg),
], ],
), ),
), ),
@ -78,7 +91,7 @@ class WonderEvents extends StatelessWidget {
/// EventsList /// EventsList
Expanded( Expanded(
child: CenteredBox( child: CenteredBox(
width: $styles.sizes.maxContentWidth1, width: $styles.sizes.maxContentWidth2,
child: _EventsList( child: _EventsList(
data: _data, data: _data,
topHeight: 100, topHeight: 100,

View File

@ -3,16 +3,18 @@ import 'dart:async';
import 'package:wonders/common_libs.dart'; import 'package:wonders/common_libs.dart';
import 'package:wonders/ui/common/utils/context_utils.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. // 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. // 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. // 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 { 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); : super(key: key);
final WonderType wonderType; final WonderType wonderType;
final bool enableAnimations; final bool enableAnimations;
final double opacity; final double opacity;
final double cloudSize;
@override @override
State<AnimatedClouds> createState() => _AnimatedCloudsState(); State<AnimatedClouds> createState() => _AnimatedCloudsState();
} }
@ -76,7 +78,7 @@ class _AnimatedCloudsState extends State<AnimatedClouds> with SingleTickerProvid
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// Old clouds animate from 0 to startOffset, new clouds do the opposite. // 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 // Use a positive, or negative start offset, based on index
final stOffset = _clouds.indexOf(c) % 2 == 0 ? -startOffset : startOffset; 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 // 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<AnimatedClouds> with SingleTickerProvid
return Positioned( return Positioned(
top: c.pos.dy, top: c.pos.dy,
left: isOld ? c.pos.dx - stOffset * curvedValue : c.pos.dx + stOffset * (1 - curvedValue), 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<AnimatedClouds> with SingleTickerProvid
flipX: rnd.getBool(), flipX: rnd.getBool(),
flipY: rnd.getBool(), flipY: rnd.getBool(),
opacity: widget.opacity, opacity: widget.opacity,
size: widget.cloudSize,
); );
}).toList(); }).toList();
} }
} }
class _Cloud extends StatelessWidget { 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 Offset pos;
final double scale; final double scale;
final bool flipX; final bool flipX;
final bool flipY; final bool flipY;
final double opacity; final double opacity;
final double size;
const _Cloud(this.pos, {this.scale = 1, this.flipX = false, this.flipY = false, required this.opacity});
@override @override
Widget build(BuildContext context) => Transform.scale( Widget build(BuildContext context) => Transform.scale(
@ -144,7 +149,7 @@ class _Cloud extends StatelessWidget {
child: Image.asset( child: Image.asset(
ImagePaths.cloud, ImagePaths.cloud,
opacity: AlwaysStoppedAnimation(.4 * opacity), opacity: AlwaysStoppedAnimation(.4 * opacity),
width: 400 * scale, width: size * scale,
fit: BoxFit.fitWidth, fit: BoxFit.fitWidth,
), ),
); );

View File

@ -69,6 +69,7 @@ class _IllustrationPieceState extends State<IllustrationPiece> {
final wonderBuilder = context.watch<WonderIllustrationBuilderState>(); final wonderBuilder = context.watch<WonderIllustrationBuilderState>();
final type = wonderBuilder.widget.wonderType; final type = wonderBuilder.widget.wonderType;
final imgPath = '${type.assetPath}/${widget.fileName}'; final imgPath = '${type.assetPath}/${widget.fileName}';
// Dynamically determine the aspect ratio of the image, so we can more easily position it
if (aspectRatio == null) { if (aspectRatio == null) {
aspectRatio == 0; // indicates load has started, so we don't run twice aspectRatio == 0; // indicates load has started, so we don't run twice
rootBundle.load(imgPath).then((img) async { rootBundle.load(imgPath).then((img) async {
@ -111,21 +112,26 @@ class _IllustrationPieceState extends State<IllustrationPiece> {
height * widget.fractionalOffset!.dy, height * widget.fractionalOffset!.dy,
); );
} }
return Stack( Widget? content;
children: [ if (uiImage != null) {
if (widget.bottom != null) Positioned.fill(child: widget.bottom!.call(context)), content = Transform.translate(
if (uiImage != null) ...[
Transform.translate(
offset: finalTranslation, offset: finalTranslation,
child: Transform.scale( child: Transform.scale(
scale: 1 + (widget.zoomAmt * config.zoom) + introZoom, scale: 1 + (widget.zoomAmt * config.zoom) + introZoom,
child: SizedBox( child: SizedBox(
height: height, height: height,
width: height * aspectRatio!, width: height * aspectRatio!,
child: !widget.enableHero ? img : Hero(tag: '$type-${widget.fileName}', child: img), child: img,
),
), ),
), ),
);
}
return Stack(
children: [
if (widget.bottom != null) Positioned.fill(child: widget.bottom!.call(context)),
if (uiImage != null) ...[
widget.enableHero ? Hero(tag: '$type-${widget.fileName}', child: content!) : content!,
], ],
if (widget.top != null) Positioned.fill(child: widget.top!.call(context)), if (widget.top != null) Positioned.fill(child: widget.top!.call(context)),
], ],

View File

@ -571,10 +571,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: image_fade name: image_fade
sha256: "6ec32003f451f3341f1b8ebd899b97e94f80ce0d66b13e59ade41ae03c34b464" sha256: "7296c9c53cd5de98e675ef1e27bdaa4035d6c3a45cf5b86094b2e545689b4ea6"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.1" version: "0.6.2"
image_gallery_saver: image_gallery_saver:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -34,7 +34,7 @@ dependencies:
google_maps_flutter_web: ^0.4.0+1 google_maps_flutter_web: ^0.4.0+1
go_router: ^4.2.8 go_router: ^4.2.8
http: ^0.13.5 http: ^0.13.5
image_fade: ^0.6.1 image_fade: ^0.6.2
image_gallery_saver: ^1.7.1 image_gallery_saver: ^1.7.1
internet_connection_checker: ^0.0.1+3 internet_connection_checker: ^0.0.1+3
intl: ^0.17.0 intl: ^0.17.0