diff --git a/lib/ui/common/previous_next_navigation.dart b/lib/ui/common/previous_next_navigation.dart index 1b7a79c9..663f9f51 100644 --- a/lib/ui/common/previous_next_navigation.dart +++ b/lib/ui/common/previous_next_navigation.dart @@ -4,10 +4,20 @@ import 'package:wonders/ui/common/app_icons.dart'; import 'package:wonders/ui/common/fullscreen_keyboard_listener.dart'; class PreviousNextNavigation extends StatelessWidget { - const PreviousNextNavigation({super.key, this.onPreviousPressed, this.onNextPressed, required this.child}); + const PreviousNextNavigation( + {super.key, + required this.onPreviousPressed, + required this.onNextPressed, + required this.child, + this.maxWidth = 1000, + this.nextBtnColor, + this.previousBtnColor}); final VoidCallback? onPreviousPressed; final VoidCallback? onNextPressed; + final Color? nextBtnColor; + final Color? previousBtnColor; final Widget child; + final double? maxWidth; bool _handleKeyDown(KeyDownEvent event) { if (event.logicalKey == LogicalKeyboardKey.arrowLeft && onPreviousPressed != null) { @@ -23,32 +33,40 @@ class PreviousNextNavigation extends StatelessWidget { @override Widget build(BuildContext context) { - Widget buildBtn(String semanticLabel, VoidCallback? onPressed, Alignment align, {bool isNext = false}) { - if (PlatformInfo.isMobile) return child; - return FullScreenKeyboardListener( - onKeyDown: _handleKeyDown, - child: Align( - alignment: align, - child: Padding( - padding: EdgeInsets.symmetric(horizontal: $styles.insets.sm), - child: CircleIconBtn( - icon: AppIcons.prev, - onPressed: onPressed, - semanticLabel: semanticLabel, - flipIcon: isNext, + if (PlatformInfo.isMobile) return child; + return FullscreenKeyboardListener( + onKeyDown: _handleKeyDown, + child: Stack( + children: [ + child, + Center( + child: SizedBox( + width: maxWidth ?? double.infinity, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: $styles.insets.sm), + child: Row( + children: [ + CircleIconBtn( + icon: AppIcons.prev, + onPressed: onPreviousPressed, + semanticLabel: 'Previous', + bgColor: previousBtnColor, + ), + Spacer(), + CircleIconBtn( + icon: AppIcons.prev, + onPressed: onNextPressed, + semanticLabel: 'Next', + flipIcon: true, + bgColor: nextBtnColor, + ) + ], + ), + ), ), ), - ), - ); - } - - return Stack( - children: [ - child, - //TODO-LOC: Add localization - buildBtn('previous', onPreviousPressed, Alignment.centerLeft), - buildBtn('next', onNextPressed, Alignment.centerRight, isNext: true), - ], + ], + ), ); } } diff --git a/lib/ui/screens/intro/intro_screen.dart b/lib/ui/screens/intro/intro_screen.dart index 56e620ac..b374b028 100644 --- a/lib/ui/screens/intro/intro_screen.dart +++ b/lib/ui/screens/intro/intro_screen.dart @@ -1,9 +1,11 @@ import 'package:flutter/gestures.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:wonders/common_libs.dart'; - import 'package:wonders/ui/common/app_icons.dart'; +import 'package:wonders/logic/common/platform_info.dart'; +import 'package:wonders/ui/common/app_icons.dart'; import 'package:wonders/ui/common/controls/app_page_indicator.dart'; import 'package:wonders/ui/common/gradient_container.dart'; +import 'package:wonders/ui/common/previous_next_navigation.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'; @@ -24,13 +26,14 @@ class _IntroScreenState extends State { static List<_PageData> pageData = []; late final PageController _pageController = PageController()..addListener(_handlePageChanged); - final ValueNotifier _currentPage = ValueNotifier(0); + late final ValueNotifier _currentPage = ValueNotifier(0)..addListener(() => setState(() {})); bool get _isOnLastPage => _currentPage.value.round() == pageData.length - 1; bool get _isOnFirstPage => _currentPage.value.round() == 0; @override void dispose() { _pageController.dispose(); + _currentPage.dispose(); super.dispose(); } @@ -53,15 +56,13 @@ class _IntroScreenState extends State { void _handleNavTextSemanticTap() => _incrementPage(1); - void _incrementPage(int dir){ + void _incrementPage(int dir) { final int current = _pageController.page!.round(); if (_isOnLastPage && dir > 0) return; if (_isOnFirstPage && dir < 0) return; _pageController.animateToPage(current + dir, duration: 250.ms, curve: Curves.easeIn); } - void _handleScrollWheel(double delta) => _incrementPage(delta >0? 1 : -1); - @override Widget build(BuildContext context) { // Set the page data, as strings may have changed based on locale @@ -78,20 +79,25 @@ class _IntroScreenState extends State { final List pages = pageData.map((e) => _Page(data: e)).toList(); /// Return resulting widget tree - return Listener( - onPointerSignal: (signal){ - if(signal is PointerScrollEvent){ - _handleScrollWheel(signal.scrollDelta.dy); - } - }, - child: DefaultTextColor( - color: $styles.colors.offWhite, - child: Container( - color: $styles.colors.black, - child: SafeArea( - child: Animate( - delay: 500.ms, - effects: const [FadeEffect()], + return DefaultTextColor( + color: $styles.colors.offWhite, + child: ColoredBox( + color: $styles.colors.black, + child: SafeArea( + child: Animate( + delay: 500.ms, + effects: const [FadeEffect()], + child: PreviousNextNavigation( + maxWidth: 600, + nextBtnColor: _isOnLastPage ? $styles.colors.accent1 : null, + onPreviousPressed: _isOnFirstPage ? null : () => _incrementPage(-1), + onNextPressed: () { + if (_isOnLastPage) { + _handleIntroCompletePressed(); + } else { + _incrementPage(1); + } + }, child: Stack( children: [ // page view with title & description: @@ -159,20 +165,15 @@ class _IntroScreenState extends State { _buildHzGradientOverlay(left: true), _buildHzGradientOverlay(), - // finish button: - Positioned( - right: $styles.insets.lg, - bottom: $styles.insets.lg, - child: _buildFinishBtn(context), - ), - // nav help text: - BottomCenter( - child: Padding( - padding: EdgeInsets.only(bottom: $styles.insets.lg), - child: _buildNavText(context), + if (PlatformInfo.isMobile) ...[ + BottomCenter( + child: Padding( + padding: EdgeInsets.only(bottom: $styles.insets.lg), + child: _buildNavText(context), + ), ), - ), + ] ], ), ), @@ -203,24 +204,6 @@ class _IntroScreenState extends State { ); } - Widget _buildFinishBtn(BuildContext context) { - return ValueListenableBuilder( - valueListenable: _currentPage, - builder: (_, pageIndex, __) { - return AnimatedOpacity( - opacity: pageIndex == pageData.length - 1 ? 1 : 0, - duration: $styles.times.fast, - child: CircleIconBtn( - icon: AppIcons.next_large, - bgColor: $styles.colors.accent1, - onPressed: _handleIntroCompletePressed, - semanticLabel: $strings.introSemanticEnterApp, - ), - ); - }, - ); - } - Widget _buildNavText(BuildContext context) { return ValueListenableBuilder( valueListenable: _currentPage,