diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/setting/workspace/invite_members_screen.dart b/frontend/appflowy_flutter/lib/mobile/presentation/setting/workspace/invite_members_screen.dart index 4f16aabffd..62aa114ef3 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/setting/workspace/invite_members_screen.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/setting/workspace/invite_members_screen.dart @@ -276,10 +276,11 @@ class _InviteMemberPageState extends State<_InviteMemberPage> { void _inviteMember(BuildContext context) { final email = emailController.text; if (!isEmail(email)) { - return showToastNotification( + showToastNotification( type: ToastificationType.error, message: LocaleKeys.settings_appearance_members_emailInvalidError.tr(), ); + return; } context .read() diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/file/file_util.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/file/file_util.dart index d7ae7c5ccf..83debdd71b 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/file/file_util.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/file/file_util.dart @@ -104,9 +104,10 @@ Future downloadMediaFile( await afLaunchUrlString(file.url); } else { if (userProfile == null) { - return showToastNotification( + showToastNotification( message: LocaleKeys.grid_media_downloadFailedToken.tr(), ); + return; } final uri = Uri.parse(file.url); diff --git a/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/continue_with/continue_with_email_and_password.dart b/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/continue_with/continue_with_email_and_password.dart index 2aa30ca0f1..e918c3f4f1 100644 --- a/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/continue_with/continue_with_email_and_password.dart +++ b/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/continue_with/continue_with_email_and_password.dart @@ -2,8 +2,6 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/user/application/sign_in_bloc.dart'; import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/continue_with/continue_with_email.dart'; import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/continue_with/continue_with_magic_link_or_passcode_page.dart'; -import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/continue_with/continue_with_password.dart'; -import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/continue_with/continue_with_password_page.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy_ui/appflowy_ui.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -59,13 +57,14 @@ class _ContinueWithEmailAndPasswordState controller.text, ), ), - VSpace(theme.spacing.l), - ContinueWithPassword( - onTap: () => _pushContinueWithPasswordPage( - context, - controller.text, - ), - ), + // Hide password sign in until we implement the reset password / forgot password + // VSpace(theme.spacing.l), + // ContinueWithPassword( + // onTap: () => _pushContinueWithPasswordPage( + // context, + // controller.text, + // ), + // ), ], ); } @@ -75,10 +74,11 @@ class _ContinueWithEmailAndPasswordState String email, ) { if (!isEmail(email)) { - return showToastNotification( + showToastNotification( message: LocaleKeys.signIn_invalidEmail.tr(), type: ToastificationType.error, ); + return; } final signInBloc = context.read(); @@ -89,13 +89,16 @@ class _ContinueWithEmailAndPasswordState Navigator.push( context, MaterialPageRoute( - builder: (context) => ContinueWithMagicLinkOrPasscodePage( - email: email, - backToLogin: () => Navigator.pop(context), - onEnterPasscode: (passcode) => signInBloc.add( - SignInEvent.signInWithPasscode( - email: email, - passcode: passcode, + builder: (context) => BlocProvider.value( + value: signInBloc, + child: ContinueWithMagicLinkOrPasscodePage( + email: email, + backToLogin: () => Navigator.pop(context), + onEnterPasscode: (passcode) => signInBloc.add( + SignInEvent.signInWithPasscode( + email: email, + passcode: passcode, + ), ), ), ), @@ -103,28 +106,28 @@ class _ContinueWithEmailAndPasswordState ); } - void _pushContinueWithPasswordPage( - BuildContext context, - String email, - ) { - final signInBloc = context.read(); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => ContinueWithPasswordPage( - email: email, - backToLogin: () => Navigator.pop(context), - onEnterPassword: (password) => signInBloc.add( - SignInEvent.signInWithEmailAndPassword( - email: email, - password: password, - ), - ), - onForgotPassword: () { - // todo: implement forgot password - }, - ), - ), - ); - } + // void _pushContinueWithPasswordPage( + // BuildContext context, + // String email, + // ) { + // final signInBloc = context.read(); + // Navigator.push( + // context, + // MaterialPageRoute( + // builder: (context) => ContinueWithPasswordPage( + // email: email, + // backToLogin: () => Navigator.pop(context), + // onEnterPassword: (password) => signInBloc.add( + // SignInEvent.signInWithEmailAndPassword( + // email: email, + // password: password, + // ), + // ), + // onForgotPassword: () { + // // todo: implement forgot password + // }, + // ), + // ), + // ); + // } } diff --git a/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/continue_with/continue_with_magic_link_or_passcode_page.dart b/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/continue_with/continue_with_magic_link_or_passcode_page.dart index 874cb40bf8..17e41ec715 100644 --- a/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/continue_with/continue_with_magic_link_or_passcode_page.dart +++ b/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/continue_with/continue_with_magic_link_or_passcode_page.dart @@ -1,7 +1,10 @@ +import 'package:appflowy/user/application/sign_in_bloc.dart'; import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/logo/logo.dart'; +import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy_ui/appflowy_ui.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; class ContinueWithMagicLinkOrPasscodePage extends StatefulWidget { const ContinueWithMagicLinkOrPasscodePage({ @@ -26,6 +29,8 @@ class _ContinueWithMagicLinkOrPasscodePageState bool isEnteringPasscode = false; + ToastificationItem? toastificationItem; + @override void dispose() { passcodeController.dispose(); @@ -35,22 +40,31 @@ class _ContinueWithMagicLinkOrPasscodePageState @override Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: SizedBox( - width: 320, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - // Logo, title and description - ..._buildLogoTitleAndDescription(), + return BlocListener( + listener: (context, state) { + if (state.isSubmitting) { + _showLoadingDialog(); + } else { + _dismissLoadingDialog(); + } + }, + child: Scaffold( + body: Center( + child: SizedBox( + width: 320, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Logo, title and description + ..._buildLogoTitleAndDescription(), - // Enter code manually - ..._buildEnterCodeManually(), + // Enter code manually + ..._buildEnterCodeManually(), - // Back to login - ..._buildBackToLogin(), - ], + // Back to login + ..._buildBackToLogin(), + ], + ), ), ), ), @@ -91,7 +105,7 @@ class _ContinueWithMagicLinkOrPasscodePageState // continue to login AFFilledTextButton.primary( - text: 'Continue to sign up', + text: 'Continue to sign in', onTap: () => widget.onEnterPasscode(passcodeController.text), size: AFButtonSize.l, alignment: Alignment.center, @@ -109,6 +123,9 @@ class _ContinueWithMagicLinkOrPasscodePageState onTap: widget.backToLogin, textColor: (context, isHovering, disabled) { final theme = AppFlowyTheme.of(context); + if (isHovering) { + return theme.fillColorScheme.themeThickHover; + } return theme.textColorScheme.theme; }, ), @@ -150,4 +167,19 @@ class _ContinueWithMagicLinkOrPasscodePageState spacing, ]; } + + void _showLoadingDialog() { + _dismissLoadingDialog(); + + toastificationItem = showToastNotification( + message: 'Signing in...', + ); + } + + void _dismissLoadingDialog() { + final toastificationItem = this.toastificationItem; + if (toastificationItem != null) { + toastification.dismiss(toastificationItem); + } + } } diff --git a/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/magic_link_sign_in_buttons.dart b/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/magic_link_sign_in_buttons.dart index 9de32861d5..45e4fe7273 100644 --- a/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/magic_link_sign_in_buttons.dart +++ b/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/magic_link_sign_in_buttons.dart @@ -64,10 +64,11 @@ class _SignInWithMagicLinkButtonsState void _sendMagicLink(BuildContext context, String email) { if (!isEmail(email)) { - return showToastNotification( + showToastNotification( message: LocaleKeys.signIn_invalidEmail.tr(), type: ToastificationType.error, ); + return; } context diff --git a/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/third_party_sign_in_button/third_party_sign_in_buttons.dart b/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/third_party_sign_in_button/third_party_sign_in_buttons.dart index 9d11aa01ec..2d1db069e1 100644 --- a/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/third_party_sign_in_button/third_party_sign_in_buttons.dart +++ b/frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/widgets/third_party_sign_in_button/third_party_sign_in_buttons.dart @@ -104,6 +104,9 @@ class _DesktopThirdPartySignInState extends State<_DesktopThirdPartySignIn> { AFGhostTextButton( text: 'More options', textColor: (context, isHovering, disabled) { + if (isHovering) { + return theme.fillColorScheme.themeThickHover; + } return theme.textColorScheme.theme; }, onTap: () { diff --git a/frontend/appflowy_flutter/lib/workspace/application/sidebar/billing/sidebar_plan_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/sidebar/billing/sidebar_plan_bloc.dart index 1737494530..2fae0e4872 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/sidebar/billing/sidebar_plan_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/sidebar/billing/sidebar_plan_bloc.dart @@ -188,6 +188,9 @@ class SidebarPlanBloc extends Bloc { UserEventGetWorkspaceUsage(payload).send().then((result) { result.onSuccess( (usage) { + if (isClosed) { + return; + } add(SidebarPlanEvent.updateWorkspaceUsage(usage)); }, ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/dialogs.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/dialogs.dart index 3bcc840582..7e30c4fa55 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/dialogs.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/dialogs.dart @@ -362,7 +362,7 @@ class OkCancelButton extends StatelessWidget { } } -void showToastNotification({ +ToastificationItem showToastNotification({ String? message, TextSpan? richMessage, String? description, @@ -374,7 +374,7 @@ void showToastNotification({ (message == null) != (richMessage == null), "Exactly one of message or richMessage must be non-null.", ); - toastification.showCustom( + return toastification.showCustom( alignment: Alignment.bottomCenter, autoCloseDuration: const Duration(milliseconds: 3000), callbacks: callbacks ?? const ToastificationCallbacks(),