mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: support canceling the sign-in event (#4342)
This commit is contained in:
@ -2,13 +2,13 @@ import 'package:appflowy/env/cloud_env.dart';
|
|||||||
import 'package:appflowy/startup/startup.dart';
|
import 'package:appflowy/startup/startup.dart';
|
||||||
import 'package:appflowy/startup/tasks/appflowy_cloud_task.dart';
|
import 'package:appflowy/startup/tasks/appflowy_cloud_task.dart';
|
||||||
import 'package:appflowy/user/application/auth/auth_service.dart';
|
import 'package:appflowy/user/application/auth/auth_service.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/code.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/code.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'
|
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'
|
||||||
show UserProfilePB;
|
show UserProfilePB;
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
part 'sign_in_bloc.freezed.dart';
|
part 'sign_in_bloc.freezed.dart';
|
||||||
|
|
||||||
@ -105,6 +105,16 @@ class SignInBloc extends Bloc<SignInEvent, SignInState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
cancel: (value) {
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
isSubmitting: false,
|
||||||
|
emailError: none(),
|
||||||
|
passwordError: none(),
|
||||||
|
successOrFail: none(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -245,6 +255,7 @@ class SignInEvent with _$SignInEvent {
|
|||||||
const factory SignInEvent.passwordChanged(String password) = PasswordChanged;
|
const factory SignInEvent.passwordChanged(String password) = PasswordChanged;
|
||||||
const factory SignInEvent.deepLinkStateChange(DeepLinkResult result) =
|
const factory SignInEvent.deepLinkStateChange(DeepLinkResult result) =
|
||||||
_DeepLinkStateChange;
|
_DeepLinkStateChange;
|
||||||
|
const factory SignInEvent.cancel() = _Cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
|
import 'package:appflowy/mobile/presentation/base/app_bar_actions.dart';
|
||||||
|
import 'package:appflowy/user/application/sign_in_bloc.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
|
class MobileLoadingScreen extends StatelessWidget {
|
||||||
|
const MobileLoadingScreen({
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
const double spacing = 16;
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: AppBarCloseButton(
|
||||||
|
onTap: () => context.read<SignInBloc>().add(
|
||||||
|
const SignInEvent.cancel(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
elevation: 0,
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
FlowyText(LocaleKeys.signIn_signingInText.tr()),
|
||||||
|
const VSpace(spacing),
|
||||||
|
const CircularProgressIndicator(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -2,106 +2,89 @@ import 'package:appflowy/env/cloud_env.dart';
|
|||||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';
|
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class MobileSignInScreen extends StatelessWidget {
|
class MobileSignInScreen extends StatelessWidget {
|
||||||
const MobileSignInScreen({super.key, required this.isLoading});
|
const MobileSignInScreen({
|
||||||
final bool isLoading;
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
const double spacing = 16;
|
const double spacing = 16;
|
||||||
// Welcome to Appflowy
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
final welcomeString = LocaleKeys.welcomeText.tr();
|
|
||||||
final style = Theme.of(context);
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
resizeToAvoidBottomInset: false,
|
body: Padding(
|
||||||
body: isLoading
|
padding: const EdgeInsets.symmetric(vertical: 50, horizontal: 40),
|
||||||
? // TODO(yijing): improve loading effect in the future
|
child: Column(
|
||||||
const Center(
|
children: [
|
||||||
child: Column(
|
const Spacer(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
flex: 4,
|
||||||
children: [
|
|
||||||
Text('Signing in...'),
|
|
||||||
VSpace(spacing),
|
|
||||||
CircularProgressIndicator(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(50, 0, 50, 30),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
const Spacer(
|
|
||||||
flex: 4,
|
|
||||||
),
|
|
||||||
const FlowySvg(
|
|
||||||
FlowySvgs.flowy_logo_xl,
|
|
||||||
size: Size.square(64),
|
|
||||||
blendMode: null,
|
|
||||||
),
|
|
||||||
const VSpace(spacing * 2),
|
|
||||||
// Welcome to
|
|
||||||
Text(
|
|
||||||
welcomeString.substring(0, welcomeString.length - 8),
|
|
||||||
style: style.textTheme.displayMedium,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
// Appflowy
|
|
||||||
Text(
|
|
||||||
welcomeString.substring(welcomeString.length - 8),
|
|
||||||
style: style.textTheme.displayLarge,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
const VSpace(spacing),
|
|
||||||
// TODO(yijing): confirm the subtitle before release app
|
|
||||||
Text(
|
|
||||||
'You are in charge of your data and customizations.',
|
|
||||||
style: style.textTheme.bodyMedium?.copyWith(
|
|
||||||
color: style.colorScheme.onSecondary,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
const Spacer(
|
|
||||||
flex: 2,
|
|
||||||
),
|
|
||||||
if (!PlatformExtension.isMobile) ...[
|
|
||||||
const SignInAnonymousButton(),
|
|
||||||
const VSpace(spacing),
|
|
||||||
],
|
|
||||||
if (isAuthEnabled) ...[
|
|
||||||
if (!PlatformExtension.isMobile) ...[
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
const Expanded(child: Divider()),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
|
||||||
child: Text(
|
|
||||||
LocaleKeys.signIn_or.tr(),
|
|
||||||
style: style.textTheme.bodyMedium?.copyWith(
|
|
||||||
color: style.colorScheme.onSecondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Expanded(child: Divider()),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const VSpace(spacing),
|
|
||||||
],
|
|
||||||
const ThirdPartySignInButtons(),
|
|
||||||
],
|
|
||||||
if (!isAuthEnabled)
|
|
||||||
const Spacer(
|
|
||||||
flex: 2,
|
|
||||||
),
|
|
||||||
const VSpace(spacing),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
const FlowySvg(
|
||||||
|
FlowySvgs.flowy_logo_xl,
|
||||||
|
size: Size.square(64),
|
||||||
|
blendMode: null,
|
||||||
|
),
|
||||||
|
const VSpace(spacing * 2),
|
||||||
|
// Welcome to
|
||||||
|
FlowyText(
|
||||||
|
LocaleKeys.welcomeTo.tr(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
fontSize: 32,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
// AppFlowy
|
||||||
|
FlowyText(
|
||||||
|
LocaleKeys.appName.tr(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
fontSize: 32,
|
||||||
|
color: const Color(0xFF00BCF0),
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
const VSpace(spacing),
|
||||||
|
const Spacer(
|
||||||
|
flex: 2,
|
||||||
|
),
|
||||||
|
|
||||||
|
// disable anonymous sign in release mode.
|
||||||
|
if (kDebugMode) ...[
|
||||||
|
const SignInAnonymousButton(),
|
||||||
|
const VSpace(spacing),
|
||||||
|
],
|
||||||
|
|
||||||
|
// if the cloud env is enabled, show the third-party sign in buttons.
|
||||||
|
if (isAuthEnabled) ...[
|
||||||
|
if (kDebugMode) ...[
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Expanded(child: Divider()),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
child: FlowyText(
|
||||||
|
LocaleKeys.signIn_or.tr(),
|
||||||
|
color: colorScheme.onSecondary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Expanded(child: Divider()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const VSpace(spacing),
|
||||||
|
],
|
||||||
|
const ThirdPartySignInButtons(),
|
||||||
|
],
|
||||||
|
if (!isAuthEnabled)
|
||||||
|
const Spacer(
|
||||||
|
flex: 2,
|
||||||
|
),
|
||||||
|
const VSpace(spacing),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import 'package:appflowy/startup/startup.dart';
|
|||||||
import 'package:appflowy/user/application/sign_in_bloc.dart';
|
import 'package:appflowy/user/application/sign_in_bloc.dart';
|
||||||
import 'package:appflowy/user/presentation/router.dart';
|
import 'package:appflowy/user/presentation/router.dart';
|
||||||
import 'package:appflowy/user/presentation/screens/sign_in_screen/desktop_sign_in_screen.dart';
|
import 'package:appflowy/user/presentation/screens/sign_in_screen/desktop_sign_in_screen.dart';
|
||||||
|
import 'package:appflowy/user/presentation/screens/sign_in_screen/mobile_loading_screen.dart';
|
||||||
import 'package:appflowy/user/presentation/screens/sign_in_screen/mobile_sign_in_screen.dart';
|
import 'package:appflowy/user/presentation/screens/sign_in_screen/mobile_sign_in_screen.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -32,12 +33,11 @@ class SignInScreen extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
// When user is logining through 3rd party, a loading widget will appear on the screen. [isLoading] is used to control it is on or not.
|
|
||||||
final isLoading = context.read<SignInBloc>().state.isSubmitting;
|
final isLoading = context.read<SignInBloc>().state.isSubmitting;
|
||||||
if (PlatformExtension.isMobile) {
|
if (PlatformExtension.isMobile) {
|
||||||
return MobileSignInScreen(
|
return isLoading
|
||||||
isLoading: isLoading,
|
? const MobileLoadingScreen()
|
||||||
);
|
: const MobileSignInScreen();
|
||||||
}
|
}
|
||||||
return DesktopSignInScreen(
|
return DesktopSignInScreen(
|
||||||
isLoading: isLoading,
|
isLoading: isLoading,
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"appName": "AppFlowy",
|
"appName": "AppFlowy",
|
||||||
"defaultUsername": "Me",
|
"defaultUsername": "Me",
|
||||||
"welcomeText": "Welcome to @:appName",
|
"welcomeText": "Welcome to @:appName",
|
||||||
|
"welcomeTo": "Welcome to",
|
||||||
"githubStarText": "Star on GitHub",
|
"githubStarText": "Star on GitHub",
|
||||||
"subscribeNewsletterText": "Subscribe to Newsletter",
|
"subscribeNewsletterText": "Subscribe to Newsletter",
|
||||||
"letsGoButtonText": "Quick Start",
|
"letsGoButtonText": "Quick Start",
|
||||||
@ -35,6 +36,7 @@
|
|||||||
"loginStartWithAnonymous": "Start with an anonymous session",
|
"loginStartWithAnonymous": "Start with an anonymous session",
|
||||||
"continueAnonymousUser": "Continue with an anonymous session",
|
"continueAnonymousUser": "Continue with an anonymous session",
|
||||||
"buttonText": "Sign In",
|
"buttonText": "Sign In",
|
||||||
|
"signingInText": "Signing in...",
|
||||||
"forgotPassword": "Forgot Password?",
|
"forgotPassword": "Forgot Password?",
|
||||||
"emailHint": "Email",
|
"emailHint": "Email",
|
||||||
"passwordHint": "Password",
|
"passwordHint": "Password",
|
||||||
|
Reference in New Issue
Block a user