refactor: move around order of TOS and username setting in signup (#2002)

This commit is contained in:
ggurdin 2025-03-05 11:24:43 -05:00 committed by GitHub
parent 29504434f3
commit b6a0868e35
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 85 additions and 90 deletions

View file

@ -4776,7 +4776,7 @@
"mediaLabel": "Media learners should share",
"languageOfInstructionsLabel": "Language of activity instructions",
"targetLanguageLabel": "Target language",
"cefrLevelLabel": "CEFR Level",
"cefrLevelLabel": "CEFR level",
"generateActivitiesButton": "Generate Activities",
"launchActivityButton": "Launch Activity",
"image": "Image",
@ -4829,6 +4829,7 @@
"ttsDisabledBody": "You can enable text-to-speech in your learning settings",
"noSpaceDescriptionYet": "No space description created yet.",
"tooLargeToSend": "This message is too large to send",
"displayName": "Display name",
"leaveRoomDescription": "You're about to leave this chat. Other users will see that you have left the chat.",
"confirmUserId": "Please confirm your Pangea Chat username in order to delete your account.",
"startingToday": "Starting today",

View file

@ -10,5 +10,4 @@ class PLocalKey {
static const String justInputtedCode = 'justInputtedCode';
static const String availableSubscriptionInfo = 'availableSubscriptionInfo';
static const String showedUpdateDialog = 'showedUpdateDialog';
static const String loginType = 'loginType';
}

View file

@ -79,9 +79,13 @@ class SignupPageController extends State<SignupPage> {
if (mounted) setState(() {});
}
void setSignupError(String? error) {
signupError = error;
if (mounted) setState(() {});
}
bool get enableSignUp =>
!loadingSignup &&
isTnCChecked &&
emailController.text.isNotEmpty &&
usernameController.text.isNotEmpty &&
passwordController.text.isNotEmpty;
@ -153,10 +157,7 @@ class SignupPageController extends State<SignupPage> {
void signup([_]) async {
setState(() => signupError = null);
final valid = formKey.currentState!.validate();
if (!isTnCChecked) {
setState(() => signupError = L10n.of(context).pleaseAgreeToTOS);
}
if (!valid || !isTnCChecked) return;
if (!valid) return;
setState(() => loadingSignup = true);
await showFutureLoadingDialog(

View file

@ -9,6 +9,7 @@ import 'package:fluffychat/pangea/common/widgets/pangea_logo_svg.dart';
import 'package:fluffychat/pangea/login/pages/pangea_login_scaffold.dart';
import 'package:fluffychat/pangea/login/widgets/full_width_button.dart';
import 'package:fluffychat/pangea/login/widgets/p_sso_button.dart';
import 'package:fluffychat/pangea/login/widgets/tos_checkbox.dart';
import 'signup.dart';
class SignupPageView extends StatelessWidget {
@ -17,29 +18,54 @@ class SignupPageView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return PangeaLoginScaffold(
children: [
FullWidthButton(
title: L10n.of(context).signUpWithEmail,
onPressed: () => context.go('/home/signup/email'),
icon: PangeaLogoSvg(
width: 20,
forceColor: Theme.of(context).colorScheme.onPrimary,
bool validator() {
final valid = controller.formKey.currentState?.validate() ?? false;
if (!valid) return false;
if (!controller.isTnCChecked) {
controller.setSignupError(L10n.of(context).pleaseAgreeToTOS);
return false;
}
return true;
}
return Form(
key: controller.formKey,
child: PangeaLoginScaffold(
children: [
TosCheckbox(
controller.isTnCChecked,
controller.onTncChange,
error: controller.signupError,
),
),
PangeaSsoButton(
provider: SSOProvider.google,
title: L10n.of(context).signUpWithGoogle,
setLoading: controller.setLoadingSSO,
loading: controller.loadingGoogleSSO,
),
PangeaSsoButton(
provider: SSOProvider.apple,
title: L10n.of(context).signUpWithApple,
setLoading: controller.setLoadingSSO,
loading: controller.loadingAppleSSO,
),
],
FullWidthButton(
title: L10n.of(context).signUpWithEmail,
onPressed: () {
if (!validator()) return;
context.go(
'/home/signup/email',
);
},
icon: PangeaLogoSvg(
width: 20,
forceColor: Theme.of(context).colorScheme.onPrimary,
),
),
PangeaSsoButton(
provider: SSOProvider.google,
title: L10n.of(context).signUpWithGoogle,
setLoading: controller.setLoadingSSO,
loading: controller.loadingGoogleSSO,
validator: validator,
),
PangeaSsoButton(
provider: SSOProvider.apple,
title: L10n.of(context).signUpWithApple,
setLoading: controller.setLoadingSSO,
loading: controller.loadingAppleSSO,
validator: validator,
),
],
),
);
}
}

View file

@ -7,7 +7,6 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/pangea/common/widgets/pangea_logo_svg.dart';
import 'package:fluffychat/pangea/login/pages/pangea_login_scaffold.dart';
import 'package:fluffychat/pangea/login/widgets/full_width_button.dart';
import 'package:fluffychat/pangea/login/widgets/tos_checkbox.dart';
import 'signup.dart';
class SignupWithEmailView extends StatelessWidget {
@ -46,11 +45,6 @@ class SignupWithEmailView extends StatelessWidget {
controller: controller.passwordController,
onSubmitted: controller.enableSignUp ? controller.signup : null,
),
TosCheckbox(
controller.isTnCChecked,
controller.onTncChange,
error: controller.signupError,
),
FullWidthButton(
title: L10n.of(context).signUp,
icon: PangeaLogoSvg(

View file

@ -7,7 +7,6 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/pangea/common/constants/local.key.dart';
import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/pangea/learning_settings/enums/language_level_type_enum.dart';
@ -40,8 +39,6 @@ class UserSettingsState extends State<UserSettingsPage> {
Uint8List? avatar;
String? _selectedFilePath;
bool isTncChecked = false;
List<String> avatarPaths = const [
"assets/pangea/Avatar_1.png",
"assets/pangea/Avatar_2.png",
@ -67,6 +64,9 @@ class UserSettingsState extends State<UserSettingsPage> {
super.initState();
selectedTargetLanguage = _pangeaController.languageController.userL2;
selectedAvatarPath = avatarPaths.first;
displayNameController.text = Matrix.of(context).client.userID?.localpart ??
Matrix.of(context).client.userID ??
"";
}
@override
@ -79,19 +79,6 @@ class UserSettingsState extends State<UserSettingsPage> {
super.dispose();
}
bool get isSSOSignup {
final loginTypeEntry = MatrixState.pangeaController.userController.loginBox
.read(PLocalKey.loginType);
return loginTypeEntry is String && loginTypeEntry == 'sso';
}
void setTncChecked(bool? value) {
setState(() {
isTncChecked = value ?? false;
tncError = null;
});
}
void setSelectedTargetLanguage(LanguageModel? language) {
setState(() {
selectedTargetLanguage = language;
@ -187,13 +174,6 @@ class UserSettingsState extends State<UserSettingsPage> {
return;
}
if (isSSOSignup && !isTncChecked) {
setState(() {
tncError = L10n.of(context).pleaseAgreeToTOS;
});
return;
}
if (!formKey.currentState!.validate()) return;
setState(() => loading = true);

View file

@ -9,7 +9,6 @@ import 'package:fluffychat/pangea/learning_settings/widgets/p_language_dropdown.
import 'package:fluffychat/pangea/login/pages/pangea_login_scaffold.dart';
import 'package:fluffychat/pangea/login/pages/user_settings.dart';
import 'package:fluffychat/pangea/login/widgets/full_width_button.dart';
import 'package:fluffychat/pangea/login/widgets/tos_checkbox.dart';
import 'package:fluffychat/pangea/user/utils/p_logout.dart';
class UserSettingsView extends StatelessWidget {
@ -96,6 +95,17 @@ class UserSettingsView extends StatelessWidget {
alignment: WrapAlignment.center,
children: avatarOptions,
),
FullWidthTextField(
labelText: L10n.of(context).displayName,
hintText: L10n.of(context).username,
validator: (username) {
if (username == null || username.isEmpty) {
return L10n.of(context).pleaseChooseAUsername;
}
return null;
},
controller: controller.displayNameController,
),
Padding(
padding: const EdgeInsets.all(8),
child: PLanguageDropdown(
@ -114,23 +124,6 @@ class UserSettingsView extends StatelessWidget {
initialLevel: controller.selectedCefrLevel,
),
),
if (controller.isSSOSignup)
FullWidthTextField(
hintText: L10n.of(context).username,
validator: (username) {
if (username == null || username.isEmpty) {
return L10n.of(context).pleaseChooseAUsername;
}
return null;
},
controller: controller.displayNameController,
),
if (controller.isSSOSignup)
TosCheckbox(
controller.isTncChecked,
controller.setTncChecked,
error: controller.tncError,
),
FullWidthButton(
title: L10n.of(context).letsStart,
onPressed: controller.selectedTargetLanguage != null
@ -138,8 +131,7 @@ class UserSettingsView extends StatelessWidget {
: null,
error: controller.profileCreationError,
loading: controller.loading,
enabled: controller.selectedTargetLanguage != null &&
(!controller.isSSOSignup || controller.isTncChecked),
enabled: controller.selectedTargetLanguage != null,
),
],
),

View file

@ -8,7 +8,6 @@ import 'package:universal_html/html.dart' as html;
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pages/homeserver_picker/homeserver_picker.dart';
import 'package:fluffychat/pangea/common/constants/local.key.dart';
import 'package:fluffychat/pangea/common/utils/firebase_analytics.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/matrix.dart';
@ -63,7 +62,5 @@ Future<void> pangeaSSOLoginAction(
initialDeviceDisplayName: PlatformInfos.clientName,
);
MatrixState.pangeaController.userController.loginBox
.write(PLocalKey.loginType, 'sso');
GoogleAnalytics.login(provider.name!, loginRes.userId);
}

View file

@ -121,7 +121,7 @@ class FullWidthTextField extends StatelessWidget {
final bool? showErrorText;
final String? errorText;
final Function(String)? onSubmitted;
final InputDecoration? decoration;
final String? labelText;
const FullWidthTextField({
required this.hintText,
@ -134,7 +134,7 @@ class FullWidthTextField extends StatelessWidget {
this.errorText,
this.showErrorText,
this.onSubmitted,
this.decoration,
this.labelText,
super.key,
});
@ -150,6 +150,7 @@ class FullWidthTextField extends StatelessWidget {
textInputAction: textInputAction,
keyboardType: keyboardType,
decoration: InputDecoration(
labelText: labelText,
hintText: hintText,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(36.0),

View file

@ -47,12 +47,14 @@ class PangeaSsoButton extends StatelessWidget {
final Function(bool, SSOProvider) setLoading;
final bool loading;
final bool? Function()? validator;
const PangeaSsoButton({
required this.title,
required this.provider,
required this.setLoading,
this.loading = false,
this.validator,
super.key,
});
@ -94,7 +96,13 @@ class PangeaSsoButton extends StatelessWidget {
BlendMode.srcIn,
),
),
onPressed: () => _runSSOLogin(context),
onPressed: () {
if (validator != null) {
final valid = validator!.call() ?? false;
if (!valid) return;
}
_runSSOLogin(context);
},
);
}
}

View file

@ -69,7 +69,8 @@ class TosCheckboxState extends State<TosCheckbox>
child: widget.error == null
? const SizedBox.shrink()
: Padding(
padding: const EdgeInsets.only(top: 4, left: 30),
padding:
const EdgeInsets.only(top: 4, left: 15, bottom: 8),
child: Text(
widget.error!,
style: TextStyle(

View file

@ -1,7 +1,6 @@
import 'dart:async';
import 'package:collection/collection.dart';
import 'package:get_storage/get_storage.dart';
import 'package:jwt_decode/jwt_decode.dart';
import 'package:matrix/matrix.dart' as matrix;
@ -18,7 +17,6 @@ import '../models/user_model.dart';
/// Controller that manages saving and reading of user/profile information
class UserController extends BaseController {
final GetStorage loginBox = GetStorage("login_storage");
late PangeaController _pangeaController;
UserController(PangeaController pangeaController) : super() {
_pangeaController = pangeaController;

View file

@ -5,7 +5,6 @@ import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/pages/login/login.dart';
import 'package:fluffychat/pangea/common/constants/local.key.dart';
import 'package:fluffychat/pangea/common/utils/firebase_analytics.dart';
import 'package:fluffychat/pangea/login/widgets/p_sso_button.dart';
import 'package:fluffychat/utils/platform_infos.dart';
@ -79,7 +78,5 @@ Future<void> _loginFuture({
}
},
);
MatrixState.pangeaController.userController.loginBox
.write(PLocalKey.loginType, 'password');
GoogleAnalytics.login("pangea", loginRes.userId);
}