diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 59babdcc..697bedf8 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1,5 +1,6 @@ { "appName": "Wonderous", + "localeSwapButton": "简体中文", "animatedArrowSemanticSwipe": "Explore details about {title}.", "appBarTitleFactsHistory": "Facts and History", "appBarTitleConstruction": "Construction", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index b3e8fd0e..31ac6c93 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -1,5 +1,6 @@ { "appName": "Wonderous", + "localeSwapButton": "English", "animatedArrowSemanticSwipe": "查看关于{title}的详细信息。", "appBarTitleFactsHistory": "历史与细节", "appBarTitleConstruction": "建造", diff --git a/lib/logic/app_logic.dart b/lib/logic/app_logic.dart index b1fd3e6f..1bc93ce3 100644 --- a/lib/logic/app_logic.dart +++ b/lib/logic/app_logic.dart @@ -30,8 +30,11 @@ class AppLogic { // Localizations await localeLogic.load(); + // Data load + wondersLogic.init(); + // Timeline - await timelineLogic.init(); + timelineLogic.init(); // Settings await settingsLogic.load(); diff --git a/lib/logic/locale_logic.dart b/lib/logic/locale_logic.dart index 9067fda9..509dd884 100644 --- a/lib/logic/locale_logic.dart +++ b/lib/logic/locale_logic.dart @@ -1,8 +1,7 @@ -import 'dart:ui'; - import 'package:flutter/foundation.dart'; -import 'package:intl/intl_standalone.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:intl/intl_standalone.dart'; +import 'package:wonders/common_libs.dart'; class LocaleLogic { AppLocalizations? _strings; @@ -10,6 +9,8 @@ class LocaleLogic { bool get isLoaded => _strings != null; + bool get isEnglish => strings.localeName == 'en'; + Future load() async { final localeCode = await findSystemLocale(); Locale locale = Locale(localeCode.split('_')[0]); @@ -20,6 +21,13 @@ class LocaleLogic { if (AppLocalizations.supportedLocales.contains(locale) == false) { locale = Locale('en'); } + settingsLogic.currentLocale.value = locale.languageCode; _strings = await AppLocalizations.delegate.load(locale); } + + Future refreshIfChanged(Locale locale) async { + if (_strings?.localeName != locale.languageCode && AppLocalizations.supportedLocales.contains(locale)) { + _strings = await AppLocalizations.delegate.load(locale); + } + } } diff --git a/lib/logic/settings_logic.dart b/lib/logic/settings_logic.dart index 451a1111..23a19059 100644 --- a/lib/logic/settings_logic.dart +++ b/lib/logic/settings_logic.dart @@ -1,4 +1,5 @@ import 'package:flutter/foundation.dart'; +import 'package:wonders/common_libs.dart'; import 'package:wonders/logic/common/save_load_mixin.dart'; class SettingsLogic with ThrottledSaveLoadMixin { @@ -7,6 +8,7 @@ class SettingsLogic with ThrottledSaveLoadMixin { late final hasCompletedOnboarding = ValueNotifier(false)..addListener(scheduleSave); late final hasDismissedSearchMessage = ValueNotifier(false)..addListener(scheduleSave); + late final currentLocale = ValueNotifier('en')..addListener(scheduleSave); final bool useBlurs = defaultTargetPlatform != TargetPlatform.android; @@ -23,4 +25,11 @@ class SettingsLogic with ThrottledSaveLoadMixin { 'hasDismissedSearchMessage': hasDismissedSearchMessage.value, }; } + + Future setLocale(Locale value) async { + currentLocale.value = value.languageCode; + await localeLogic.refreshIfChanged(value); + wondersLogic.init(); + timelineLogic.init(); + } } diff --git a/lib/logic/timeline_logic.dart b/lib/logic/timeline_logic.dart index 32dc2995..8e1e6808 100644 --- a/lib/logic/timeline_logic.dart +++ b/lib/logic/timeline_logic.dart @@ -3,18 +3,17 @@ import 'package:wonders/logic/common/string_utils.dart'; import 'package:wonders/logic/data/timeline_data.dart'; class TimelineLogic { - final List events = []; + List events = []; - Future init() async { - events.addAll(GlobalEventsData().globalEvents); - - for (var w in wondersLogic.all) { - events.add( - TimelineEvent( + void init() { + events = [ + ...GlobalEventsData().globalEvents, + ...wondersLogic.all.map( + (w) => TimelineEvent( w.startYr, StringUtils.supplant($strings.timelineLabelConstruction, {'{title}': w.title}), ), - ); - } + ) + ]; } } diff --git a/lib/logic/wonders_logic.dart b/lib/logic/wonders_logic.dart index 34362286..f84481c8 100644 --- a/lib/logic/wonders_logic.dart +++ b/lib/logic/wonders_logic.dart @@ -10,16 +10,7 @@ import 'package:wonders/logic/data/wonders_data/pyramids_giza_data.dart'; import 'package:wonders/logic/data/wonders_data/taj_mahal_data.dart'; class WondersLogic { - late List all = [ - GreatWallData(), - PetraData(), - ColosseumData(), - ChichenItzaData(), - MachuPicchuData(), - TajMahalData(), - ChristRedeemerData(), - PyramidsGizaData(), - ]; + List all = []; final int timelineStartYear = -3000; final int timelineEndYear = 2200; @@ -29,4 +20,17 @@ class WondersLogic { if (result == null) throw ('Could not find data for wonder type $value'); return result; } + + void init() { + all = [ + GreatWallData(), + PetraData(), + ColosseumData(), + ChichenItzaData(), + MachuPicchuData(), + TajMahalData(), + ChristRedeemerData(), + PyramidsGizaData(), + ]; + } } diff --git a/lib/main.dart b/lib/main.dart index fed31757..4b08f62e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -30,19 +30,25 @@ class WondersApp extends StatelessWidget { const WondersApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return MaterialApp.router( - debugShowCheckedModeBanner: false, - routerDelegate: appRouter.routerDelegate, - routeInformationProvider: appRouter.routeInformationProvider, - routeInformationParser: appRouter.routeInformationParser, - theme: ThemeData(fontFamily: $styles.text.body.fontFamily), - localizationsDelegates: const [ - AppLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - GlobalCupertinoLocalizations.delegate, - ], - supportedLocales: AppLocalizations.supportedLocales, + return ValueListenableBuilder( + valueListenable: settingsLogic.currentLocale, + builder: (_, localeCode, __) { + return MaterialApp.router( + locale: Locale(localeCode), + debugShowCheckedModeBanner: false, + routerDelegate: appRouter.routerDelegate, + routeInformationProvider: appRouter.routeInformationProvider, + routeInformationParser: appRouter.routeInformationParser, + theme: ThemeData(fontFamily: $styles.text.body.fontFamily), + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: AppLocalizations.supportedLocales, + ); + } ); } } diff --git a/lib/styles/styles.dart b/lib/styles/styles.dart index caf64d58..966452b0 100644 --- a/lib/styles/styles.dart +++ b/lib/styles/styles.dart @@ -134,6 +134,9 @@ class _Insets { @immutable class _Shadows { + final textSoft = [ + Shadow(color: Colors.black.withOpacity(.25), offset: Offset(0, 2), blurRadius: 4), + ]; final text = [ Shadow(color: Colors.black.withOpacity(.6), offset: Offset(0, 2), blurRadius: 2), ]; diff --git a/lib/ui/common/collectible_item.dart b/lib/ui/common/collectible_item.dart index 25f45bbf..5fa39dc0 100644 --- a/lib/ui/common/collectible_item.dart +++ b/lib/ui/common/collectible_item.dart @@ -52,13 +52,12 @@ class CollectibleItem extends StatelessWidget with GetItMixin { ), ) .animate(onPlay: (controller) => controller.repeat()) - // TODO SB (Aug 17, 2022): Temporarily removed on Jonahs request, due to a bug in Impeller which should be fixed soon. Re-enable when fixed. - //.shimmer(delay: 4000.ms, duration: $styles.times.med * 3) - .shake(delay: 4000.ms, duration: $styles.times.med * 3, curve: Curves.easeInOutCubic, hz: 4) + .shimmer(delay: 4000.ms, duration: $styles.times.med * 3) + .shake(curve: Curves.easeInOutCubic, hz: 4) .scale(begin: 1.0, end: 1.1, duration: $styles.times.med) .then(delay: $styles.times.med) .scale(begin: 1.0, end: 1 / 1.1), - ), + ), ), ), ); diff --git a/lib/ui/common/controls/diagonal_text_page_indicator.dart b/lib/ui/common/controls/diagonal_text_page_indicator.dart index 2d480fe2..4d62d346 100644 --- a/lib/ui/common/controls/diagonal_text_page_indicator.dart +++ b/lib/ui/common/controls/diagonal_text_page_indicator.dart @@ -5,7 +5,7 @@ class DiagonalTextPageIndicator extends StatelessWidget { const DiagonalTextPageIndicator({Key? key, required this.current, required this.total}) : super(key: key); final int current; final int total; - static const double _fontSize = 32; + static const double _fontSize = 26; @override Widget build(BuildContext context) { @@ -21,10 +21,7 @@ class DiagonalTextPageIndicator extends StatelessWidget { 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)), + width: size, height: size, child: Text('0$current', style: textStyle, textAlign: TextAlign.right)), ), ), ClipPath( @@ -38,7 +35,7 @@ class DiagonalTextPageIndicator extends StatelessWidget { opacity: .5, child: Text( '0$total', - style: textStyle.copyWith(shadows: $styles.shadows.textStrong), + style: textStyle, //.copyWith(shadows: $styles.shadows.textStrong), ), ), ), diff --git a/lib/ui/common/controls/locale_switcher.dart b/lib/ui/common/controls/locale_switcher.dart new file mode 100644 index 00000000..9150b9c2 --- /dev/null +++ b/lib/ui/common/controls/locale_switcher.dart @@ -0,0 +1,19 @@ +import 'package:wonders/common_libs.dart'; + +class LocaleSwitcher extends StatelessWidget with GetItMixin { + LocaleSwitcher({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final locale = watchX((SettingsLogic s) => s.currentLocale); + Future handleSwapLocale() async { + final newLocale = Locale(locale == 'en' ? 'zh' : 'en'); + await settingsLogic.setLocale(newLocale); + } + + return AppBtn.from( + padding: EdgeInsets.symmetric(vertical: $styles.insets.sm, horizontal: $styles.insets.sm), + text: $strings.localeSwapButton, + onPressed: handleSwapLocale); + } +} diff --git a/lib/ui/screens/artifact/artifact_search/widgets/_results_grid.dart b/lib/ui/screens/artifact/artifact_search/widgets/_results_grid.dart index d2c89da2..ee891aca 100644 --- a/lib/ui/screens/artifact/artifact_search/widgets/_results_grid.dart +++ b/lib/ui/screens/artifact/artifact_search/widgets/_results_grid.dart @@ -31,11 +31,10 @@ class _ResultsGrid extends StatelessWidget { } Widget _buildLanguageMessage(BuildContext context) { - bool isEnglish = localeLogic.strings.localeName == 'en'; return ValueListenableBuilder( valueListenable: settingsLogic.hasDismissedSearchMessage, builder: (_, value, __) { - if (isEnglish || value) return SizedBox(); + if (localeLogic.isEnglish || value) return SizedBox(); return AppBtn.basic( onPressed: () => settingsLogic.hasDismissedSearchMessage.value = true, semanticLabel: $strings.resultsSemanticDismiss, 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 2d90c1c3..3b24528e 100644 --- a/lib/ui/screens/editorial/widgets/_collapsing_pull_quote_image.dart +++ b/lib/ui/screens/editorial/widgets/_collapsing_pull_quote_image.dart @@ -9,7 +9,7 @@ class _CollapsingPullQuoteImage extends StatelessWidget { Widget build(BuildContext context) { // Start transitioning when we are halfway up the screen final collapseStartPx = context.heightPx * 1; - final collapseEndPx = context.heightPx * .35; + final collapseEndPx = context.heightPx * .15; const double imgHeight = 430; const double outerPadding = 100; diff --git a/lib/ui/screens/editorial/widgets/_scrolling_content.dart b/lib/ui/screens/editorial/widgets/_scrolling_content.dart index 9acf8a99..de320a02 100644 --- a/lib/ui/screens/editorial/widgets/_scrolling_content.dart +++ b/lib/ui/screens/editorial/widgets/_scrolling_content.dart @@ -28,8 +28,7 @@ class _ScrollingContent extends StatelessWidget { final String dropChar = value.substring(0, 1); 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; + final bool skipCaps = !localeLogic.isEnglish || MediaQuery.of(context).accessibleNavigation; return Semantics( label: value, child: !skipCaps diff --git a/lib/ui/screens/editorial/widgets/_title_text.dart b/lib/ui/screens/editorial/widgets/_title_text.dart index 69886906..948834a3 100644 --- a/lib/ui/screens/editorial/widgets/_title_text.dart +++ b/lib/ui/screens/editorial/widgets/_title_text.dart @@ -14,6 +14,8 @@ class _TitleText extends StatelessWidget { children: [ Gap($styles.insets.md), Gap(30), + + /// Sub-title row SeparatedRow( padding: EdgeInsets.symmetric(horizontal: $styles.insets.sm), separatorBuilder: () => Gap($styles.insets.sm), @@ -39,14 +41,23 @@ class _TitleText extends StatelessWidget { ], ), Gap($styles.insets.md), - Semantics(sortKey: OrdinalSortKey(0), child: WonderTitleText(data)), + + /// Wonder title text + Semantics( + sortKey: OrdinalSortKey(0), + child: WonderTitleText(data), + ), Gap($styles.insets.xs), + + /// Region Text( data.regionTitle.toUpperCase(), style: $styles.text.title1, textAlign: TextAlign.center, ), Gap($styles.insets.md), + + /// Compass divider ExcludeSemantics( child: Padding( padding: EdgeInsets.symmetric(horizontal: $styles.insets.md), @@ -61,6 +72,8 @@ class _TitleText extends StatelessWidget { ), ), Gap($styles.insets.sm), + + /// Date Text( StringUtils.supplant( $strings.titleLabelDate, diff --git a/lib/ui/screens/home/wonders_home_screen.dart b/lib/ui/screens/home/wonders_home_screen.dart index 06861261..b7743218 100644 --- a/lib/ui/screens/home/wonders_home_screen.dart +++ b/lib/ui/screens/home/wonders_home_screen.dart @@ -12,6 +12,7 @@ import 'package:wonders/ui/screens/home_menu/home_menu.dart'; import 'package:wonders/ui/wonder_illustrations/common/animated_clouds.dart'; import 'package:wonders/ui/wonder_illustrations/common/wonder_illustration.dart'; import 'package:wonders/ui/wonder_illustrations/common/wonder_illustration_config.dart'; +import 'package:wonders/ui/wonder_illustrations/common/wonder_title_text.dart'; part '_vertical_swipe_controller.dart'; part 'widgets/_animated_arrow_button.dart'; @@ -143,7 +144,7 @@ class _HomeScreenState extends State with SingleTickerProviderStateM Stack(children: [ /// Foreground gradient-1, gets darker when swiping up BottomCenter( - child: _buildSwipeableBgGradient(currentWonder.type.bgColor.withOpacity(.5)), + child: _buildSwipeableBgGradient(currentWonder.type.bgColor.withOpacity(.65)), ), /// Foreground decorators @@ -151,69 +152,72 @@ class _HomeScreenState extends State with SingleTickerProviderStateM /// Foreground gradient-2, gets darker when swiping up BottomCenter( - child: _buildSwipeableBgGradient(currentWonder.type.bgColor.withOpacity(.5)), + child: _buildSwipeableBgGradient(currentWonder.type.bgColor.withOpacity(1)), ), /// Floating controls / UI AnimatedSwitcher( duration: $styles.times.fast, child: RepaintBoundary( - child: OverflowBox( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox(width: double.infinity), - const Spacer(), + key: ObjectKey(currentWonder), + child: IgnorePointer( + ignoringSemantics: false, + child: OverflowBox( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(width: double.infinity), + const Spacer(), - /// Title Content - LightText( - child: MergeSemantics( - child: Column( - children: [ - /// Page indicator - IgnorePointer( - child: DiagonalTextPageIndicator(current: _wonderIndex + 1, total: _numWonders), + /// Title Content + LightText( + child: MergeSemantics( + child: Transform.translate( + offset: Offset(0, 30), + child: Column( + children: [ + WonderTitleText(currentWonder, enableShadows: true), + Gap($styles.insets.md), + AppPageIndicator( + count: _numWonders, + controller: _pageController, + color: $styles.colors.white, + dotSize: 8, + onDotPressed: _handlePageIndicatorDotPressed, + semanticPageTitle: $strings.homeSemanticWonder, + ), + Gap($styles.insets.md), + ], ), - Gap($styles.insets.sm), - - AppPageIndicator( - count: _numWonders, - controller: _pageController, - color: $styles.colors.white, - dotSize: 8, - onDotPressed: _handlePageIndicatorDotPressed, - semanticPageTitle: $strings.homeSemanticWonder, - ), - ], + ), ), ), - ), - Gap($styles.insets.xs), - /// Animated arrow and background - /// Wrap in a container that is full-width to make it easier to find for screen readers - MergeSemantics( - child: Container( - width: double.infinity, - alignment: Alignment.center, + /// Animated arrow and background + /// Wrap in a container that is full-width to make it easier to find for screen readers + MergeSemantics( + child: Container( + width: double.infinity, + alignment: Alignment.center, - /// Lose state of child objects when index changes, this will re-run all the animated switcher and the arrow anim - key: ValueKey(_wonderIndex), - child: Stack( - children: [ - /// Expanding rounded rect that grows in height as user swipes up - Positioned.fill( - child: _buildSwipeableArrowBg(), - ), + /// Lose state of child objects when index changes, this will re-run all the animated switcher and the arrow anim + key: ValueKey(_wonderIndex), + child: Stack( + children: [ + /// Expanding rounded rect that grows in height as user swipes up + Positioned.fill( + child: _buildSwipeableArrowBg(), + ), - /// Arrow Btn that fades in and out - _AnimatedArrowButton(onTap: _showDetailsPage, semanticTitle: currentWonder.title), - ], + /// Arrow Btn that fades in and out + _AnimatedArrowButton(onTap: _showDetailsPage, semanticTitle: currentWonder.title), + ], + ), ), ), - ), - Gap($styles.insets.md), - ], + Gap($styles.insets.md), + ], + ), ), ), ), @@ -306,7 +310,7 @@ class _HomeScreenState extends State with SingleTickerProviderStateM return _swipeController.buildListener(builder: (swipeAmt, isPointerDown, _) { return IgnorePointer( child: FractionallySizedBox( - heightFactor: .5, + heightFactor: .6, child: Container( decoration: BoxDecoration( gradient: LinearGradient( @@ -314,7 +318,7 @@ class _HomeScreenState extends State with SingleTickerProviderStateM end: Alignment.bottomCenter, colors: [ fgColor.withOpacity(0), - fgColor.withOpacity(fgColor.opacity * .75 + (isPointerDown ? .05 : 0) + swipeAmt * .20), + fgColor.withOpacity(.5 + fgColor.opacity * .25 + (isPointerDown ? .05 : 0) + swipeAmt * .20), ], stops: const [0, 1], ), diff --git a/lib/ui/screens/home_menu/home_menu.dart b/lib/ui/screens/home_menu/home_menu.dart index 6b023cdf..138e0694 100644 --- a/lib/ui/screens/home_menu/home_menu.dart +++ b/lib/ui/screens/home_menu/home_menu.dart @@ -4,6 +4,7 @@ import 'package:wonders/common_libs.dart'; 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/controls/locale_switcher.dart'; import 'package:wonders/ui/screens/home_menu/about_dialog_content.dart'; class HomeMenu extends StatelessWidget { @@ -49,11 +50,23 @@ class HomeMenu extends StatelessWidget { ), ), - /// Back btn - BackBtn.close( - bgColor: Colors.transparent, - iconColor: $styles.colors.offWhite, - ).safe(), + SafeArea( + child: PaddedRow( + padding: EdgeInsets.symmetric( + horizontal: $styles.insets.md, + vertical: $styles.insets.sm, + ), + children: [ + /// Back btn + BackBtn.close( + bgColor: Colors.transparent, + iconColor: $styles.colors.offWhite, + ), + Spacer(), + LocaleSwitcher() + ], + ), + ), /// Content Positioned.fill( @@ -75,7 +88,7 @@ class HomeMenu extends StatelessWidget { ), ), ), - ) + ), ], ); } @@ -106,31 +119,35 @@ class HomeMenu extends StatelessWidget { } Widget _buildBottomBtns(BuildContext context) { - return SeparatedColumn( - separatorBuilder: () => Divider(thickness: 1.5, height: 1).animate().scale( - duration: $styles.times.slow, - delay: $styles.times.pageTransition + 200.ms, - curve: Curves.easeOutBack, - ), - children: [ - _MenuTextBtn( - label: $strings.homeMenuButtonExplore, - icon: AppIcons.timeline, - onPressed: () => _handleTimelinePressed(context)), - _MenuTextBtn( - label: $strings.homeMenuButtonView, - icon: AppIcons.collection, - onPressed: () => _handleCollectionPressed(context)), - _MenuTextBtn( - label: $strings.homeMenuButtonAbout, - icon: AppIcons.info, - onPressed: () => _handleAboutPressed(context), - ), - ] - .animate(interval: 50.ms) - .fade(delay: $styles.times.pageTransition + 50.ms) - .slide(begin: Offset(0, .1), curve: Curves.easeOut), - ); + return ValueListenableBuilder( + valueListenable: settingsLogic.currentLocale, + builder: (_, __, ___) { + return SeparatedColumn( + separatorBuilder: () => Divider(thickness: 1.5, height: 1).animate().scale( + duration: $styles.times.slow, + delay: $styles.times.pageTransition + 200.ms, + curve: Curves.easeOutBack, + ), + children: [ + _MenuTextBtn( + label: $strings.homeMenuButtonExplore, + icon: AppIcons.timeline, + onPressed: () => _handleTimelinePressed(context)), + _MenuTextBtn( + label: $strings.homeMenuButtonView, + icon: AppIcons.collection, + onPressed: () => _handleCollectionPressed(context)), + _MenuTextBtn( + label: $strings.homeMenuButtonAbout, + icon: AppIcons.info, + onPressed: () => _handleAboutPressed(context), + ), + ] + .animate(interval: 50.ms) + .fade(delay: $styles.times.pageTransition + 50.ms) + .slide(begin: Offset(0, .1), curve: Curves.easeOut), + ); + }); } Widget _buildGridBtn(BuildContext context, WonderData btnData) { diff --git a/lib/ui/screens/intro/intro_screen.dart b/lib/ui/screens/intro/intro_screen.dart index 37955fef..d0afe413 100644 --- a/lib/ui/screens/intro/intro_screen.dart +++ b/lib/ui/screens/intro/intro_screen.dart @@ -19,11 +19,7 @@ class _IntroScreenState extends State { static const double _textHeight = 155; static const double _pageIndicatorHeight = 55; - static List<_PageData> pageData = [ - _PageData($strings.introTitleJourney, $strings.introDescriptionNavigate, 'camel', '1'), - _PageData($strings.introTitleExplore, $strings.introDescriptionUncover, 'petra', '2'), - _PageData($strings.introTitleDiscover, $strings.introDescriptionLearn, 'statue', '3'), - ]; + static List<_PageData> pageData = []; late final PageController _pageController = PageController()..addListener(_handlePageChanged); final ValueNotifier _currentPage = ValueNotifier(0); @@ -51,6 +47,13 @@ class _IntroScreenState extends State { @override Widget build(BuildContext context) { + // Set the page data, as strings may have changed based on locale + pageData = [ + _PageData($strings.introTitleJourney, $strings.introDescriptionNavigate, 'camel', '1'), + _PageData($strings.introTitleExplore, $strings.introDescriptionUncover, 'petra', '2'), + _PageData($strings.introTitleDiscover, $strings.introDescriptionLearn, 'statue', '3'), + ]; + // This view uses a full screen PageView to enable swipe navigation. // However, we only want the title / description to actually swipe, // so we stack a PageView with that content over top of all the other diff --git a/lib/ui/wonder_illustrations/common/wonder_title_text.dart b/lib/ui/wonder_illustrations/common/wonder_title_text.dart index e07e796f..a16e638c 100644 --- a/lib/ui/wonder_illustrations/common/wonder_title_text.dart +++ b/lib/ui/wonder_illustrations/common/wonder_title_text.dart @@ -17,7 +17,7 @@ class WonderTitleText extends StatelessWidget { ); bool smallText = [WonderType.christRedeemer, WonderType.colosseum].contains(data.type); if (smallText) { - textStyle = textStyle.copyWith(fontSize: 48); + textStyle = textStyle.copyWith(fontSize: 56); } // First, get a list like: ['the\n', 'great wall'] @@ -40,12 +40,15 @@ class WonderTitleText extends StatelessWidget { ); } - List shadows = enableShadows ? $styles.shadows.text : []; - return RichText( - textAlign: TextAlign.center, - text: TextSpan( - style: textStyle.copyWith(shadows: shadows), - children: pieces.map(buildTextSpan).toList(), + List shadows = enableShadows ? $styles.shadows.textSoft : []; + return Hero( + tag: 'wonderTitle-$title', + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + style: textStyle.copyWith(shadows: shadows), + children: pieces.map(buildTextSpan).toList(), + ), ), ); } diff --git a/lib/ui/wonder_illustrations/taj_mahal_illustration.dart b/lib/ui/wonder_illustrations/taj_mahal_illustration.dart index 93f52a2e..fbe9dbbb 100644 --- a/lib/ui/wonder_illustrations/taj_mahal_illustration.dart +++ b/lib/ui/wonder_illustrations/taj_mahal_illustration.dart @@ -56,17 +56,20 @@ class TajMahalIllustration extends StatelessWidget { alignment: Alignment(0, config.shortMode ? 1 : -.15), child: FractionallySizedBox( widthFactor: config.shortMode ? 1 : 1.7, - child: WonderHero(config, 'taj-mg', - child: Stack( - children: [ - Image.asset('$assetPath/taj-mahal.png', opacity: anim, fit: BoxFit.cover), - if (!config.shortMode) - FractionalTranslation( - translation: Offset(0, 1.33), - child: Image.asset('$assetPath/pool.png', opacity: anim, fit: BoxFit.cover), - ), - ], - )), + child: Stack( + children: [ + WonderHero( + config, + 'taj-mg', + child: Image.asset('$assetPath/taj-mahal.png', opacity: anim, fit: BoxFit.cover), + ), + if (!config.shortMode) + FractionalTranslation( + translation: Offset(0, 1.33), + child: Image.asset('$assetPath/pool.png', opacity: anim, fit: BoxFit.cover), + ), + ], + ), ), ), ) diff --git a/release_notes.txt b/release_notes.txt index 7c5a0593..8083fe0a 100644 --- a/release_notes.txt +++ b/release_notes.txt @@ -1,6 +1,9 @@ # 1.9.0 - Improved support for dynamic text scaling - Improved performance for blend modes and blurs +- Added LocalSwitcher btn in the main Wonders Menu +- Request higher preferred FPS for Android devices +- Fix rendering issues with Chinese fonts # 1.8.0 - Initial release \ No newline at end of file