diff --git a/data/lib/service/user/user_service.dart b/data/lib/service/user/user_service.dart index a1a2b72f..549a3a94 100644 --- a/data/lib/service/user/user_service.dart +++ b/data/lib/service/user/user_service.dart @@ -80,13 +80,23 @@ class UserService { for (final tenIds in ids.chunked(10)) { QuerySnapshot> snapshot = await _firestore .collection(FireStoreConst.usersCollection) - .where('id', whereIn: tenIds) + .where(FireStoreConst.id, whereIn: tenIds) .get(); users.addAll(snapshot.docs.map((doc) { final data = doc.data(); return UserModel.fromJson(data).copyWith(id: doc.id); }).toList()); + + final deactivatedUserIds = + tenIds.where((id) => !users.map((user) => user.id).contains(id)); + users.addAll(deactivatedUserIds.map( + (id) => UserModel( + id: id, + name: "Deactivated User", + created_at: DateTime(1950), + location: "--"), + )); } return users; diff --git a/khelo/assets/locales/app_en.arb b/khelo/assets/locales/app_en.arb index faefef42..6fc709d1 100644 --- a/khelo/assets/locales/app_en.arb +++ b/khelo/assets/locales/app_en.arb @@ -542,7 +542,6 @@ "score_board_runs_title": "Runs", "score_board_not_from_bat_text": "Not from bat?", "score_board_is_boundary_text": "Is that a boundary?", - "score_board_boundary_text": "Boundary", "score_board_over_complete_title": "Over Complete", "score_board_inning_complete_title": "Inning Complete", "score_board_match_complete_title": "Match Complete", diff --git a/khelo/lib/ui/flow/home/home_view_model.dart b/khelo/lib/ui/flow/home/home_view_model.dart index a319c02c..3b3ad930 100644 --- a/khelo/lib/ui/flow/home/home_view_model.dart +++ b/khelo/lib/ui/flow/home/home_view_model.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:data/api/match/match_model.dart'; import 'package:data/service/match/match_service.dart'; +import 'package:data/storage/app_preferences.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -9,7 +10,12 @@ part 'home_view_model.freezed.dart'; final homeViewStateProvider = StateNotifierProvider.autoDispose( - (ref) => HomeViewNotifier(ref.read(matchServiceProvider)), + (ref) { + final notifier = HomeViewNotifier(ref.read(matchServiceProvider)); + ref.listen( + hasUserSession, (_, next) => notifier._onUserSessionUpdate(next)); + return notifier; + }, ); class HomeViewNotifier extends StateNotifier { @@ -20,6 +26,12 @@ class HomeViewNotifier extends StateNotifier { _loadMatches(); } + void _onUserSessionUpdate(bool hasSession) { + if (!hasSession) { + _streamSubscription.cancel(); + } + } + void _loadMatches() async { state = state.copyWith(loading: state.matches.isEmpty); diff --git a/khelo/lib/ui/flow/main/main_screen.dart b/khelo/lib/ui/flow/main/main_screen.dart index 60cc1f39..7d6a3edf 100644 --- a/khelo/lib/ui/flow/main/main_screen.dart +++ b/khelo/lib/ui/flow/main/main_screen.dart @@ -21,7 +21,7 @@ class MainScreen extends ConsumerStatefulWidget { } class _MainScreenState extends ConsumerState - with AutomaticKeepAliveClientMixin, WidgetsBindingObserver { + with WidgetsBindingObserver { static final List _widgets = [ const HomeScreen(), const MyGameTabScreen(), @@ -31,10 +31,6 @@ class _MainScreenState extends ConsumerState final _materialPageController = PageController(); final _cupertinoTabController = CupertinoTabController(); - bool _wantKeepAlive = true; - - @override - bool get wantKeepAlive => _wantKeepAlive; @override void initState() { @@ -44,15 +40,7 @@ class _MainScreenState extends ConsumerState @override void didChangeAppLifecycleState(AppLifecycleState state) { - if (state == AppLifecycleState.paused) { - setState(() { - _wantKeepAlive = false; - }); - } else if (state == AppLifecycleState.resumed) { - setState(() { - _wantKeepAlive = true; - }); - } else if (state == AppLifecycleState.detached) { + if (state == AppLifecycleState.detached) { // deallocate resources _materialPageController.dispose(); _cupertinoTabController.dispose(); @@ -62,7 +50,6 @@ class _MainScreenState extends ConsumerState @override Widget build(BuildContext context) { - super.build(context); if (Platform.isIOS) { return _cupertinoTabs(context); } diff --git a/khelo/lib/ui/flow/matches/add_match/add_match_screen.dart b/khelo/lib/ui/flow/matches/add_match/add_match_screen.dart index 28fb7785..ffdee690 100644 --- a/khelo/lib/ui/flow/matches/add_match/add_match_screen.dart +++ b/khelo/lib/ui/flow/matches/add_match/add_match_screen.dart @@ -66,13 +66,13 @@ class _AddMatchScreenState extends ConsumerState { ? context.l10n.add_match_screen_edit_match_title : context.l10n.add_match_screen_title, actions: [ - if (widget.matchId != null) - _deleteMatchButton(context, onDelete: notifier.deleteMatch), _scheduleMatchButton( context, saveBtnError: state.saveBtnError, onSchedule: () => notifier.addMatch(), ), + if (widget.matchId != null) + _deleteMatchButton(context, onDelete: notifier.deleteMatch), ], body: Builder(builder: (context) { return Stack( @@ -104,7 +104,7 @@ class _AddMatchScreenState extends ConsumerState { height: 24, colorFilter: ColorFilter.mode( saveBtnError == null - ? context.colorScheme.primary + ? context.colorScheme.textPrimary : context.colorScheme.textDisabled, BlendMode.srcIn), ), @@ -126,7 +126,7 @@ class _AddMatchScreenState extends ConsumerState { width: 24, fit: BoxFit.contain, colorFilter: - ColorFilter.mode(context.colorScheme.primary, BlendMode.srcATop), + ColorFilter.mode(context.colorScheme.alert, BlendMode.srcATop), )); } diff --git a/khelo/lib/ui/flow/matches/add_match/match_officials/add_match_officials_screen.dart b/khelo/lib/ui/flow/matches/add_match/match_officials/add_match_officials_screen.dart index ae0a1d3d..0666377a 100644 --- a/khelo/lib/ui/flow/matches/add_match/match_officials/add_match_officials_screen.dart +++ b/khelo/lib/ui/flow/matches/add_match/match_officials/add_match_officials_screen.dart @@ -10,6 +10,7 @@ import 'package:khelo/domain/extensions/context_extensions.dart'; import 'package:khelo/domain/extensions/widget_extension.dart'; import 'package:khelo/ui/flow/matches/add_match/match_officials/components/officials_cell_view.dart'; import 'package:khelo/ui/flow/matches/add_match/match_officials/search_user/search_user_screen.dart'; +import 'package:style/button/back_button.dart'; import 'package:style/button/bottom_sticky_overlay.dart'; import 'package:style/button/primary_button.dart'; import 'package:style/extensions/context_extensions.dart'; @@ -43,6 +44,7 @@ class _AddMatchOfficialsScreenState return AppPage( title: context.l10n.add_match_officials_screen_title, + leading: backButton(context, onPressed: context.pop), body: Builder(builder: (context) { return Stack( children: [ diff --git a/khelo/lib/ui/flow/matches/add_match/match_officials/search_user/search_user_screen.dart b/khelo/lib/ui/flow/matches/add_match/match_officials/search_user/search_user_screen.dart index 800dffa9..f1a5e8cd 100644 --- a/khelo/lib/ui/flow/matches/add_match/match_officials/search_user/search_user_screen.dart +++ b/khelo/lib/ui/flow/matches/add_match/match_officials/search_user/search_user_screen.dart @@ -9,7 +9,7 @@ import 'package:khelo/domain/extensions/context_extensions.dart'; import 'package:khelo/ui/flow/matches/add_match/match_officials/search_user/search_user_view_model.dart'; import 'package:khelo/ui/flow/matches/add_match/select_squad/components/user_detail_sheet.dart'; import 'package:khelo/ui/flow/team/add_team_member/components/verify_team_member_sheet.dart'; -import 'package:style/animations/on_tap_scale.dart'; +import 'package:style/button/secondary_button.dart'; import 'package:style/extensions/context_extensions.dart'; import 'package:style/text/app_text_style.dart'; import 'package:style/text/search_text_field.dart'; @@ -126,8 +126,9 @@ class SearchUserBottomSheet extends ConsumerWidget { } Widget _addButton(BuildContext context, UserModel user) { - return OnTapScale( - onTap: () async { + return SecondaryButton( + context.l10n.common_add_title, + onPressed: () async { if (user.phone != null) { final res = await VerifyTeamMemberSheet.show(context, phoneNumber: user.phone!); @@ -136,17 +137,6 @@ class SearchUserBottomSheet extends ConsumerWidget { } } }, - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - decoration: BoxDecoration( - color: context.colorScheme.containerLow, - borderRadius: BorderRadius.circular(30)), - child: Text( - context.l10n.common_add_title, - style: AppTextStyle.body2 - .copyWith(color: context.colorScheme.textDisabled), - ), - ), ); } } diff --git a/khelo/lib/ui/flow/matches/add_match/power_play/power_play_screen.dart b/khelo/lib/ui/flow/matches/add_match/power_play/power_play_screen.dart index bf34737b..ea983a57 100644 --- a/khelo/lib/ui/flow/matches/add_match/power_play/power_play_screen.dart +++ b/khelo/lib/ui/flow/matches/add_match/power_play/power_play_screen.dart @@ -6,6 +6,7 @@ import 'package:khelo/domain/extensions/context_extensions.dart'; import 'package:khelo/domain/extensions/widget_extension.dart'; import 'package:khelo/ui/flow/matches/add_match/power_play/power_play_view_model.dart'; import 'package:style/animations/on_tap_scale.dart'; +import 'package:style/button/back_button.dart'; import 'package:style/button/bottom_sticky_overlay.dart'; import 'package:style/button/primary_button.dart'; import 'package:style/extensions/context_extensions.dart'; @@ -56,6 +57,7 @@ class _PowerPlayScreenState extends ConsumerState { return AppPage( title: context.l10n.common_power_play_title, + leading: backButton(context, onPressed: context.pop), body: Builder(builder: (context) { return Stack( children: [ diff --git a/khelo/lib/ui/flow/matches/add_match/select_squad/select_squad_screen.dart b/khelo/lib/ui/flow/matches/add_match/select_squad/select_squad_screen.dart index 7dfe728d..706b28a4 100644 --- a/khelo/lib/ui/flow/matches/add_match/select_squad/select_squad_screen.dart +++ b/khelo/lib/ui/flow/matches/add_match/select_squad/select_squad_screen.dart @@ -13,7 +13,6 @@ import 'package:khelo/gen/assets.gen.dart'; import 'package:khelo/ui/flow/matches/add_match/select_squad/components/select_admin_and_captain_dialog.dart'; import 'package:khelo/ui/flow/matches/add_match/select_squad/components/user_detail_sheet.dart'; import 'package:khelo/ui/flow/matches/add_match/select_squad/select_squad_view_model.dart'; -import 'package:style/animations/on_tap_scale.dart'; import 'package:style/button/action_button.dart'; import 'package:style/extensions/context_extensions.dart'; import 'package:style/text/app_text_style.dart'; @@ -70,7 +69,7 @@ class _SelectSquadScreenState extends ConsumerState { Assets.images.icCheck, colorFilter: ColorFilter.mode( state.isDoneBtnEnable - ? context.colorScheme.primary + ? context.colorScheme.textPrimary : context.colorScheme.textDisabled, BlendMode.srcIn), )), @@ -224,17 +223,17 @@ class _SelectSquadScreenState extends ConsumerState { required MatchPlayer member, required bool isRemove, }) { - return OnTapScale( - onTap: () => isRemove - ? notifier.removeFromSquad(member.player) - : notifier.addToSquad(member), - child: Padding( - padding: const EdgeInsets.all(10.0), - child: Icon( - isRemove ? Icons.close : Icons.add, - size: 16, - color: context.colorScheme.textDisabled, - ), - )); + return actionButton( + context, + onPressed: () => isRemove + ? notifier.removeFromSquad(member.player) + : notifier.addToSquad(member), + padding: const EdgeInsets.only(left: 10, top: 10, bottom: 10), + icon: Icon( + isRemove ? Icons.close : Icons.add, + size: 16, + color: context.colorScheme.textDisabled, + ), + ); } } diff --git a/khelo/lib/ui/flow/matches/match_list_screen.dart b/khelo/lib/ui/flow/matches/match_list_screen.dart index cbd0d0e8..e1398dbe 100644 --- a/khelo/lib/ui/flow/matches/match_list_screen.dart +++ b/khelo/lib/ui/flow/matches/match_list_screen.dart @@ -19,12 +19,8 @@ class MatchListScreen extends ConsumerStatefulWidget { } class _MatchListScreenState extends ConsumerState - with AutomaticKeepAliveClientMixin, WidgetsBindingObserver { + with WidgetsBindingObserver { late MatchListViewNotifier notifier; - bool _wantKeepAlive = true; - - @override - bool get wantKeepAlive => _wantKeepAlive; @override void initState() { @@ -34,15 +30,7 @@ class _MatchListScreenState extends ConsumerState @override void didChangeAppLifecycleState(AppLifecycleState state) { - if (state == AppLifecycleState.paused) { - setState(() { - _wantKeepAlive = false; - }); - } else if (state == AppLifecycleState.resumed) { - setState(() { - _wantKeepAlive = true; - }); - } else if (state == AppLifecycleState.detached) { + if (state == AppLifecycleState.detached) { // deallocate resources notifier.dispose(); WidgetsBinding.instance.removeObserver(this); @@ -51,7 +39,6 @@ class _MatchListScreenState extends ConsumerState @override Widget build(BuildContext context) { - super.build(context); final state = ref.watch(matchListStateProvider); notifier = ref.watch(matchListStateProvider.notifier); diff --git a/khelo/lib/ui/flow/matches/match_list_view_model.dart b/khelo/lib/ui/flow/matches/match_list_view_model.dart index c314c33e..ff4f634b 100644 --- a/khelo/lib/ui/flow/matches/match_list_view_model.dart +++ b/khelo/lib/ui/flow/matches/match_list_view_model.dart @@ -32,6 +32,9 @@ class MatchListViewNotifier extends StateNotifier { } void setUserId(String? userId) { + if (userId == null) { + _cancelStreamSubscription(); + } state = state.copyWith(currentUserId: userId); } diff --git a/khelo/lib/ui/flow/my_game/my_game_tab_screen.dart b/khelo/lib/ui/flow/my_game/my_game_tab_screen.dart index 531b3f65..61358e54 100644 --- a/khelo/lib/ui/flow/my_game/my_game_tab_screen.dart +++ b/khelo/lib/ui/flow/my_game/my_game_tab_screen.dart @@ -20,7 +20,7 @@ class MyGameTabScreen extends ConsumerStatefulWidget { } class _MyGameTabScreenState extends ConsumerState - with AutomaticKeepAliveClientMixin, WidgetsBindingObserver { + with WidgetsBindingObserver { final List _tabs = [ const MatchListScreen(), const TeamListScreen(), @@ -31,10 +31,6 @@ class _MyGameTabScreenState extends ConsumerState int get _selectedTab => _controller.hasClients ? _controller.page?.round() ?? 0 : _controller.initialPage; - bool _wantKeepAlive = true; - - @override - bool get wantKeepAlive => _wantKeepAlive; @override void initState() { @@ -48,15 +44,7 @@ class _MyGameTabScreenState extends ConsumerState @override void didChangeAppLifecycleState(AppLifecycleState state) { - if (state == AppLifecycleState.paused) { - setState(() { - _wantKeepAlive = false; - }); - } else if (state == AppLifecycleState.resumed) { - setState(() { - _wantKeepAlive = true; - }); - } else if (state == AppLifecycleState.detached) { + if (state == AppLifecycleState.detached) { // deallocate resources _controller.dispose(); WidgetsBinding.instance.removeObserver(this); @@ -65,8 +53,6 @@ class _MyGameTabScreenState extends ConsumerState @override Widget build(BuildContext context) { - super.build(context); - final notifier = ref.watch(myGameTabViewStateProvider.notifier); return AppPage( @@ -126,13 +112,14 @@ class _MyGameTabScreenState extends ConsumerState .read(teamListViewStateProvider.notifier) .onFilterButtonTap(), icon: Icon(CupertinoIcons.slider_horizontal_3, - color: context.colorScheme.primary)), + color: context.colorScheme.textPrimary)), ], actionButton(context, onPressed: () => _selectedTab == 1 ? AppRoute.addTeam().push(context) : AppRoute.addMatch().push(context), - icon: Icon(Icons.add, color: context.colorScheme.primary)), + icon: Icon(Icons.add, color: context.colorScheme.textPrimary)), + const SizedBox(width: 8), ], ), ); diff --git a/khelo/lib/ui/flow/score_board/components/score_board_buttons.dart b/khelo/lib/ui/flow/score_board/components/score_board_buttons.dart index 7381213f..414028cd 100644 --- a/khelo/lib/ui/flow/score_board/components/score_board_buttons.dart +++ b/khelo/lib/ui/flow/score_board/components/score_board_buttons.dart @@ -1,5 +1,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:khelo/domain/extensions/context_extensions.dart'; import 'package:khelo/ui/flow/score_board/score_board_view_model.dart'; @@ -8,7 +9,7 @@ import 'package:style/extensions/context_extensions.dart'; import 'package:style/text/app_text_style.dart'; class ScoreBoardButtons extends StatelessWidget { - final Function(ScoreButton) onTap; + final Function(ScoreButton, bool) onTap; const ScoreBoardButtons({super.key, required this.onTap}); @@ -117,7 +118,11 @@ class ScoreBoardButtons extends StatelessWidget { Color? backgroundColor, }) { return OnTapScale( - onTap: () => onTap(btn), + onTap: () => onTap(btn, false), + onLongTap: () { + HapticFeedback.mediumImpact(); + onTap(btn, true); + }, child: Container( alignment: Alignment.center, margin: const EdgeInsets.only(bottom: 8, right: 8), diff --git a/khelo/lib/ui/flow/score_board/score_board_screen.dart b/khelo/lib/ui/flow/score_board/score_board_screen.dart index 5ce82889..afc9b932 100644 --- a/khelo/lib/ui/flow/score_board/score_board_screen.dart +++ b/khelo/lib/ui/flow/score_board/score_board_screen.dart @@ -22,6 +22,7 @@ import 'package:khelo/ui/flow/score_board/components/select_wicket_taker_sheet.d import 'package:khelo/ui/flow/score_board/components/select_wicket_type_sheet.dart'; import 'package:khelo/ui/flow/score_board/components/striker_selection_sheet.dart'; import 'package:khelo/ui/flow/score_board/score_board_view_model.dart'; +import 'package:style/button/more_option_button.dart'; import 'package:style/extensions/context_extensions.dart'; import 'package:style/indicator/progress_indicator.dart'; import 'package:style/theme/colors.dart'; @@ -66,8 +67,6 @@ class _ScoreBoardScreenState extends ConsumerState { _observeShowOverCompleteSheet(context, ref); _observeShowInningCompleteSheet(context, ref); _observeShowMatchCompleteSheet(context, ref); - _observeShowBoundaryConfirmationDialogForSix(context, ref); - _observeShowBoundaryConfirmationDialogForFour(context, ref); _observeShowAddExtraSheetForNoBall(context, ref); _observeShowAddExtraSheetForLegBye(context, ref); _observeShowAddExtraSheetForBye(context, ref); @@ -96,28 +95,25 @@ class _ScoreBoardScreenState extends ConsumerState { BuildContext context, ScoreBoardViewState state, ) { - return IconButton( - onPressed: () async { - showActionBottomSheet( - context: context, - items: MatchOption.values - .map( - (option) => BottomSheetAction( - title: option.getTitle(context), - onTap: () { - if (option != MatchOption.continueWithInjuredPlayer) { - context.pop(); - notifier.onMatchOptionSelect(option, true); - } - }, - child: option == MatchOption.continueWithInjuredPlayer - ? _toggleButton(context, state) - : null, - ), - ) - .toList()); - }, - icon: const Icon(Icons.more_horiz)); + return moreOptionButton( + context, + onPressed: () => showActionBottomSheet( + context: context, + items: MatchOption.values + .map((option) => BottomSheetAction( + title: option.getTitle(context), + onTap: () { + if (option != MatchOption.continueWithInjuredPlayer) { + context.pop(); + notifier.onMatchOptionSelect(option, true); + } + }, + child: option == MatchOption.continueWithInjuredPlayer + ? _toggleButton(context, state) + : null, + )) + .toList()), + ); } Widget _toggleButton( @@ -296,21 +292,6 @@ class _ScoreBoardScreenState extends ConsumerState { } } - Future _showBoundaryConfirmationDialog( - BuildContext context, int run) async { - showConfirmationDialog( - context, - title: context.l10n.score_board_boundary_text, - message: context.l10n.score_board_is_boundary_text, - isDestructiveAction: true, - confirmBtnText: context.l10n.common_yes_title, - cancelBtnText: context.l10n.common_no_title, - onConfirm: () => - notifier.addBall(run: run, isSix: run == 6, isFour: run == 4), - onCancel: () => notifier.addBall(run: run), - ); - } - Future _showAddExtraSheet( BuildContext context, ExtrasType? extra, @@ -507,30 +488,6 @@ class _ScoreBoardScreenState extends ConsumerState { }); } - void _observeShowBoundaryConfirmationDialogForSix( - BuildContext context, WidgetRef ref) { - ref.listen( - scoreBoardStateProvider - .select((value) => value.showBoundaryConfirmationDialogForSix), - (previous, next) { - if (next != null) { - _showBoundaryConfirmationDialog(context, 6); - } - }); - } - - void _observeShowBoundaryConfirmationDialogForFour( - BuildContext context, WidgetRef ref) { - ref.listen( - scoreBoardStateProvider - .select((value) => value.showBoundaryConfirmationDialogForFour), - (previous, next) { - if (next != null) { - _showBoundaryConfirmationDialog(context, 4); - } - }); - } - void _observeShowAddExtraSheetForNoBall(BuildContext context, WidgetRef ref) { ref.listen( scoreBoardStateProvider.select( diff --git a/khelo/lib/ui/flow/score_board/score_board_view_model.dart b/khelo/lib/ui/flow/score_board/score_board_view_model.dart index db466936..d6a8d444 100644 --- a/khelo/lib/ui/flow/score_board/score_board_view_model.dart +++ b/khelo/lib/ui/flow/score_board/score_board_view_model.dart @@ -396,7 +396,7 @@ class ScoreBoardViewNotifier extends StateNotifier { state = state.copyWith(showStrikerSelectionSheet: DateTime.now()); } - void onScoreButtonTap(ScoreButton btn) { + void onScoreButtonTap(ScoreButton btn, bool isLongTap) { if (state.isActionInProgress) { return; } @@ -410,11 +410,9 @@ class ScoreBoardViewNotifier extends StateNotifier { case ScoreButton.three: addBall(run: 3); case ScoreButton.four: - state = state.copyWith( - showBoundaryConfirmationDialogForFour: DateTime.now()); + addBall(run: 4, isFour: !isLongTap); case ScoreButton.six: - state = state.copyWith( - showBoundaryConfirmationDialogForSix: DateTime.now()); + addBall(run: 6, isSix: !isLongTap); case ScoreButton.fiveOrSeven: state = state.copyWith(showAddExtraSheetForFiveSeven: DateTime.now()); case ScoreButton.undo: @@ -1174,8 +1172,6 @@ class ScoreBoardViewState with _$ScoreBoardViewState { DateTime? showOverCompleteSheet, DateTime? showInningCompleteSheet, DateTime? showMatchCompleteSheet, - DateTime? showBoundaryConfirmationDialogForSix, - DateTime? showBoundaryConfirmationDialogForFour, DateTime? showAddExtraSheetForNoBall, DateTime? showAddExtraSheetForLegBye, DateTime? showAddExtraSheetForBye, diff --git a/khelo/lib/ui/flow/score_board/score_board_view_model.freezed.dart b/khelo/lib/ui/flow/score_board/score_board_view_model.freezed.dart index f8140558..6d4ad385 100644 --- a/khelo/lib/ui/flow/score_board/score_board_view_model.freezed.dart +++ b/khelo/lib/ui/flow/score_board/score_board_view_model.freezed.dart @@ -36,10 +36,6 @@ mixin _$ScoreBoardViewState { DateTime? get showOverCompleteSheet => throw _privateConstructorUsedError; DateTime? get showInningCompleteSheet => throw _privateConstructorUsedError; DateTime? get showMatchCompleteSheet => throw _privateConstructorUsedError; - DateTime? get showBoundaryConfirmationDialogForSix => - throw _privateConstructorUsedError; - DateTime? get showBoundaryConfirmationDialogForFour => - throw _privateConstructorUsedError; DateTime? get showAddExtraSheetForNoBall => throw _privateConstructorUsedError; DateTime? get showAddExtraSheetForLegBye => @@ -95,8 +91,6 @@ abstract class $ScoreBoardViewStateCopyWith<$Res> { DateTime? showOverCompleteSheet, DateTime? showInningCompleteSheet, DateTime? showMatchCompleteSheet, - DateTime? showBoundaryConfirmationDialogForSix, - DateTime? showBoundaryConfirmationDialogForFour, DateTime? showAddExtraSheetForNoBall, DateTime? showAddExtraSheetForLegBye, DateTime? showAddExtraSheetForBye, @@ -154,8 +148,6 @@ class _$ScoreBoardViewStateCopyWithImpl<$Res, $Val extends ScoreBoardViewState> Object? showOverCompleteSheet = freezed, Object? showInningCompleteSheet = freezed, Object? showMatchCompleteSheet = freezed, - Object? showBoundaryConfirmationDialogForSix = freezed, - Object? showBoundaryConfirmationDialogForFour = freezed, Object? showAddExtraSheetForNoBall = freezed, Object? showAddExtraSheetForLegBye = freezed, Object? showAddExtraSheetForBye = freezed, @@ -244,16 +236,6 @@ class _$ScoreBoardViewStateCopyWithImpl<$Res, $Val extends ScoreBoardViewState> ? _value.showMatchCompleteSheet : showMatchCompleteSheet // ignore: cast_nullable_to_non_nullable as DateTime?, - showBoundaryConfirmationDialogForSix: freezed == - showBoundaryConfirmationDialogForSix - ? _value.showBoundaryConfirmationDialogForSix - : showBoundaryConfirmationDialogForSix // ignore: cast_nullable_to_non_nullable - as DateTime?, - showBoundaryConfirmationDialogForFour: freezed == - showBoundaryConfirmationDialogForFour - ? _value.showBoundaryConfirmationDialogForFour - : showBoundaryConfirmationDialogForFour // ignore: cast_nullable_to_non_nullable - as DateTime?, showAddExtraSheetForNoBall: freezed == showAddExtraSheetForNoBall ? _value.showAddExtraSheetForNoBall : showAddExtraSheetForNoBall // ignore: cast_nullable_to_non_nullable @@ -409,8 +391,6 @@ abstract class _$$ScoreBoardViewStateImplCopyWith<$Res> DateTime? showOverCompleteSheet, DateTime? showInningCompleteSheet, DateTime? showMatchCompleteSheet, - DateTime? showBoundaryConfirmationDialogForSix, - DateTime? showBoundaryConfirmationDialogForFour, DateTime? showAddExtraSheetForNoBall, DateTime? showAddExtraSheetForLegBye, DateTime? showAddExtraSheetForBye, @@ -470,8 +450,6 @@ class __$$ScoreBoardViewStateImplCopyWithImpl<$Res> Object? showOverCompleteSheet = freezed, Object? showInningCompleteSheet = freezed, Object? showMatchCompleteSheet = freezed, - Object? showBoundaryConfirmationDialogForSix = freezed, - Object? showBoundaryConfirmationDialogForFour = freezed, Object? showAddExtraSheetForNoBall = freezed, Object? showAddExtraSheetForLegBye = freezed, Object? showAddExtraSheetForBye = freezed, @@ -560,16 +538,6 @@ class __$$ScoreBoardViewStateImplCopyWithImpl<$Res> ? _value.showMatchCompleteSheet : showMatchCompleteSheet // ignore: cast_nullable_to_non_nullable as DateTime?, - showBoundaryConfirmationDialogForSix: freezed == - showBoundaryConfirmationDialogForSix - ? _value.showBoundaryConfirmationDialogForSix - : showBoundaryConfirmationDialogForSix // ignore: cast_nullable_to_non_nullable - as DateTime?, - showBoundaryConfirmationDialogForFour: freezed == - showBoundaryConfirmationDialogForFour - ? _value.showBoundaryConfirmationDialogForFour - : showBoundaryConfirmationDialogForFour // ignore: cast_nullable_to_non_nullable - as DateTime?, showAddExtraSheetForNoBall: freezed == showAddExtraSheetForNoBall ? _value.showAddExtraSheetForNoBall : showAddExtraSheetForNoBall // ignore: cast_nullable_to_non_nullable @@ -672,8 +640,6 @@ class _$ScoreBoardViewStateImpl implements _ScoreBoardViewState { this.showOverCompleteSheet, this.showInningCompleteSheet, this.showMatchCompleteSheet, - this.showBoundaryConfirmationDialogForSix, - this.showBoundaryConfirmationDialogForFour, this.showAddExtraSheetForNoBall, this.showAddExtraSheetForLegBye, this.showAddExtraSheetForBye, @@ -742,10 +708,6 @@ class _$ScoreBoardViewStateImpl implements _ScoreBoardViewState { @override final DateTime? showMatchCompleteSheet; @override - final DateTime? showBoundaryConfirmationDialogForSix; - @override - final DateTime? showBoundaryConfirmationDialogForFour; - @override final DateTime? showAddExtraSheetForNoBall; @override final DateTime? showAddExtraSheetForLegBye; @@ -811,7 +773,7 @@ class _$ScoreBoardViewStateImpl implements _ScoreBoardViewState { @override String toString() { - return 'ScoreBoardViewState(error: $error, actionError: $actionError, match: $match, currentInning: $currentInning, otherInning: $otherInning, bowler: $bowler, strikerId: $strikerId, batsMans: $batsMans, showSelectBatsManSheet: $showSelectBatsManSheet, showSelectBowlerSheet: $showSelectBowlerSheet, showSelectBowlerAndBatsManSheet: $showSelectBowlerAndBatsManSheet, showSelectPlayerSheet: $showSelectPlayerSheet, showSelectWicketTypeSheet: $showSelectWicketTypeSheet, showStrikerSelectionSheet: $showStrikerSelectionSheet, showUndoBallConfirmationDialog: $showUndoBallConfirmationDialog, showOverCompleteSheet: $showOverCompleteSheet, showInningCompleteSheet: $showInningCompleteSheet, showMatchCompleteSheet: $showMatchCompleteSheet, showBoundaryConfirmationDialogForSix: $showBoundaryConfirmationDialogForSix, showBoundaryConfirmationDialogForFour: $showBoundaryConfirmationDialogForFour, showAddExtraSheetForNoBall: $showAddExtraSheetForNoBall, showAddExtraSheetForLegBye: $showAddExtraSheetForLegBye, showAddExtraSheetForBye: $showAddExtraSheetForBye, showAddExtraSheetForFiveSeven: $showAddExtraSheetForFiveSeven, showPauseScoringSheet: $showPauseScoringSheet, showAddPenaltyRunSheet: $showAddPenaltyRunSheet, showEndMatchSheet: $showEndMatchSheet, invalidUndoToast: $invalidUndoToast, currentScoresList: $currentScoresList, previousScoresList: $previousScoresList, loading: $loading, pop: $pop, continueWithInjuredPlayers: $continueWithInjuredPlayers, ballScoreQueryListenerSet: $ballScoreQueryListenerSet, isMatchUpdated: $isMatchUpdated, isActionInProgress: $isActionInProgress, ballCount: $ballCount, overCount: $overCount, lastAssignedIndex: $lastAssignedIndex)'; + return 'ScoreBoardViewState(error: $error, actionError: $actionError, match: $match, currentInning: $currentInning, otherInning: $otherInning, bowler: $bowler, strikerId: $strikerId, batsMans: $batsMans, showSelectBatsManSheet: $showSelectBatsManSheet, showSelectBowlerSheet: $showSelectBowlerSheet, showSelectBowlerAndBatsManSheet: $showSelectBowlerAndBatsManSheet, showSelectPlayerSheet: $showSelectPlayerSheet, showSelectWicketTypeSheet: $showSelectWicketTypeSheet, showStrikerSelectionSheet: $showStrikerSelectionSheet, showUndoBallConfirmationDialog: $showUndoBallConfirmationDialog, showOverCompleteSheet: $showOverCompleteSheet, showInningCompleteSheet: $showInningCompleteSheet, showMatchCompleteSheet: $showMatchCompleteSheet, showAddExtraSheetForNoBall: $showAddExtraSheetForNoBall, showAddExtraSheetForLegBye: $showAddExtraSheetForLegBye, showAddExtraSheetForBye: $showAddExtraSheetForBye, showAddExtraSheetForFiveSeven: $showAddExtraSheetForFiveSeven, showPauseScoringSheet: $showPauseScoringSheet, showAddPenaltyRunSheet: $showAddPenaltyRunSheet, showEndMatchSheet: $showEndMatchSheet, invalidUndoToast: $invalidUndoToast, currentScoresList: $currentScoresList, previousScoresList: $previousScoresList, loading: $loading, pop: $pop, continueWithInjuredPlayers: $continueWithInjuredPlayers, ballScoreQueryListenerSet: $ballScoreQueryListenerSet, isMatchUpdated: $isMatchUpdated, isActionInProgress: $isActionInProgress, ballCount: $ballCount, overCount: $overCount, lastAssignedIndex: $lastAssignedIndex)'; } @override @@ -853,12 +815,6 @@ class _$ScoreBoardViewStateImpl implements _ScoreBoardViewState { other.showInningCompleteSheet == showInningCompleteSheet) && (identical(other.showMatchCompleteSheet, showMatchCompleteSheet) || other.showMatchCompleteSheet == showMatchCompleteSheet) && - (identical(other.showBoundaryConfirmationDialogForSix, showBoundaryConfirmationDialogForSix) || - other.showBoundaryConfirmationDialogForSix == - showBoundaryConfirmationDialogForSix) && - (identical(other.showBoundaryConfirmationDialogForFour, showBoundaryConfirmationDialogForFour) || - other.showBoundaryConfirmationDialogForFour == - showBoundaryConfirmationDialogForFour) && (identical(other.showAddExtraSheetForNoBall, showAddExtraSheetForNoBall) || other.showAddExtraSheetForNoBall == showAddExtraSheetForNoBall) && @@ -868,10 +824,14 @@ class _$ScoreBoardViewStateImpl implements _ScoreBoardViewState { (identical(other.showAddExtraSheetForBye, showAddExtraSheetForBye) || other.showAddExtraSheetForBye == showAddExtraSheetForBye) && (identical(other.showAddExtraSheetForFiveSeven, showAddExtraSheetForFiveSeven) || - other.showAddExtraSheetForFiveSeven == showAddExtraSheetForFiveSeven) && - (identical(other.showPauseScoringSheet, showPauseScoringSheet) || other.showPauseScoringSheet == showPauseScoringSheet) && - (identical(other.showAddPenaltyRunSheet, showAddPenaltyRunSheet) || other.showAddPenaltyRunSheet == showAddPenaltyRunSheet) && - (identical(other.showEndMatchSheet, showEndMatchSheet) || other.showEndMatchSheet == showEndMatchSheet) && + other.showAddExtraSheetForFiveSeven == + showAddExtraSheetForFiveSeven) && + (identical(other.showPauseScoringSheet, showPauseScoringSheet) || + other.showPauseScoringSheet == showPauseScoringSheet) && + (identical(other.showAddPenaltyRunSheet, showAddPenaltyRunSheet) || + other.showAddPenaltyRunSheet == showAddPenaltyRunSheet) && + (identical(other.showEndMatchSheet, showEndMatchSheet) || + other.showEndMatchSheet == showEndMatchSheet) && (identical(other.invalidUndoToast, invalidUndoToast) || other.invalidUndoToast == invalidUndoToast) && const DeepCollectionEquality().equals(other._currentScoresList, _currentScoresList) && const DeepCollectionEquality().equals(other._previousScoresList, _previousScoresList) && @@ -907,8 +867,6 @@ class _$ScoreBoardViewStateImpl implements _ScoreBoardViewState { showOverCompleteSheet, showInningCompleteSheet, showMatchCompleteSheet, - showBoundaryConfirmationDialogForSix, - showBoundaryConfirmationDialogForFour, showAddExtraSheetForNoBall, showAddExtraSheetForLegBye, showAddExtraSheetForBye, @@ -958,8 +916,6 @@ abstract class _ScoreBoardViewState implements ScoreBoardViewState { final DateTime? showOverCompleteSheet, final DateTime? showInningCompleteSheet, final DateTime? showMatchCompleteSheet, - final DateTime? showBoundaryConfirmationDialogForSix, - final DateTime? showBoundaryConfirmationDialogForFour, final DateTime? showAddExtraSheetForNoBall, final DateTime? showAddExtraSheetForLegBye, final DateTime? showAddExtraSheetForBye, @@ -1017,10 +973,6 @@ abstract class _ScoreBoardViewState implements ScoreBoardViewState { @override DateTime? get showMatchCompleteSheet; @override - DateTime? get showBoundaryConfirmationDialogForSix; - @override - DateTime? get showBoundaryConfirmationDialogForFour; - @override DateTime? get showAddExtraSheetForNoBall; @override DateTime? get showAddExtraSheetForLegBye; diff --git a/khelo/lib/ui/flow/settings/edit_profile/edit_profile_screen.dart b/khelo/lib/ui/flow/settings/edit_profile/edit_profile_screen.dart index 4cdc137c..b05c517a 100644 --- a/khelo/lib/ui/flow/settings/edit_profile/edit_profile_screen.dart +++ b/khelo/lib/ui/flow/settings/edit_profile/edit_profile_screen.dart @@ -54,9 +54,9 @@ class EditProfileScreen extends ConsumerWidget { fit: BoxFit.contain, colorFilter: ColorFilter.mode( state.isButtonEnable && !state.isImageUploading - ? context.colorScheme.primary + ? context.colorScheme.textPrimary : context.colorScheme.textDisabled, - BlendMode.srcATop), + BlendMode.srcIn), )), ], body: Builder( diff --git a/khelo/lib/ui/flow/stats/my_stats_tab_screen.dart b/khelo/lib/ui/flow/stats/my_stats_tab_screen.dart index 90af2ce1..003fabca 100644 --- a/khelo/lib/ui/flow/stats/my_stats_tab_screen.dart +++ b/khelo/lib/ui/flow/stats/my_stats_tab_screen.dart @@ -1,11 +1,13 @@ -import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:khelo/components/app_page.dart'; import 'package:khelo/domain/extensions/context_extensions.dart'; import 'package:khelo/ui/flow/stats/my_stats_tab_view_model.dart'; import 'package:khelo/ui/flow/stats/user_match/user_match_list_screen.dart'; import 'package:khelo/ui/flow/stats/user_stat/user_stat_screen.dart'; +import 'package:style/button/action_button.dart'; import 'package:style/button/tab_button.dart'; +import 'package:style/extensions/context_extensions.dart'; class MyStatsTabScreen extends ConsumerStatefulWidget { const MyStatsTabScreen({super.key}); @@ -15,7 +17,7 @@ class MyStatsTabScreen extends ConsumerStatefulWidget { } class _MyStatsTabScreenState extends ConsumerState - with AutomaticKeepAliveClientMixin, WidgetsBindingObserver { + with WidgetsBindingObserver { final List _tabs = [ const UserMatchListScreen(), const UserStatScreen(), @@ -27,11 +29,6 @@ class _MyStatsTabScreenState extends ConsumerState ? _controller.page?.round() ?? 0 : _controller.initialPage; - bool _wantKeepAlive = true; - - @override - bool get wantKeepAlive => _wantKeepAlive; - @override void initState() { super.initState(); @@ -43,15 +40,7 @@ class _MyStatsTabScreenState extends ConsumerState @override void didChangeAppLifecycleState(AppLifecycleState state) { - if (state == AppLifecycleState.paused) { - setState(() { - _wantKeepAlive = false; - }); - } else if (state == AppLifecycleState.resumed) { - setState(() { - _wantKeepAlive = true; - }); - } else if (state == AppLifecycleState.detached) { + if (state == AppLifecycleState.detached) { // deallocate resources _controller.dispose(); WidgetsBinding.instance.removeObserver(this); @@ -61,7 +50,6 @@ class _MyStatsTabScreenState extends ConsumerState @override Widget build(BuildContext context) { final notifier = ref.watch(myStatsTabStateProvider.notifier); - super.build(context); return AppPage( body: Builder( builder: (context) { @@ -107,6 +95,17 @@ class _MyStatsTabScreenState extends ConsumerState selected: _selectedTab == 1, onTap: () => _controller.jumpToPage(1), ), + + // Dummy add-icon to maintain consistency in tab placement for myCricket & Stats tab. + Visibility( + visible: false, + maintainState: true, + maintainAnimation: true, + maintainSize: true, + child: actionButton(context, + onPressed: null, + icon: Icon(Icons.add, color: context.colorScheme.primary)), + ), ], ), ); diff --git a/khelo/lib/ui/flow/stats/user_match/user_match_list_screen.dart b/khelo/lib/ui/flow/stats/user_match/user_match_list_screen.dart index 9328c86b..8fa9a705 100644 --- a/khelo/lib/ui/flow/stats/user_match/user_match_list_screen.dart +++ b/khelo/lib/ui/flow/stats/user_match/user_match_list_screen.dart @@ -17,12 +17,8 @@ class UserMatchListScreen extends ConsumerStatefulWidget { } class _UserMatchListScreenState extends ConsumerState - with AutomaticKeepAliveClientMixin, WidgetsBindingObserver { + with WidgetsBindingObserver { late UserMatchListViewNotifier notifier; - bool _wantKeepAlive = true; - - @override - bool get wantKeepAlive => _wantKeepAlive; @override void initState() { @@ -33,15 +29,7 @@ class _UserMatchListScreenState extends ConsumerState @override void didChangeAppLifecycleState(AppLifecycleState state) { - if (state == AppLifecycleState.paused) { - setState(() { - _wantKeepAlive = false; - }); - } else if (state == AppLifecycleState.resumed) { - setState(() { - _wantKeepAlive = true; - }); - } else if (state == AppLifecycleState.detached) { + if (state == AppLifecycleState.detached) { // deallocate resources notifier.dispose(); WidgetsBinding.instance.removeObserver(this); @@ -50,7 +38,6 @@ class _UserMatchListScreenState extends ConsumerState @override Widget build(BuildContext context) { - super.build(context); return Builder(builder: (context) { return _body(context); }); diff --git a/khelo/lib/ui/flow/stats/user_match/user_match_list_view_model.dart b/khelo/lib/ui/flow/stats/user_match/user_match_list_view_model.dart index 90a8f836..1a20eddc 100644 --- a/khelo/lib/ui/flow/stats/user_match/user_match_list_view_model.dart +++ b/khelo/lib/ui/flow/stats/user_match/user_match_list_view_model.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:data/api/match/match_model.dart'; import 'package:data/service/match/match_service.dart'; +import 'package:data/storage/app_preferences.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -9,9 +10,9 @@ part 'user_match_list_view_model.freezed.dart'; final userMatchListStateProvider = StateNotifierProvider((ref) { - return UserMatchListViewNotifier( - ref.read(matchServiceProvider), - ); + final notifier = UserMatchListViewNotifier(ref.read(matchServiceProvider)); + ref.listen(hasUserSession, (_, next) => notifier._onUserSessionUpdate(next)); + return notifier; }); class UserMatchListViewNotifier extends StateNotifier { @@ -23,6 +24,12 @@ class UserMatchListViewNotifier extends StateNotifier { _loadUserMatches(); } + void _onUserSessionUpdate(bool hasSession) { + if (!hasSession) { + _cancelStreamSubscription(); + } + } + Future _loadUserMatches() async { state = state.copyWith(loading: true); try { diff --git a/khelo/lib/ui/flow/stats/user_stat/user_stat_screen.dart b/khelo/lib/ui/flow/stats/user_stat/user_stat_screen.dart index 47f3df73..85fad617 100644 --- a/khelo/lib/ui/flow/stats/user_stat/user_stat_screen.dart +++ b/khelo/lib/ui/flow/stats/user_stat/user_stat_screen.dart @@ -18,12 +18,8 @@ class UserStatScreen extends ConsumerStatefulWidget { } class _UserStatScreenState extends ConsumerState - with AutomaticKeepAliveClientMixin, WidgetsBindingObserver { + with WidgetsBindingObserver { late UserStatViewNotifier notifier; - bool _wantKeepAlive = true; - - @override - bool get wantKeepAlive => _wantKeepAlive; @override void initState() { @@ -34,15 +30,7 @@ class _UserStatScreenState extends ConsumerState @override void didChangeAppLifecycleState(AppLifecycleState state) { - if (state == AppLifecycleState.paused) { - setState(() { - _wantKeepAlive = false; - }); - } else if (state == AppLifecycleState.resumed) { - setState(() { - _wantKeepAlive = true; - }); - } else if (state == AppLifecycleState.detached) { + if (state == AppLifecycleState.detached) { // deallocate resources notifier.dispose(); WidgetsBinding.instance.removeObserver(this); @@ -51,7 +39,6 @@ class _UserStatScreenState extends ConsumerState @override Widget build(BuildContext context) { - super.build(context); return Builder(builder: (context) => _body(context)); } diff --git a/khelo/lib/ui/flow/stats/user_stat/user_stat_view_model.dart b/khelo/lib/ui/flow/stats/user_stat/user_stat_view_model.dart index 135b38a5..ccbc951e 100644 --- a/khelo/lib/ui/flow/stats/user_stat/user_stat_view_model.dart +++ b/khelo/lib/ui/flow/stats/user_stat/user_stat_view_model.dart @@ -30,6 +30,9 @@ class UserStatViewNotifier extends StateNotifier { } void setUserId(String? userId) { + if (userId == null) { + _cancelStreamSubscription(); + } state = state.copyWith(currentUserId: userId); } diff --git a/khelo/lib/ui/flow/team/add_team/add_team_screen.dart b/khelo/lib/ui/flow/team/add_team/add_team_screen.dart index c3978430..cdc53a2b 100644 --- a/khelo/lib/ui/flow/team/add_team/add_team_screen.dart +++ b/khelo/lib/ui/flow/team/add_team/add_team_screen.dart @@ -20,6 +20,7 @@ import 'package:style/indicator/progress_indicator.dart'; import 'package:style/text/app_text_field.dart'; import 'package:style/text/app_text_style.dart'; import 'package:style/button/action_button.dart'; +import 'package:style/button/back_button.dart'; import 'package:style/button/bottom_sticky_overlay.dart'; import 'package:style/widgets/rounded_check_box.dart'; @@ -56,13 +57,9 @@ class _AddTeamScreenState extends ConsumerState { ? context.l10n.common_edit_team_title : context.l10n.add_team_screen_title, automaticallyImplyLeading: false, - leading: actionButton( + leading: backButton( context, onPressed: context.pop, - icon: Icon( - Icons.arrow_back, - color: context.colorScheme.textPrimary, - ), ), actions: [ if (widget.editTeam != null) ...[ @@ -151,6 +148,7 @@ class _AddTeamScreenState extends ConsumerState { Text(context.l10n.add_team_players_text, style: AppTextStyle.header4 .copyWith(color: context.colorScheme.textPrimary)), + const SizedBox(width: 16), actionButton( context, onPressed: () => @@ -159,7 +157,7 @@ class _AddTeamScreenState extends ConsumerState { icon: Icon( CupertinoIcons.add, color: context.colorScheme.textPrimary, - size: 20, + size: 24, ), ) ], @@ -184,7 +182,13 @@ class _AddTeamScreenState extends ConsumerState { user: player, trailing: actionButton(context, onPressed: () => notifier.onRemoveUserFromTeam(player), - icon: const Icon(Icons.close)), + padding: const EdgeInsets.only( + left: 10, top: 10, bottom: 10), + icon: Icon( + Icons.close, + size: 16, + color: context.colorScheme.textDisabled, + )), ), ), ), diff --git a/khelo/lib/ui/flow/team/add_team_member/add_team_member_screen.dart b/khelo/lib/ui/flow/team/add_team_member/add_team_member_screen.dart index 599a1762..eea067b0 100644 --- a/khelo/lib/ui/flow/team/add_team_member/add_team_member_screen.dart +++ b/khelo/lib/ui/flow/team/add_team_member/add_team_member_screen.dart @@ -15,6 +15,7 @@ import 'package:khelo/ui/flow/team/add_team_member/add_team_member_view_model.da import 'package:khelo/ui/flow/team/add_team_member/components/verify_team_member_sheet.dart'; import 'package:style/animations/on_tap_scale.dart'; import 'package:style/button/action_button.dart'; +import 'package:style/button/secondary_button.dart'; import 'package:style/extensions/context_extensions.dart'; import 'package:style/indicator/progress_indicator.dart'; import 'package:style/text/search_text_field.dart'; @@ -50,22 +51,21 @@ class _AddTeamMemberScreenState extends ConsumerState { return AppPage( title: context.l10n.add_team_member_screen_title, actions: [ - Visibility( - visible: state.selectedUsers.isNotEmpty, - child: state.isAddInProgress - ? const AppProgressIndicator(size: AppProgressIndicatorSize.small) - : actionButton( - context, - onPressed: () => notifier.addPlayersToTeam(widget.team.id), - icon: SvgPicture.asset( - Assets.images.icCheck, - colorFilter: ColorFilter.mode( - context.colorScheme.primary, - BlendMode.srcATop, - ), + state.isAddInProgress + ? const AppProgressIndicator(size: AppProgressIndicatorSize.small) + : actionButton( + context, + onPressed: () => notifier.addPlayersToTeam(widget.team.id), + icon: SvgPicture.asset( + Assets.images.icCheck, + colorFilter: ColorFilter.mode( + state.selectedUsers.isNotEmpty + ? context.colorScheme.textPrimary + : context.colorScheme.textDisabled, + BlendMode.srcIn, ), ), - ), + ), ], body: Builder(builder: (context) { return Padding( @@ -141,36 +141,25 @@ class _AddTeamMemberScreenState extends ConsumerState { } }, ), - trailing: OnTapScale( - onTap: widget.team.players?.contains(user) != true && - !state.selectedUsers.contains(user) - ? () async { - if (user.phone != null) { - final res = - await VerifyTeamMemberSheet.show( - context, - phoneNumber: user.phone!); - if (res != null && res && context.mounted) { - notifier.selectUser(user); - } - } - } - : null, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 16, vertical: 8), - decoration: BoxDecoration( - color: context.colorScheme.containerLow, - borderRadius: BorderRadius.circular(20)), - child: Text( - widget.team.players?.contains(user) == true || - state.selectedUsers.contains(user) - ? context.l10n.add_team_member_added_text - : context.l10n.common_add_title.toUpperCase(), - style: AppTextStyle.body2.copyWith( - color: context.colorScheme.textDisabled), - ), - ), + trailing: SecondaryButton( + widget.team.players?.contains(user) == true || + state.selectedUsers.contains(user) + ? context.l10n.add_team_member_added_text + : context.l10n.common_add_title.toUpperCase(), + enabled: + widget.team.players?.contains(user) != true && + !state.selectedUsers.contains(user), + onPressed: () async { + if (user.phone != null) { + final res = await VerifyTeamMemberSheet.show( + context, + phoneNumber: user.phone! + .substring(user.phone!.length - 5)); + if (res != null && res && context.mounted) { + notifier.selectUser(user); + } + } + }, ), ), ), diff --git a/khelo/lib/ui/flow/team/add_team_member/components/verify_team_member_sheet.dart b/khelo/lib/ui/flow/team/add_team_member/components/verify_team_member_sheet.dart index fb82e429..8f5f4d53 100644 --- a/khelo/lib/ui/flow/team/add_team_member/components/verify_team_member_sheet.dart +++ b/khelo/lib/ui/flow/team/add_team_member/components/verify_team_member_sheet.dart @@ -52,6 +52,8 @@ class _VerifyTeamMemberSheetState extends State { PrimaryButton( context.l10n.common_cancel_title, expanded: false, + background: context.colorScheme.containerLow, + foreground: context.colorScheme.primary, onPressed: context.pop, ), PrimaryButton( diff --git a/khelo/lib/ui/flow/team/detail/team_detail_screen.dart b/khelo/lib/ui/flow/team/detail/team_detail_screen.dart index 9ff3e324..1389da93 100644 --- a/khelo/lib/ui/flow/team/detail/team_detail_screen.dart +++ b/khelo/lib/ui/flow/team/detail/team_detail_screen.dart @@ -1,7 +1,4 @@ -import 'dart:io'; - import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:khelo/components/action_bottom_sheet.dart'; @@ -15,6 +12,7 @@ import 'package:khelo/ui/app_route.dart'; import 'package:khelo/ui/flow/team/detail/components/team_detail_member_content.dart'; import 'package:khelo/ui/flow/team/detail/team_detail_view_model.dart'; import 'package:style/button/action_button.dart'; +import 'package:style/button/more_option_button.dart'; import 'package:style/button/tab_button.dart'; import 'package:style/extensions/context_extensions.dart'; import 'package:style/indicator/progress_indicator.dart'; @@ -74,13 +72,8 @@ class _TeamDetailScreenState extends ConsumerState { )), actions: (state.currentUserId == state.team?.created_by) ? [ - actionButton( + moreOptionButton( context, - icon: Icon( - Platform.isIOS - ? Icons.more_horiz_rounded - : Icons.more_vert_rounded, - color: context.colorScheme.textPrimary), onPressed: () => _moreActionButton(context, notifier, state), ), ] diff --git a/khelo/lib/ui/flow/team/search_team/components/team_member_sheet.dart b/khelo/lib/ui/flow/team/search_team/components/team_member_sheet.dart index ce274564..75ec9577 100644 --- a/khelo/lib/ui/flow/team/search_team/components/team_member_sheet.dart +++ b/khelo/lib/ui/flow/team/search_team/components/team_member_sheet.dart @@ -6,7 +6,7 @@ import 'package:go_router/go_router.dart'; import 'package:khelo/components/user_detail_cell.dart'; import 'package:khelo/domain/extensions/context_extensions.dart'; import 'package:khelo/ui/flow/team/add_team_member/components/verify_team_member_sheet.dart'; -import 'package:style/animations/on_tap_scale.dart'; +import 'package:style/button/secondary_button.dart'; import 'package:style/extensions/context_extensions.dart'; import 'package:style/text/app_text_style.dart'; @@ -75,8 +75,9 @@ class TeamMemberSheet extends StatelessWidget { } Widget _selectButton(BuildContext context, UserModel user) { - return OnTapScale( - onTap: () async { + return SecondaryButton( + context.l10n.common_select_title, + onPressed: () async { if (user.phone != null) { final res = await VerifyTeamMemberSheet.show(context, phoneNumber: user.phone!); @@ -85,17 +86,6 @@ class TeamMemberSheet extends StatelessWidget { } } }, - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), - decoration: BoxDecoration( - color: context.colorScheme.containerLow, - borderRadius: BorderRadius.circular(20)), - child: Text( - context.l10n.common_select_title, - style: AppTextStyle.body2 - .copyWith(color: context.colorScheme.textDisabled), - ), - ), ); } } diff --git a/khelo/lib/ui/flow/team/search_team/search_team_screen.dart b/khelo/lib/ui/flow/team/search_team/search_team_screen.dart index 976ed9f9..1a4f9cd5 100644 --- a/khelo/lib/ui/flow/team/search_team/search_team_screen.dart +++ b/khelo/lib/ui/flow/team/search_team/search_team_screen.dart @@ -76,7 +76,7 @@ class _SearchTeamScreenState extends ConsumerState { Assets.images.icCheck, colorFilter: ColorFilter.mode( state.selectedTeam != null - ? context.colorScheme.primary + ? context.colorScheme.textPrimary : context.colorScheme.textDisabled, BlendMode.srcIn, ), diff --git a/khelo/lib/ui/flow/team/team_list_screen.dart b/khelo/lib/ui/flow/team/team_list_screen.dart index 5a6d21a9..fcddae8f 100644 --- a/khelo/lib/ui/flow/team/team_list_screen.dart +++ b/khelo/lib/ui/flow/team/team_list_screen.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:data/api/team/team_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -13,7 +11,7 @@ import 'package:khelo/domain/extensions/context_extensions.dart'; import 'package:khelo/ui/app_route.dart'; import 'package:khelo/ui/flow/team/team_list_view_model.dart'; import 'package:style/animations/on_tap_scale.dart'; -import 'package:style/button/action_button.dart'; +import 'package:style/button/more_option_button.dart'; import 'package:style/extensions/context_extensions.dart'; import 'package:style/indicator/progress_indicator.dart'; import 'package:style/text/app_text_style.dart'; @@ -28,12 +26,8 @@ class TeamListScreen extends ConsumerStatefulWidget { } class _TeamListScreenState extends ConsumerState - with AutomaticKeepAliveClientMixin, WidgetsBindingObserver { + with WidgetsBindingObserver { late TeamListViewNotifier notifier; - bool _wantKeepAlive = true; - - @override - bool get wantKeepAlive => _wantKeepAlive; @override void initState() { @@ -43,15 +37,7 @@ class _TeamListScreenState extends ConsumerState @override void didChangeAppLifecycleState(AppLifecycleState state) { - if (state == AppLifecycleState.paused) { - setState(() { - _wantKeepAlive = false; - }); - } else if (state == AppLifecycleState.resumed) { - setState(() { - _wantKeepAlive = true; - }); - } else if (state == AppLifecycleState.detached) { + if (state == AppLifecycleState.detached) { // deallocate resources notifier.dispose(); WidgetsBinding.instance.removeObserver(this); @@ -60,7 +46,6 @@ class _TeamListScreenState extends ConsumerState @override Widget build(BuildContext context) { - super.build(context); notifier = ref.watch(teamListViewStateProvider.notifier); _observeShowFilterOptionSheet(context, ref); @@ -153,14 +138,10 @@ class _TeamListScreenState extends ConsumerState ) : null, trailing: showMoreOptionButton - ? actionButton(context, + ? moreOptionButton( + context, onPressed: () => _moreActionButton(context, team), - icon: Icon( - Platform.isIOS - ? Icons.more_horiz_rounded - : Icons.more_vert_rounded, - color: context.colorScheme.textPrimary, - )) + ) : null, ), ), diff --git a/khelo/lib/ui/flow/team/team_list_view_model.dart b/khelo/lib/ui/flow/team/team_list_view_model.dart index ef4dd697..04e7e395 100644 --- a/khelo/lib/ui/flow/team/team_list_view_model.dart +++ b/khelo/lib/ui/flow/team/team_list_view_model.dart @@ -31,6 +31,9 @@ class TeamListViewNotifier extends StateNotifier { } void setUserId(String? userId) { + if (userId == null) { + _cancelStreamSubscription(); + } state = state.copyWith(currentUserId: userId); } diff --git a/style/lib/button/back_button.dart b/style/lib/button/back_button.dart new file mode 100644 index 00000000..79934650 --- /dev/null +++ b/style/lib/button/back_button.dart @@ -0,0 +1,17 @@ +import 'package:flutter/material.dart'; +import 'package:style/button/action_button.dart'; +import 'package:style/extensions/context_extensions.dart'; + +Widget backButton( + BuildContext context, { + Function()? onPressed, +}) { + return actionButton( + context, + onPressed: onPressed, + icon: Icon( + Icons.arrow_back, + color: context.colorScheme.textPrimary, + ), + ); +} diff --git a/style/lib/button/more_option_button.dart b/style/lib/button/more_option_button.dart new file mode 100644 index 00000000..d9d87083 --- /dev/null +++ b/style/lib/button/more_option_button.dart @@ -0,0 +1,19 @@ +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:style/button/action_button.dart'; +import 'package:style/extensions/context_extensions.dart'; + +Widget moreOptionButton( + BuildContext context, { + Function()? onPressed, + double size = 24, + Color? tintColor, +}) { + return actionButton(context, + onPressed: onPressed, + icon: Icon( + Platform.isIOS ? Icons.more_horiz_rounded : Icons.more_vert_rounded, + size: size, + color: tintColor ?? context.colorScheme.textPrimary, + )); +} diff --git a/style/lib/button/secondary_button.dart b/style/lib/button/secondary_button.dart new file mode 100644 index 00000000..80b91f1a --- /dev/null +++ b/style/lib/button/secondary_button.dart @@ -0,0 +1,45 @@ +import 'package:flutter/material.dart'; +import 'package:style/animations/on_tap_scale.dart'; +import 'package:style/extensions/context_extensions.dart'; +import 'package:style/text/app_text_style.dart'; + +class SecondaryButton extends StatelessWidget { + final String text; + final bool enabled; + final Function()? onPressed; + + const SecondaryButton( + this.text, { + super.key, + this.enabled = true, + required this.onPressed, + }); + + @override + Widget build(BuildContext context) { + return OnTapScale( + onTap: onPressed, + enabled: enabled, + child: Material( + type: MaterialType.transparency, + child: Chip( + label: Text( + text, + style: AppTextStyle.body2.copyWith( + color: enabled + ? context.colorScheme.primary + : Color.alphaBlend( + context.colorScheme.primary.withOpacity(0.5), + context.colorScheme.surface)), + ), + backgroundColor: context.colorScheme.containerLowOnSurface, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + side: const BorderSide(color: Colors.transparent), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30), + ), + ), + ), + ); + } +} diff --git a/style/lib/theme/colors.dart b/style/lib/theme/colors.dart index b45f3299..6779991e 100644 --- a/style/lib/theme/colors.dart +++ b/style/lib/theme/colors.dart @@ -2,7 +2,8 @@ import 'package:flutter/material.dart'; import '../text/app_text_style.dart'; -const primaryColor = Color(0xFF01579B); +const primaryLightColor = Color(0xFF01579B); +const primaryDarkColor = Color(0xFF0075D1); const primaryVariantLightColor = Color(0x4D01579B); const primaryVariantDarkColor = Color(0x6601579B); @@ -13,9 +14,9 @@ const containerHighLightColor = Color(0x1401345D); const containerNormalLightColor = Color(0x0F01345D); const containerLowLightColor = Color(0x0A01345D); -const containerHighDarkColor = Color(0x14D1E1ED); -const containerNormalDarkColor = Color(0x0FD1E1ED); -const containerLowDarkColor = Color(0x0AD1E1ED); +const containerHighDarkColor = Color(0x3DD1E1ED); +const containerNormalDarkColor = Color(0x29D1E1ED); +const containerLowDarkColor = Color(0x14D1E1ED); const textPrimaryLightColor = Color(0xDE000000); const textSecondaryLightColor = Color(0x99000000); @@ -25,7 +26,8 @@ const textPrimaryDarkColor = Color(0xFFFFFFFF); const textSecondaryDarkColor = Color(0xDEFFFFFF); const textDisabledDarkColor = Color(0x99FFFFFF); -const outlineColor = Color(0xFFEBEBEB); +const outlineLightColor = Color(0x14000000); +const outlineDarkColor = Color(0x1FFFFFFF); const surfaceLightColor = Color(0xFFFFFFFF); const surfaceDarkColor = Color(0xFF212121); @@ -39,12 +41,12 @@ final ThemeData _materialLightTheme = ThemeData.light(useMaterial3: true); final ThemeData _materialDarkTheme = ThemeData.dark(useMaterial3: true); final ThemeData materialThemeDataLight = _materialLightTheme.copyWith( - primaryColor: primaryColor, - dividerColor: outlineColor, + primaryColor: primaryLightColor, + dividerColor: outlineLightColor, datePickerTheme: _materialLightTheme.datePickerTheme.copyWith( backgroundColor: surfaceLightColor, headerForegroundColor: textPrimaryLightColor, - dividerColor: outlineColor, + dividerColor: outlineLightColor, inputDecorationTheme: _materialLightTheme.datePickerTheme.inputDecorationTheme?.copyWith( errorBorder: const OutlineInputBorder( @@ -54,7 +56,7 @@ final ThemeData materialThemeDataLight = _materialLightTheme.copyWith( timePickerTheme: _materialLightTheme.timePickerTheme.copyWith( backgroundColor: surfaceLightColor, dialBackgroundColor: containerLowLightColor, - dayPeriodColor: primaryColor, + dayPeriodColor: primaryLightColor, hourMinuteColor: containerLowLightColor, inputDecorationTheme: _materialLightTheme.timePickerTheme.inputDecorationTheme?.copyWith( @@ -63,7 +65,7 @@ final ThemeData materialThemeDataLight = _materialLightTheme.copyWith( ), ), colorScheme: _materialLightTheme.colorScheme.copyWith( - primary: primaryColor, + primary: primaryLightColor, secondary: secondaryColor, surface: surfaceLightColor, onPrimary: textPrimaryDarkColor, @@ -82,12 +84,12 @@ final ThemeData materialThemeDataLight = _materialLightTheme.copyWith( ); final ThemeData materialThemeDataDark = _materialDarkTheme.copyWith( - primaryColor: primaryColor, - dividerColor: outlineColor, + primaryColor: primaryDarkColor, + dividerColor: outlineDarkColor, datePickerTheme: _materialDarkTheme.datePickerTheme.copyWith( backgroundColor: surfaceDarkColor, headerForegroundColor: textPrimaryDarkColor, - dividerColor: outlineColor, + dividerColor: outlineDarkColor, inputDecorationTheme: _materialDarkTheme.datePickerTheme.inputDecorationTheme?.copyWith( errorBorder: const OutlineInputBorder( @@ -97,7 +99,7 @@ final ThemeData materialThemeDataDark = _materialDarkTheme.copyWith( timePickerTheme: _materialDarkTheme.timePickerTheme.copyWith( backgroundColor: surfaceDarkColor, dialBackgroundColor: containerLowDarkColor, - dayPeriodColor: primaryColor, + dayPeriodColor: primaryDarkColor, hourMinuteColor: containerLowDarkColor, inputDecorationTheme: _materialDarkTheme.timePickerTheme.inputDecorationTheme?.copyWith( @@ -106,7 +108,7 @@ final ThemeData materialThemeDataDark = _materialDarkTheme.copyWith( ), ), colorScheme: _materialDarkTheme.colorScheme.copyWith( - primary: primaryColor, + primary: primaryDarkColor, secondary: secondaryColor, surface: surfaceDarkColor, onPrimary: textPrimaryDarkColor, @@ -187,11 +189,11 @@ class AppColorScheme { } final appColorSchemeLight = AppColorScheme( - primary: primaryColor, + primary: primaryLightColor, primaryVariant: primaryVariantLightColor, secondary: secondaryColor, surface: surfaceLightColor, - outline: outlineColor, + outline: outlineLightColor, textPrimary: textPrimaryLightColor, textSecondary: textSecondaryLightColor, textDisabled: textDisabledLightColor, @@ -213,11 +215,11 @@ final appColorSchemeLight = AppColorScheme( ); final appColorSchemeDark = AppColorScheme( - primary: primaryColor, + primary: primaryDarkColor, primaryVariant: primaryVariantDarkColor, secondary: secondaryColor, surface: surfaceDarkColor, - outline: outlineColor, + outline: outlineDarkColor, textPrimary: textPrimaryDarkColor, textSecondary: textSecondaryDarkColor, textDisabled: textDisabledDarkColor,