diff --git a/lib/logic/app_logic.dart b/lib/logic/app_logic.dart index acc843ea..6646799e 100644 --- a/lib/logic/app_logic.dart +++ b/lib/logic/app_logic.dart @@ -21,26 +21,30 @@ class AppLogic { // Default to only allowing portrait mode setDeviceOrientation(Axis.vertical); - // Try and get highest FPS possible on Android devices + // Set preferred refresh rate to the max possible (the OS may ignore this) await FlutterDisplayMode.setHighRefreshRate(); - // Localizations load + // Localizations await localeLogic.load(); - // Data load + + // Timeline await timelineLogic.init(); - // Settings load + + // Settings await settingsLogic.load(); - // Collectibles init + + // Collectibles await collectiblesLogic.load(); // flag bootStrap as complete isBootstrapComplete = true; - // load initial view (replace empty initial view) - if (settingsLogic.hasCompletedOnboarding.value) { - appRouter.go(ScreenPaths.home); - } else { + // load initial view (replace empty initial view which is covered by a native splash screen) + bool showIntro = settingsLogic.hasCompletedOnboarding.value == false; + if (showIntro) { appRouter.go(ScreenPaths.intro); + } else { + appRouter.go(ScreenPaths.home); } } diff --git a/lib/ui/common/controls/diagonal_text_page_indicator.dart b/lib/ui/common/controls/diagonal_text_page_indicator.dart index f7fa0ee3..2d480fe2 100644 --- a/lib/ui/common/controls/diagonal_text_page_indicator.dart +++ b/lib/ui/common/controls/diagonal_text_page_indicator.dart @@ -1,4 +1,5 @@ import 'package:wonders/common_libs.dart'; +import 'package:wonders/ui/common/static_text_scale.dart'; class DiagonalTextPageIndicator extends StatelessWidget { const DiagonalTextPageIndicator({Key? key, required this.current, required this.total}) : super(key: key); @@ -11,46 +12,48 @@ class DiagonalTextPageIndicator extends StatelessWidget { //final textShadows = [Shadow(color: Colors.black.withOpacity(.5), offset: Offset(0, 4), blurRadius: 6)]; final textStyle = $styles.text.titleFont.copyWith(fontSize: _fontSize, height: 1); const size = _fontSize * 1.5; - return Padding( - padding: EdgeInsets.symmetric(horizontal: textStyle.fontSize! * .4).copyWith(top: textStyle.fontSize! * .2), - child: Stack(children: [ - ClipPath( - clipper: _DiagonalClipper(leftSide: true), - child: Transform.translate( - offset: Offset(-_fontSize * .7, 0), - child: SizedBox( + return StaticTextScale( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: textStyle.fontSize! * .4).copyWith(top: textStyle.fontSize! * .2), + child: Stack(children: [ + ClipPath( + clipper: _DiagonalClipper(leftSide: true), + child: Transform.translate( + offset: Offset(-_fontSize * .7, 0), + child: SizedBox( + width: size, + height: size, + child: Text('0$current', + style: textStyle.copyWith(shadows: $styles.shadows.text), textAlign: TextAlign.right)), + ), + ), + ClipPath( + clipper: _DiagonalClipper(leftSide: false), + child: Transform.translate( + offset: Offset(_fontSize * .45, _fontSize * .6), + child: SizedBox( width: size, height: size, - child: Text('0$current', - style: textStyle.copyWith(shadows: $styles.shadows.text), textAlign: TextAlign.right)), - ), - ), - ClipPath( - clipper: _DiagonalClipper(leftSide: false), - child: Transform.translate( - offset: Offset(_fontSize * .45, _fontSize * .6), - child: SizedBox( - width: size, - height: size, - child: Opacity( - opacity: .5, - child: Text( - '0$total', - style: textStyle.copyWith(shadows: $styles.shadows.textStrong), + child: Opacity( + opacity: .5, + child: Text( + '0$total', + style: textStyle.copyWith(shadows: $styles.shadows.textStrong), + ), ), ), ), ), - ), - Positioned.fill( - child: Center( - child: Transform.rotate( - angle: pi * -.25, - child: Container(height: 2, color: Colors.white), + Positioned.fill( + child: Center( + child: Transform.rotate( + angle: pi * -.25, + child: Container(height: 2, color: Colors.white), + ), ), ), - ), - ]), + ]), + ), ); } } diff --git a/lib/ui/common/static_text_scale.dart b/lib/ui/common/static_text_scale.dart new file mode 100644 index 00000000..5dd74a74 --- /dev/null +++ b/lib/ui/common/static_text_scale.dart @@ -0,0 +1,15 @@ +import 'package:wonders/common_libs.dart'; + +class StaticTextScale extends StatelessWidget { + const StaticTextScale({Key? key, required this.child, this.scale = 1}) : super(key: key); + final Widget child; + final double scale; + + @override + Widget build(BuildContext context) { + return MediaQuery( + data: MediaQuery.of(context).copyWith(textScaleFactor: scale), + child: child, + ); + } +} 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 4b81ed94..1bdc5426 100644 --- a/lib/ui/screens/artifact/artifact_carousel/artifact_carousel_screen.dart +++ b/lib/ui/screens/artifact/artifact_carousel/artifact_carousel_screen.dart @@ -5,6 +5,7 @@ import 'package:wonders/common_libs.dart'; import 'package:wonders/logic/data/highlight_data.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/static_text_scale.dart'; part 'widgets/_blurred_image_bg.dart'; part 'widgets/_carousel_item.dart'; @@ -184,12 +185,14 @@ class _ArtifactScreenState extends State { Container( height: small ? 90 : 110, alignment: Alignment.center, - child: Text( - artifact.title, - overflow: TextOverflow.ellipsis, - style: $styles.text.h2.copyWith(color: $styles.colors.black, height: 1.2), - textAlign: TextAlign.center, - maxLines: 2, + child: StaticTextScale( + child: Text( + artifact.title, + overflow: TextOverflow.ellipsis, + style: $styles.text.h2.copyWith(color: $styles.colors.black, height: 1.2), + textAlign: TextAlign.center, + maxLines: 2, + ), ), ), if (!small) Gap($styles.insets.xxs), 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 65716b8d..8d5751f8 100644 --- a/lib/ui/screens/artifact/artifact_search/artifact_search_screen.dart +++ b/lib/ui/screens/artifact/artifact_search/artifact_search_screen.dart @@ -5,6 +5,7 @@ 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/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'; @@ -129,39 +130,43 @@ class _ArtifactSearchScreenState extends State with GetItS Widget _buildStatusText(BuildContext context) { final TextStyle statusStyle = $styles.text.body.copyWith(color: $styles.colors.accent1); if (_searchResults.isEmpty) { - return Text( - $strings.artifactsSearchLabelNotFound, - textHeightBehavior: TextHeightBehavior(applyHeightToFirstAscent: false), - style: statusStyle, - textAlign: TextAlign.center, + return StaticTextScale( + child: Text( + $strings.artifactsSearchLabelNotFound, + textHeightBehavior: TextHeightBehavior(applyHeightToFirstAscent: false), + style: statusStyle, + textAlign: TextAlign.center, + ), ); } return MergeSemantics( - child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ - Gap($styles.insets.sm), - Text( - StringUtils.supplant( - $strings.artifactsSearchLabelFound, - { - '{numFound}': _searchResults.length.toString(), - '{numResults}': _filteredResults.length.toString(), - }, - ), - textHeightBehavior: TextHeightBehavior(applyHeightToFirstAscent: false), - style: statusStyle, - ), - AppBtn.basic( - semanticLabel: $strings.artifactsSearchButtonToggle, - onPressed: () => panelController.toggle(), - enableFeedback: false, // handled when panelController changes. - child: Text( - $strings.artifactsSearchSemanticTimeframe, + child: StaticTextScale( + child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ + Gap($styles.insets.sm), + Text( + StringUtils.supplant( + $strings.artifactsSearchLabelFound, + { + '{numFound}': _searchResults.length.toString(), + '{numResults}': _filteredResults.length.toString(), + }, + ), textHeightBehavior: TextHeightBehavior(applyHeightToFirstAscent: false), - style: statusStyle.copyWith(decoration: TextDecoration.underline), + style: statusStyle, ), - ), - Gap($styles.insets.sm), - ]), + AppBtn.basic( + semanticLabel: $strings.artifactsSearchButtonToggle, + onPressed: () => panelController.toggle(), + enableFeedback: false, // handled when panelController changes. + child: Text( + $strings.artifactsSearchSemanticTimeframe, + textHeightBehavior: TextHeightBehavior(applyHeightToFirstAscent: false), + style: statusStyle.copyWith(decoration: TextDecoration.underline), + ), + ), + Gap($styles.insets.sm), + ]), + ), ); } diff --git a/lib/ui/screens/editorial/editorial_screen.dart b/lib/ui/screens/editorial/editorial_screen.dart index 26d86240..d7d5dcf5 100644 --- a/lib/ui/screens/editorial/editorial_screen.dart +++ b/lib/ui/screens/editorial/editorial_screen.dart @@ -15,6 +15,7 @@ import 'package:wonders/ui/common/google_maps_marker.dart'; import 'package:wonders/ui/common/gradient_container.dart'; import 'package:wonders/ui/common/hidden_collectible.dart'; import 'package:wonders/ui/common/scaling_list_item.dart'; +import 'package:wonders/ui/common/static_text_scale.dart'; import 'package:wonders/ui/common/themed_text.dart'; import 'package:wonders/ui/common/utils/context_utils.dart'; import 'package:wonders/ui/wonder_illustrations/common/animated_clouds.dart'; diff --git a/lib/ui/screens/editorial/widgets/_collapsing_pull_quote_image.dart b/lib/ui/screens/editorial/widgets/_collapsing_pull_quote_image.dart index 2eec13a4..2d90c1c3 100644 --- a/lib/ui/screens/editorial/widgets/_collapsing_pull_quote_image.dart +++ b/lib/ui/screens/editorial/widgets/_collapsing_pull_quote_image.dart @@ -7,7 +7,6 @@ class _CollapsingPullQuoteImage extends StatelessWidget { @override Widget build(BuildContext context) { - final textScale = MediaQuery.of(context).textScaleFactor; // Start transitioning when we are halfway up the screen final collapseStartPx = context.heightPx * 1; final collapseEndPx = context.heightPx * .35; @@ -20,7 +19,7 @@ class _CollapsingPullQuoteImage extends StatelessWidget { var quoteSize = quoteStyle.fontSize; quoteStyle = quoteStyle.copyWith( color: $styles.colors.caption, - fontSize: (quoteSize ??= 36) / textScale, //dynamic font size for more consistent quote layout + fontSize: (quoteSize ??= 36), //dynamic font size for more consistent quote layout ); if (isAuthor) { quoteStyle = quoteStyle.copyWith(fontSize: 20, fontWeight: FontWeight.w600); @@ -91,19 +90,21 @@ class _CollapsingPullQuoteImage extends StatelessWidget { Positioned.fill( child: Container( margin: const EdgeInsets.symmetric(horizontal: 24), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox(height: 32), // push down vertical centre - buildText(data.pullQuote1Top, collapseAmt, top: true), - buildText(data.pullQuote1Bottom, collapseAmt, top: false), - if (data.pullQuote1Author.isNotEmpty) ...[ - Container( - margin: const EdgeInsets.only(top: 16), - child: buildText('- ${data.pullQuote1Author}', collapseAmt, top: false, isAuthor: true), - ) + child: StaticTextScale( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 32), // push down vertical centre + buildText(data.pullQuote1Top, collapseAmt, top: true), + buildText(data.pullQuote1Bottom, collapseAmt, top: false), + if (data.pullQuote1Author.isNotEmpty) ...[ + Container( + margin: const EdgeInsets.only(top: 16), + child: buildText('- ${data.pullQuote1Author}', collapseAmt, top: false, isAuthor: true), + ) + ], ], - ], + ), ), ), ), diff --git a/lib/ui/screens/editorial/widgets/_scrolling_content.dart b/lib/ui/screens/editorial/widgets/_scrolling_content.dart index 5c81d6d2..9acf8a99 100644 --- a/lib/ui/screens/editorial/widgets/_scrolling_content.dart +++ b/lib/ui/screens/editorial/widgets/_scrolling_content.dart @@ -26,7 +26,8 @@ class _ScrollingContent extends StatelessWidget { final TextStyle dropStyle = $styles.text.dropCase; final TextStyle bodyStyle = $styles.text.body; final String dropChar = value.substring(0, 1); - final double dropCapWidth = StringUtils.measure(dropChar, dropStyle).width; + final textScale = MediaQuery.of(context).textScaleFactor; + final double dropCapWidth = StringUtils.measure(dropChar, dropStyle).width * textScale; final bool isEnglish = localeLogic.strings.localeName == 'en'; //TODO EC: Helper method for localLogic.isEnglish? final bool skipCaps = !isEnglish || MediaQuery.of(context).accessibleNavigation; return Semantics( diff --git a/lib/ui/screens/editorial/widgets/_title_text.dart b/lib/ui/screens/editorial/widgets/_title_text.dart index 42515d05..69886906 100644 --- a/lib/ui/screens/editorial/widgets/_title_text.dart +++ b/lib/ui/screens/editorial/widgets/_title_text.dart @@ -9,70 +9,72 @@ class _TitleText extends StatelessWidget { Widget build(BuildContext context) => MergeSemantics( child: DefaultTextColor( color: $styles.colors.offWhite, - child: Column( - children: [ - Gap($styles.insets.md), - Gap(30), - SeparatedRow( - padding: EdgeInsets.symmetric(horizontal: $styles.insets.sm), - separatorBuilder: () => Gap($styles.insets.sm), - children: [ - Expanded( - child: Divider( - color: data.type.fgColor, - ).animate().scale(curve: Curves.easeOut, delay: 500.ms), - ), - Semantics( - header: true, - sortKey: OrdinalSortKey(1), - child: Text( - data.subTitle.toUpperCase(), - style: $styles.text.title2, - ).animate().fade(delay: 100.ms), - ), - Expanded( - child: Divider( - color: data.type.fgColor, - ).animate().scale(curve: Curves.easeOut, delay: 500.ms), - ), - ], - ), - Gap($styles.insets.md), - Semantics(sortKey: OrdinalSortKey(0), child: WonderTitleText(data)), - Gap($styles.insets.xs), - Text( - data.regionTitle.toUpperCase(), - style: $styles.text.title1, - textAlign: TextAlign.center, - ), - Gap($styles.insets.md), - ExcludeSemantics( - child: Padding( - padding: EdgeInsets.symmetric(horizontal: $styles.insets.md), - child: AnimatedBuilder( - animation: scroller, - builder: (_, __) => CompassDivider( - isExpanded: scroller.position.pixels <= 0, - linesColor: data.type.fgColor, - compassColor: $styles.colors.offWhite, + child: StaticTextScale( + child: Column( + children: [ + Gap($styles.insets.md), + Gap(30), + SeparatedRow( + padding: EdgeInsets.symmetric(horizontal: $styles.insets.sm), + separatorBuilder: () => Gap($styles.insets.sm), + children: [ + Expanded( + child: Divider( + color: data.type.fgColor, + ).animate().scale(curve: Curves.easeOut, delay: 500.ms), + ), + Semantics( + header: true, + sortKey: OrdinalSortKey(1), + child: Text( + data.subTitle.toUpperCase(), + style: $styles.text.title2, + ).animate().fade(delay: 100.ms), + ), + Expanded( + child: Divider( + color: data.type.fgColor, + ).animate().scale(curve: Curves.easeOut, delay: 500.ms), + ), + ], + ), + Gap($styles.insets.md), + Semantics(sortKey: OrdinalSortKey(0), child: WonderTitleText(data)), + Gap($styles.insets.xs), + Text( + data.regionTitle.toUpperCase(), + style: $styles.text.title1, + textAlign: TextAlign.center, + ), + Gap($styles.insets.md), + ExcludeSemantics( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: $styles.insets.md), + child: AnimatedBuilder( + animation: scroller, + builder: (_, __) => CompassDivider( + isExpanded: scroller.position.pixels <= 0, + linesColor: data.type.fgColor, + compassColor: $styles.colors.offWhite, + ), ), ), ), - ), - Gap($styles.insets.sm), - Text( - StringUtils.supplant( - $strings.titleLabelDate, - { - '{fromDate}': StringUtils.formatYr(data.startYr), - '{endDate}': StringUtils.formatYr(data.endYr), - }, + Gap($styles.insets.sm), + Text( + StringUtils.supplant( + $strings.titleLabelDate, + { + '{fromDate}': StringUtils.formatYr(data.startYr), + '{endDate}': StringUtils.formatYr(data.endYr), + }, + ), + style: $styles.text.h4, + textAlign: TextAlign.center, ), - style: $styles.text.h4, - textAlign: TextAlign.center, - ), - Gap($styles.insets.sm), - ], + Gap($styles.insets.sm), + ], + ), ), ), ); diff --git a/lib/ui/screens/intro/intro_screen.dart b/lib/ui/screens/intro/intro_screen.dart index 6f20a4b9..37955fef 100644 --- a/lib/ui/screens/intro/intro_screen.dart +++ b/lib/ui/screens/intro/intro_screen.dart @@ -2,6 +2,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:wonders/common_libs.dart'; import 'package:wonders/ui/common/app_icons.dart'; import 'package:wonders/ui/common/controls/app_page_indicator.dart'; +import 'package:wonders/ui/common/static_text_scale.dart'; import 'package:wonders/ui/common/themed_text.dart'; import 'package:wonders/ui/common/utils/app_haptics.dart'; @@ -208,13 +209,15 @@ class _Page extends StatelessWidget { SizedBox( height: _IntroScreenState._textHeight, width: _IntroScreenState._imageSize + $styles.insets.md, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text(data.title, style: $styles.text.wonderTitle.copyWith(fontSize: 24)), - Gap($styles.insets.sm), - Text(data.desc, style: $styles.text.body, textAlign: TextAlign.center), - ], + child: StaticTextScale( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(data.title, style: $styles.text.wonderTitle.copyWith(fontSize: 24)), + Gap($styles.insets.sm), + Text(data.desc, style: $styles.text.body, textAlign: TextAlign.center), + ], + ), ), ), Gap(_IntroScreenState._pageIndicatorHeight), @@ -234,9 +237,11 @@ class _WonderousLogo extends StatelessWidget { child: SvgPicture.asset(SvgPaths.compassSimple, color: $styles.colors.offWhite, height: 48), ), Gap($styles.insets.xs), - Text( - $strings.introSemanticWonderous, - style: $styles.text.wonderTitle.copyWith(fontSize: 32, color: $styles.colors.offWhite), + StaticTextScale( + child: Text( + $strings.introSemanticWonderous, + style: $styles.text.wonderTitle.copyWith(fontSize: 32, color: $styles.colors.offWhite), + ), ) ], ); diff --git a/pubspec.lock b/pubspec.lock index 87955950..41a4e88b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -272,6 +272,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.3.1" + flutter_displaymode: + dependency: "direct main" + description: + name: flutter_displaymode + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.0" flutter_driver: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index dfa3c275..8419f0ff 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -21,6 +21,7 @@ dependencies: flextras: ^0.0.2 flutter_animate: ^1.0.0 flutter_circular_text: ^0.3.1 + flutter_displaymode: ^0.4.0 flutter_inappwebview: ^5.4.3 flutter_native_splash: ^2.2.7 flutter_staggered_grid_view: ^0.6.2