diff --git a/lib/providers/auth.dart b/lib/providers/auth.dart index a481c87..430f91c 100644 --- a/lib/providers/auth.dart +++ b/lib/providers/auth.dart @@ -161,14 +161,15 @@ class _AuthNotifier extends ChangeNotifier { utilities.api.options.headers["authorization"] = "Bearer $token"; utilities.Global.isAuthenticated = true; + isGuest = false; if (player != null) utilities.Global.isPlayerConnected = true; + _recordLoginAnalytics(); // upon successful login, send FCM token and deviceDetail to server _sendDeviceDetail(); // save response in local db _saveResponse(response); - isGuest = false; notifyListeners(); return data_classes.SignInProviderResponse(result: true); @@ -220,6 +221,10 @@ class _AuthNotifier extends ChangeNotifier { utilities.api.options.headers["authorization"] = null; utilities.Global.isAuthenticated = false; + isGuest = true; + if (player != null) utilities.Global.isPlayerConnected = false; + + notifyListeners(); return true; } diff --git a/lib/utilities/navigation.dart b/lib/utilities/navigation.dart index ca8c2db..8e1747e 100644 --- a/lib/utilities/navigation.dart +++ b/lib/utilities/navigation.dart @@ -33,7 +33,6 @@ abstract class Navigation { /// Sanitized routePath by adding / in front /// eg. `friends => /friends` /// eg. `/ => /` - /// eg. `/login => /login` static String sanitizeRoutePath(String routePath) => routePath[0] == "/" ? routePath : "/$routePath"; @@ -41,5 +40,4 @@ abstract class Navigation { /// user lands on a protected route static String? protectedRouteRedirect(BuildContext _, GoRouterState state) => Global.isAuthenticated ? null : screens.Main.routePath; - // TODO: also open the login modal } diff --git a/lib/widgets/button.dart b/lib/widgets/button.dart index 25ada1d..a6f5071 100644 --- a/lib/widgets/button.dart +++ b/lib/widgets/button.dart @@ -1,5 +1,6 @@ import "package:flutter/material.dart"; import "package:paladinsedge/theme/index.dart" as theme; +import "package:paladinsedge/widgets/loading_indicator.dart"; enum ButtonStyle { solid, @@ -12,6 +13,8 @@ class Button extends StatelessWidget { final bool disabled; final MaterialColor color; final ButtonStyle style; + final double width; + final bool isLoading; final Color? backgroundColor; final IconData? leading; final IconData? trailing; @@ -24,6 +27,8 @@ class Button extends StatelessWidget { this.disabled = false, this.color = theme.themeMaterialColor, this.style = ButtonStyle.solid, + this.width = 128, + this.isLoading = false, this.backgroundColor, this.leading, this.trailing, @@ -39,22 +44,23 @@ class Button extends StatelessWidget { final color1 = isLightTheme ? color.shade50 : color.shade700; final color2 = isLightTheme ? color.shade700 : color.shade50; final outlinedColor = isLightTheme ? color2 : color1; + final isDisabled = disabled || isLoading; return style == ButtonStyle.outlined ? SizedBox( height: 36, - width: 128, + width: width, child: TextButton( style: TextButton.styleFrom( backgroundColor: backgroundColor, - elevation: disabled ? 0 : elevation, + elevation: isDisabled ? 0 : elevation, shape: const StadiumBorder(), side: BorderSide( color: outlinedColor, width: 1, ), ), - onPressed: disabled ? null : onPressed, + onPressed: isDisabled ? null : onPressed, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -71,7 +77,7 @@ class Button extends StatelessWidget { label, style: TextStyle( fontSize: 14, - color: disabled ? null : outlinedColor, + color: isDisabled ? null : outlinedColor, ).merge(labelStyle), ), if (trailing != null) @@ -80,7 +86,7 @@ class Button extends StatelessWidget { child: Icon( trailing, size: 14, - color: disabled ? null : outlinedColor, + color: isDisabled ? null : outlinedColor, ), ), ], @@ -89,18 +95,26 @@ class Button extends StatelessWidget { ) : SizedBox( height: 36, - width: 128, + width: width, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: color1, - elevation: disabled ? 0 : elevation, + elevation: isDisabled ? 0 : elevation, shape: const StadiumBorder(), ), - onPressed: disabled ? null : onPressed, + onPressed: isDisabled ? null : onPressed, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - if (leading != null) + if (isLoading) + const Padding( + padding: EdgeInsets.only(right: 7.5), + child: LoadingIndicator( + size: 14, + lineWidth: 1.5, + ), + ), + if (leading != null && !isLoading) Padding( padding: const EdgeInsets.only(right: 5), child: Icon( @@ -113,16 +127,16 @@ class Button extends StatelessWidget { label, style: TextStyle( fontSize: 14, - color: disabled ? null : color2, + color: isDisabled ? null : color2, ).merge(labelStyle), ), - if (trailing != null) + if (trailing != null && !isLoading) Padding( padding: const EdgeInsets.only(left: 5), child: Icon( trailing, size: 14, - color: disabled ? null : color2, + color: isDisabled ? null : color2, ), ), ], diff --git a/lib/widgets/connect_player_modal.dart b/lib/widgets/connect_player_modal.dart index 5daf5b4..0e90ab2 100644 --- a/lib/widgets/connect_player_modal.dart +++ b/lib/widgets/connect_player_modal.dart @@ -60,10 +60,23 @@ class _ConnectPlayerHeader extends HookConsumerWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - "Hi, $firstName", - style: textTheme.bodyLarge?.copyWith(fontSize: 18), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Hi, $firstName", + style: textTheme.displayLarge?.copyWith(fontSize: 18), + ), + Text( + "required", + style: textTheme.bodyLarge?.copyWith( + fontSize: 12, + fontStyle: FontStyle.italic, + ), + ), + ], ), + const SizedBox(height: 10), Text( "Link Paladins Edge to your profile, search your name and tap to connect", style: textTheme.bodyLarge?.copyWith(fontSize: 14), @@ -231,13 +244,23 @@ class _ConnectPlayerList extends HookConsumerWidget { [selectedPlayer], ); + final onConnected = useCallback( + () { + utilities.Navigation.pop(context); + }, + [], + ); + final onConnect = useCallback( () async { if (selectedPlayer.value == null) return; isConnecting.value = true; - await authProvider.connectPlayer(selectedPlayer.value!.playerId); + final response = await authProvider.connectPlayer( + selectedPlayer.value!.playerId, + ); isConnecting.value = false; + if (response != null) onConnected(); }, [selectedPlayer, isConnecting], ); @@ -281,9 +304,10 @@ class _ConnectPlayerList extends HookConsumerWidget { ), const SizedBox(width: 10), widgets.Button( - label: "Connect", + label: isConnecting.value ? "Connecting" : "Connect", + width: isConnecting.value ? 150 : 132, onPressed: onConnect, - disabled: isConnecting.value, + isLoading: isConnecting.value, ), ], ), diff --git a/lib/widgets/settings_modal.dart b/lib/widgets/settings_modal.dart index 9a8b69d..f9319b3 100644 --- a/lib/widgets/settings_modal.dart +++ b/lib/widgets/settings_modal.dart @@ -3,7 +3,6 @@ import "package:flutter_feather_icons/flutter_feather_icons.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:paladinsedge/providers/index.dart" as providers; -import "package:paladinsedge/screens/index.dart" as screens; import "package:paladinsedge/utilities/index.dart" as utilities; import "package:paladinsedge/widgets/button.dart" as button_widget; import "package:paladinsedge/widgets/loading_indicator.dart"; @@ -131,14 +130,6 @@ class _SettingsModal extends HookConsumerWidget { [settings], ); - final navigateToMain = useCallback( - () { - utilities.Navigation.pop(context); - utilities.Navigation.navigate(context, screens.Main.routeName); - }, - [], - ); - final onLogoutFail = useCallback( () { showToast( @@ -150,13 +141,19 @@ class _SettingsModal extends HookConsumerWidget { [], ); + final onLogoutSuccess = useCallback( + () { + utilities.Navigation.pop(context); + }, + [], + ); + final onLogout = useCallback( () async { isLoggingOut.value = true; final isLoggedOut = await authProvider.logout(); - if (isLoggedOut) { - navigateToMain(); + onLogoutSuccess(); } else { onLogoutFail(); } diff --git a/pubspec.assets.yaml b/pubspec.assets.yaml index b277a5d..75357e6 100644 --- a/pubspec.assets.yaml +++ b/pubspec.assets.yaml @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.10.1 +version: 1.11.0 homepage: "https://paladinsedge.app" diff --git a/pubspec.yaml b/pubspec.yaml index 6e7ac65..4c94576 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.10.1 +version: 1.11.0 homepage: "https://paladinsedge.app"