From d7be3e5d483c33d12469f4c397f3ae3b41e157ac Mon Sep 17 00:00:00 2001 From: Efrain Bastidas Date: Sun, 26 Nov 2023 21:43:31 -0500 Subject: [PATCH] [Presentation] Minor ui improvements --- .../lib/presentation/intro/intro_page.dart | 259 +++++++++--------- CastIt.Client/lib/presentation/main_page.dart | 6 +- .../presentation/playlist/playlist_page.dart | 2 +- .../shared/common_bottom_sheet.dart | 6 +- .../extensions/app_theme_type_extensions.dart | 3 +- .../shared/modal_sheet_separator.dart | 2 +- .../presentation/shared/nothing_found.dart | 2 +- 7 files changed, 141 insertions(+), 139 deletions(-) diff --git a/CastIt.Client/lib/presentation/intro/intro_page.dart b/CastIt.Client/lib/presentation/intro/intro_page.dart index 5766b6d1..025869e4 100644 --- a/CastIt.Client/lib/presentation/intro/intro_page.dart +++ b/CastIt.Client/lib/presentation/intro/intro_page.dart @@ -32,6 +32,9 @@ class _IntroPageState extends State { @override Widget build(BuildContext context) { + final theme = Theme.of(context); + final i18n = S.of(context); + return BlocConsumer( listener: (ctx, state) { state.maybeMap( @@ -44,88 +47,40 @@ class _IntroPageState extends State { ); }, builder: (ctx, state) => Scaffold( - body: _buildPage(state), - bottomSheet: _buildBottomSheet(state), - ), - ); - } - - @override - void dispose() { - super.dispose(); - _pageController.dispose(); - } - - Widget _buildPage(IntroState state) { - final i18n = S.of(context); - return state.map( - loading: (_) => PageView(), - loaded: (s) => PageView( - controller: _pageController, - onPageChanged: (index) => context.read().add(IntroEvent.changePage(newPage: index)), - children: [ - IntroPageItem( - mainTitle: i18n.welcome(i18n.appName), - subTitle: i18n.aboutSummary, - content: i18n.welcomeSummary, - extraContent: _buildLanguageSettings(s.currentLang), - ), - IntroPageItem( - mainTitle: i18n.webServerUrl, - subTitle: s.currentCastItUrl, - content: i18n.youCanSkip, - ), - IntroPageItem( - mainTitle: i18n.welcome(i18n.appName), - subTitle: i18n.aboutSummary, - content: i18n.enjoyTheApp, + body: state.map( + loading: (_) => PageView(), + loaded: (s) => PageView( + controller: _pageController, + onPageChanged: (index) => context.read().add(IntroEvent.changePage(newPage: index)), + children: [ + IntroPageItem( + mainTitle: i18n.welcome(i18n.appName), + subTitle: i18n.aboutSummary, + content: i18n.welcomeSummary, + extraContent: _LanguageSettings(currentLang: s.currentLang), + ), + IntroPageItem( + mainTitle: i18n.webServerUrl, + subTitle: s.currentCastItUrl, + content: i18n.youCanSkip, + ), + IntroPageItem( + mainTitle: i18n.welcome(i18n.appName), + subTitle: i18n.aboutSummary, + content: i18n.enjoyTheApp, + ), + ], ), - ], - ), - ); - } - - Widget? _buildBottomSheet(IntroState state) { - return state.map( - loading: (_) => null, - loaded: (s) { - final theme = Theme.of(context); - final i18n = S.of(context); - return s.page != 2 - ? Container( - margin: const EdgeInsets.symmetric(vertical: 5), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - TextButton( - onPressed: () async { - await _showSkipDialog(); - }, - child: Text( - i18n.skip.toUpperCase(), - style: TextStyle(color: theme.colorScheme.secondary, fontWeight: FontWeight.w600), - ), - ), - Row( - children: [ - for (int i = 0; i < _maxNumberOfPages; i++) i == s.page ? _buildPageIndicator(true) : _buildPageIndicator(false), - ], - ), - TextButton( - onPressed: () => _onNext(s.page, s.currentCastItUrl), - child: Text( - i18n.next.toUpperCase(), - style: TextStyle(color: theme.colorScheme.secondary, fontWeight: FontWeight.w600), - ), - ), - ], - ), - ) - : InkWell( + ), + bottomSheet: state.map( + loading: (_) => null, + loaded: (s) { + if (s.page == _maxNumberOfPages - 1) { + return InkWell( onTap: _onStart, child: Container( height: 60, - color: theme.colorScheme.secondary, + color: theme.colorScheme.primary, alignment: Alignment.center, child: Text( i18n.start.toUpperCase(), @@ -133,63 +88,43 @@ class _IntroPageState extends State { ), ), ); - }, - ); - } + } - Widget _buildPageIndicator(bool isCurrentPage) { - final theme = Theme.of(context); - return Container( - margin: const EdgeInsets.symmetric(horizontal: 2.0), - height: isCurrentPage ? 10.0 : 6.0, - width: isCurrentPage ? 10.0 : 6.0, - decoration: BoxDecoration( - color: isCurrentPage ? theme.colorScheme.secondary : Colors.grey[300], - borderRadius: BorderRadius.circular(12), + return Container( + margin: const EdgeInsets.symmetric(vertical: 5), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TextButton( + onPressed: () => _showSkipDialog(), + child: Text( + i18n.skip.toUpperCase(), + style: TextStyle(color: theme.colorScheme.secondary, fontWeight: FontWeight.w600), + ), + ), + Row( + children: Iterable.generate(_maxNumberOfPages, (i) => _PageIndicator(isCurrentPage: i == s.page)).toList(), + ), + TextButton( + onPressed: () => _onNext(s.page, s.currentCastItUrl), + child: Text( + i18n.next.toUpperCase(), + style: TextStyle(color: theme.colorScheme.secondary, fontWeight: FontWeight.w600), + ), + ), + ], + ), + ); + }, + ), ), ); } - Widget _buildLanguageSettings(AppLanguageType currentLang) { - final i18n = S.of(context); - final dropdown = [AppLanguageType.english, AppLanguageType.spanish] - .map>( - (lang) => DropdownMenuItem( - value: lang, - child: Text( - i18n.translateAppLanguageType(lang), - ), - ), - ) - .toList(); - - final content = Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Row( - children: [ - const Icon(Icons.language), - Container( - margin: const EdgeInsets.only(left: 5), - child: Text(i18n.language, style: Theme.of(context).textTheme.titleLarge), - ), - ], - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: DropdownButton( - isExpanded: true, - hint: Text(i18n.chooseLanguage), - value: currentLang, - underline: Container(height: 0, color: Colors.transparent), - onChanged: (newValue) => context.read().add(SettingsEvent.languageChanged(lang: newValue!)), - items: dropdown, - ), - ), - ], - ); - - return content; + @override + void dispose() { + super.dispose(); + _pageController.dispose(); } void _showUrlModal(String castItUrl) { @@ -240,3 +175,67 @@ class _IntroPageState extends State { void _onStart() => context.read().add(MainEvent.introCompleted()); } + +class _PageIndicator extends StatelessWidget { + final bool isCurrentPage; + + const _PageIndicator({required this.isCurrentPage}); + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + return Container( + margin: const EdgeInsets.symmetric(horizontal: 2.0), + height: isCurrentPage ? 10.0 : 6.0, + width: isCurrentPage ? 10.0 : 6.0, + decoration: BoxDecoration( + color: isCurrentPage ? theme.colorScheme.primary : theme.colorScheme.secondary, + borderRadius: BorderRadius.circular(12), + ), + ); + } +} + +class _LanguageSettings extends StatelessWidget { + final AppLanguageType currentLang; + + const _LanguageSettings({required this.currentLang}); + + @override + Widget build(BuildContext context) { + final i18n = S.of(context); + + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Row( + children: [ + const Icon(Icons.language), + Container( + margin: const EdgeInsets.only(left: 5), + child: Text(i18n.language, style: Theme.of(context).textTheme.titleLarge), + ), + ], + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: DropdownButton( + isExpanded: true, + hint: Text(i18n.chooseLanguage), + value: currentLang, + underline: Container(height: 0, color: Colors.transparent), + onChanged: (newValue) => context.read().add(SettingsEvent.languageChanged(lang: newValue!)), + items: AppLanguageType.values + .map>( + (lang) => DropdownMenuItem( + value: lang, + child: Text(i18n.translateAppLanguageType(lang)), + ), + ) + .toList(), + ), + ), + ], + ); + } +} diff --git a/CastIt.Client/lib/presentation/main_page.dart b/CastIt.Client/lib/presentation/main_page.dart index b2b104e2..0d29021b 100644 --- a/CastIt.Client/lib/presentation/main_page.dart +++ b/CastIt.Client/lib/presentation/main_page.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:castit/application/bloc.dart'; import 'package:castit/domain/enums/enums.dart'; import 'package:castit/generated/l10n.dart'; @@ -42,7 +44,9 @@ class _MainPageState extends State with WidgetsBindingObserver { @override void didChangeAppLifecycleState(AppLifecycleState state) { debugPrint('State = $state'); - if (state == AppLifecycleState.inactive) { + final bool disconnect = (state == AppLifecycleState.paused && (Platform.isAndroid || Platform.isIOS)) || + (state == AppLifecycleState.hidden && (Platform.isMacOS || Platform.isWindows)); + if (disconnect) { _canShowConnectionModal = false; context.read().add(ServerWsEvent.disconnectFromWs()); } else if (state == AppLifecycleState.resumed) { diff --git a/CastIt.Client/lib/presentation/playlist/playlist_page.dart b/CastIt.Client/lib/presentation/playlist/playlist_page.dart index ef51cd8c..dc05f14d 100644 --- a/CastIt.Client/lib/presentation/playlist/playlist_page.dart +++ b/CastIt.Client/lib/presentation/playlist/playlist_page.dart @@ -35,7 +35,7 @@ class PlayListPage extends StatefulWidget { class _PlayListPageState extends State with SingleTickerProviderStateMixin { final _refreshController = RefreshController(); final _listViewScrollController = ScrollController(); - final _itemHeight = 75.0; + final _itemHeight = 80.0; bool isFabVisible = true; @override diff --git a/CastIt.Client/lib/presentation/shared/common_bottom_sheet.dart b/CastIt.Client/lib/presentation/shared/common_bottom_sheet.dart index 901e8079..9085aa31 100644 --- a/CastIt.Client/lib/presentation/shared/common_bottom_sheet.dart +++ b/CastIt.Client/lib/presentation/shared/common_bottom_sheet.dart @@ -30,7 +30,6 @@ class CommonBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = Theme.of(context); final s = S.of(context); return SingleChildScrollView( padding: MediaQuery.of(context).viewInsets, @@ -49,12 +48,13 @@ class CommonBottomSheet extends StatelessWidget { buttonPadding: const EdgeInsets.symmetric(horizontal: 10), children: [ if (showCancelButton) - OutlinedButton( + ElevatedButton( onPressed: onCancel != null ? () => onCancel!() : () => _cancel(context), - child: Text(cancelText ?? s.cancel, style: TextStyle(color: theme.primaryColor)), + child: Text(cancelText ?? s.cancel), ), if (showOkButton) ElevatedButton( + autofocus: true, onPressed: onOk != null ? () => onOk!() : null, child: Text(okText ?? s.ok), ), diff --git a/CastIt.Client/lib/presentation/shared/extensions/app_theme_type_extensions.dart b/CastIt.Client/lib/presentation/shared/extensions/app_theme_type_extensions.dart index ea280c49..07534cbf 100644 --- a/CastIt.Client/lib/presentation/shared/extensions/app_theme_type_extensions.dart +++ b/CastIt.Client/lib/presentation/shared/extensions/app_theme_type_extensions.dart @@ -22,13 +22,12 @@ extension AppThemeTypeExtensions on AppAccentColorType { return Colors.purple; case AppAccentColorType.deepPurple: return Colors.deepPurple; - case AppAccentColorType.grey: - return Colors.grey; case AppAccentColorType.orange: return Colors.orange; case AppAccentColorType.yellow: return Colors.yellow; case AppAccentColorType.blueGrey: + case AppAccentColorType.grey: return Colors.blueGrey; case AppAccentColorType.teal: return Colors.teal; diff --git a/CastIt.Client/lib/presentation/shared/modal_sheet_separator.dart b/CastIt.Client/lib/presentation/shared/modal_sheet_separator.dart index 81a3e62d..3b9769dc 100644 --- a/CastIt.Client/lib/presentation/shared/modal_sheet_separator.dart +++ b/CastIt.Client/lib/presentation/shared/modal_sheet_separator.dart @@ -12,7 +12,7 @@ class ModalSheetSeparator extends StatelessWidget { height: 10, child: DecoratedBox( decoration: BoxDecoration( - color: theme.primaryColor, + color: theme.colorScheme.primary, borderRadius: BorderRadius.circular(20), ), ), diff --git a/CastIt.Client/lib/presentation/shared/nothing_found.dart b/CastIt.Client/lib/presentation/shared/nothing_found.dart index 5ad0fbeb..bbc7afd3 100644 --- a/CastIt.Client/lib/presentation/shared/nothing_found.dart +++ b/CastIt.Client/lib/presentation/shared/nothing_found.dart @@ -24,7 +24,7 @@ class NothingFound extends StatelessWidget { children: [ Icon( icon, - color: theme.primaryColor, + color: theme.colorScheme.primary, size: 60, ), Text(