Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support sign-in and sign-up on Web #5712

Merged
merged 16 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions frontend/appflowy_flutter/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ SPEC CHECKSUMS:
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
flowy_infra_ui: 0455e1fa8c51885aa1437848e361e99419f34ebc
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
fluttertoast: fafc4fa4d01a6a9e4f772ecd190ffa525e9e2d9c
fluttertoast: 31b00dabfa7fb7bacd9e7dbee580d7a2ff4bf265
image_gallery_saver: cb43cc43141711190510e92c460eb1655cd343cb
image_picker_ios: 99dfe1854b4fa34d0364e74a78448a0151025425
integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4
Expand All @@ -191,4 +191,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: d0d9b4ff572d8695c38eb3f9b490f55cdfc57eca

COCOAPODS: 1.11.3
COCOAPODS: 1.15.2
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ class AboutSettingGroup extends StatelessWidget {
trailing: const Icon(
Icons.chevron_right,
),
onTap: () => afLaunchUrlString('https://appflowy.io/privacy/app'),
onTap: () => afLaunchUrlString('https://appflowy.io/privacy'),
),
MobileSettingItem(
name: LocaleKeys.settings_mobile_termsAndConditions.tr(),
trailing: const Icon(
Icons.chevron_right,
),
onTap: () => afLaunchUrlString('https://appflowy.io/terms/app'),
onTap: () => afLaunchUrlString('https://appflowy.io/terms'),
),
if (kDebugMode)
MobileSettingItem(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,8 @@ class DesktopSignInScreen extends StatelessWidget {
const SignInAnonymousButtonV2(),
const VSpace(10),

SwitchSignInSignUpButton(
onTap: () {
final type = state.loginType == LoginType.signIn
? LoginType.signUp
: LoginType.signIn;
context
.read<SignInBloc>()
.add(SignInEvent.switchLoginType(type));
},
),
// sign in agreement
const SignInAgreement(),

// loading status
const VSpace(indicatorMinHeight),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,7 @@ class MobileSignInScreen extends StatelessWidget {
const VSpace(spacing),
const SignInAnonymousButtonV2(),
const VSpace(spacing),
SwitchSignInSignUpButton(
onTap: () {
final type = state.loginType == LoginType.signIn
? LoginType.signUp
: LoginType.signIn;
context.read<SignInBloc>().add(
SignInEvent.switchLoginType(type),
);
},
),
const SignInAgreement(),
const VSpace(spacing),
_buildSettingsButton(context),
if (!isAuthEnabled) const Spacer(flex: 2),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import 'package:flutter/material.dart';

import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/user/application/sign_in_bloc.dart';
import 'package:appflowy/workspace/presentation/home/toast.dart';
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/size.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:string_validator/string_validator.dart';
import 'package:toastification/toastification.dart';

class SignInWithMagicLinkButtons extends StatefulWidget {
const SignInWithMagicLinkButtons({super.key});
Expand Down Expand Up @@ -53,18 +53,19 @@ class _SignInWithMagicLinkButtonsState

void _sendMagicLink(BuildContext context, String email) {
if (!isEmail(email)) {
return showSnackBarMessage(
return showToastNotification(
context,
LocaleKeys.signIn_invalidEmail.tr(),
duration: const Duration(seconds: 8),
message: LocaleKeys.signIn_invalidEmail.tr(),
type: ToastificationType.error,
);
}

context.read<SignInBloc>().add(SignInEvent.signedWithMagicLink(email));
showSnackBarMessage(
context,
LocaleKeys.signIn_magicLinkSent.tr(),
duration: const Duration(seconds: 1000),

showConfirmDialog(
context: context,
title: LocaleKeys.signIn_magicLinkSent.tr(),
description: LocaleKeys.signIn_magicLinkSentDescription.tr(),
);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import 'package:appflowy/core/helpers/url_launcher.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

class SignInAgreement extends StatelessWidget {
const SignInAgreement({
super.key,
});

@override
Widget build(BuildContext context) {
return RichText(
textAlign: TextAlign.center,
text: TextSpan(
children: [
TextSpan(
text: '${LocaleKeys.web_signInAgreement.tr()} ',
style: const TextStyle(color: Colors.grey, fontSize: 12),
),
TextSpan(
text: '${LocaleKeys.web_termOfUse.tr()} ',
style: const TextStyle(color: Colors.blue, fontSize: 12),
mouseCursor: SystemMouseCursors.click,
recognizer: TapGestureRecognizer()
..onTap = () => afLaunchUrlString('https://appflowy.io/terms'),
),
TextSpan(
text: '${LocaleKeys.web_and.tr()} ',
style: const TextStyle(color: Colors.grey, fontSize: 12),
),
TextSpan(
text: LocaleKeys.web_privacyPolicy.tr(),
style: const TextStyle(color: Colors.blue, fontSize: 12),
mouseCursor: SystemMouseCursors.click,
recognizer: TapGestureRecognizer()
..onTap = () => afLaunchUrlString('https://appflowy.io/privacy'),
),
],
),
);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export 'magic_link_sign_in_buttons.dart';
export 'sign_in_anonymous_button.dart';
export 'sign_in_or_logout_button.dart';
export 'switch_sign_in_sign_up_button.dart';

// export 'switch_sign_in_sign_up_button.dart';
export 'third_party_sign_in_buttons.dart';
export 'sign_in_agreement.dart';
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,55 @@ class SpaceCancelOrConfirmButton extends StatelessWidget {
}
}

class ConfirmDeletionPopup extends StatefulWidget {
const ConfirmDeletionPopup({
class SpaceOkButton extends StatelessWidget {
const SpaceOkButton({
super.key,
required this.onConfirm,
required this.confirmButtonName,
this.confirmButtonColor,
});

final VoidCallback onConfirm;
final String confirmButtonName;
final Color? confirmButtonColor;

@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
DecoratedBox(
decoration: ShapeDecoration(
color: confirmButtonColor ?? Theme.of(context).colorScheme.primary,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: FlowyButton(
useIntrinsicWidth: true,
margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 9.0),
radius: BorderRadius.circular(8),
text: FlowyText.regular(
confirmButtonName,
color: Colors.white,
),
onTap: onConfirm,
),
),
],
);
}
}

enum ConfirmPopupStyle {
onlyOk,
cancelAndOk,
}

class ConfirmPopup extends StatefulWidget {
const ConfirmPopup({
super.key,
this.style = ConfirmPopupStyle.cancelAndOk,
required this.title,
required this.description,
required this.onConfirm,
Expand All @@ -234,12 +280,13 @@ class ConfirmDeletionPopup extends StatefulWidget {
final String title;
final String description;
final VoidCallback onConfirm;
final ConfirmPopupStyle style;

@override
State<ConfirmDeletionPopup> createState() => _ConfirmDeletionPopupState();
State<ConfirmPopup> createState() => _ConfirmPopupState();
}

class _ConfirmDeletionPopupState extends State<ConfirmDeletionPopup> {
class _ConfirmPopupState extends State<ConfirmPopup> {
final focusNode = FocusNode();

@override
Expand All @@ -262,46 +309,70 @@ class _ConfirmDeletionPopupState extends State<ConfirmDeletionPopup> {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Flexible(
child: FlowyText(
widget.title,
fontSize: 14.0,
overflow: TextOverflow.ellipsis,
),
),
const HSpace(6.0),
FlowyButton(
useIntrinsicWidth: true,
text: const FlowySvg(FlowySvgs.upgrade_close_s),
onTap: () => Navigator.of(context).pop(),
),
],
),
const VSpace(8.0),
FlowyText.regular(
widget.description,
fontSize: 12.0,
color: Theme.of(context).hintColor,
maxLines: 3,
lineHeight: 1.4,
),
_buildTitle(),
const VSpace(6.0),
_buildDescription(),
const VSpace(20.0),
SpaceCancelOrConfirmButton(
onCancel: () => Navigator.of(context).pop(),
onConfirm: () {
widget.onConfirm();
Navigator.of(context).pop();
},
confirmButtonName: LocaleKeys.space_delete.tr(),
confirmButtonColor: Theme.of(context).colorScheme.error,
),
_buildStyledButton(context),
],
),
),
);
}

Widget _buildTitle() {
return Row(
children: [
Expanded(
child: FlowyText(
widget.title,
fontSize: 14.0,
overflow: TextOverflow.ellipsis,
),
),
const HSpace(6.0),
FlowyButton(
useIntrinsicWidth: true,
text: const FlowySvg(FlowySvgs.upgrade_close_s),
onTap: () => Navigator.of(context).pop(),
),
],
);
}

Widget _buildDescription() {
return FlowyText.regular(
widget.description,
fontSize: 12.0,
color: Theme.of(context).hintColor,
maxLines: 3,
lineHeight: 1.4,
);
}

Widget _buildStyledButton(BuildContext context) {
switch (widget.style) {
case ConfirmPopupStyle.onlyOk:
return SpaceOkButton(
onConfirm: () {
widget.onConfirm();
Navigator.of(context).pop();
},
confirmButtonName: LocaleKeys.button_ok.tr(),
confirmButtonColor: Theme.of(context).colorScheme.primary,
);
case ConfirmPopupStyle.cancelAndOk:
return SpaceCancelOrConfirmButton(
onCancel: () => Navigator.of(context).pop(),
onConfirm: () {
widget.onConfirm();
Navigator.of(context).pop();
},
confirmButtonName: LocaleKeys.space_delete.tr(),
confirmButtonColor: Theme.of(context).colorScheme.error,
);
}
}
}

class SpacePopup extends StatelessWidget {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,11 @@ void showToastNotification(
BuildContext context, {
required String message,
String? description,
ToastificationType type = ToastificationType.success,
}) {
toastification.show(
context: context,
type: ToastificationType.success,
type: type,
style: ToastificationStyle.flat,
title: FlowyText(message),
description: description != null
Expand Down Expand Up @@ -329,7 +330,7 @@ Future<void> showConfirmDeletionDialog({
),
child: SizedBox(
width: 440,
child: ConfirmDeletionPopup(
child: ConfirmPopup(
title: title,
description: description,
onConfirm: onConfirm,
Expand All @@ -339,3 +340,30 @@ Future<void> showConfirmDeletionDialog({
},
);
}

Future<void> showConfirmDialog({
required BuildContext context,
required String title,
required String description,
VoidCallback? onConfirm,
}) {
return showDialog(
context: context,
builder: (_) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: SizedBox(
width: 440,
child: ConfirmPopup(
title: title,
description: description,
onConfirm: () => onConfirm?.call(),
style: ConfirmPopupStyle.onlyOk,
),
),
);
},
);
}
Loading
Loading