Signup login updates (#1324)

* fix: stop signup/login loading on dispose

* fix: if user signs up with SSO, make them agree to TOS on language/avatar settings page
pull/1544/head
ggurdin 10 months ago committed by GitHub
parent 6b24b68239
commit 0368ce3ea7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -72,6 +72,16 @@ class LoginController extends State<Login> {
});
}
@override
void dispose() {
usernameController.dispose();
passwordController.dispose();
loading = false;
usernameError = null;
passwordError = null;
super.dispose();
}
void _setStateOnTextChange(String? oldText, String newText) {
if ((oldText == null || oldText.isEmpty) && (newText.isNotEmpty)) {
setState(() {});

@ -55,6 +55,30 @@ class PangeaSsoButton extends StatefulWidget {
class PangeaSsoButtonState extends State<PangeaSsoButton> {
bool _loading = false;
String? _error;
AppLifecycleListener? _listener;
@override
void initState() {
_listener = AppLifecycleListener(
onStateChange: _onAppLifecycleChange,
);
super.initState();
}
// when the SSO login launches, stop the loading indicator
void _onAppLifecycleChange(AppLifecycleState state) {
if ((state == AppLifecycleState.inactive ||
state == AppLifecycleState.hidden) &&
_loading) {
setState(() => _loading = false);
}
}
@override
void dispose() {
_listener?.dispose();
super.dispose();
}
Future<void> _runSSOLogin() async {
try {

@ -43,6 +43,7 @@ class FullWidthButtonState extends State<FullWidthButton> {
onPressed: widget.onPressed,
borderRadius: BorderRadius.circular(36),
color: Theme.of(context).colorScheme.primary,
isShadow: true,
child: Container(
// internal padding
padding: const EdgeInsets.symmetric(horizontal: 16),

@ -55,6 +55,16 @@ class SignupPageController extends State<SignupPage> {
});
}
@override
void dispose() {
usernameController.dispose();
passwordController.dispose();
emailController.dispose();
loading = false;
error = null;
super.dispose();
}
bool get enableSignUp =>
!loading &&
isTnCChecked &&

@ -44,7 +44,11 @@ class SignupWithEmailView extends StatelessWidget {
validator: controller.password1TextFieldValidator,
controller: controller.passwordController,
),
TosCheckbox(controller),
TosCheckbox(
controller.isTnCChecked,
controller.onTncChange,
error: controller.signupError,
),
FullWidthButton(
title: L10n.of(context).signUp,
icon: PangeaLogoSvg(

@ -29,12 +29,15 @@ class UserSettingsState extends State<UserSettingsPage> {
String? selectedLanguageError;
String? profileCreationError;
String? tncError;
bool loading = false;
Uint8List? avatar;
String? _selectedFilePath;
bool isTncChecked = false;
List<String> avatarPaths = const [
"assets/pangea/Avatar_1.png",
"assets/pangea/Avatar_2.png",
@ -52,7 +55,6 @@ class UserSettingsState extends State<UserSettingsPage> {
: PangeaLanguage.byLangCode(systemLangCode);
}
bool canSetDisplayName = false;
TextEditingController displayNameController = TextEditingController();
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
@ -61,19 +63,31 @@ class UserSettingsState extends State<UserSettingsPage> {
super.initState();
selectedTargetLanguage = _pangeaController.languageController.userL2;
selectedAvatarPath = avatarPaths.first;
final loginTypeEntry =
_pangeaController.pStoreService.read(PLocalKey.loginType);
if (loginTypeEntry is String && loginTypeEntry == 'sso') {
canSetDisplayName = true;
}
}
@override
void dispose() {
displayNameController.dispose();
loading = false;
selectedLanguageError = null;
profileCreationError = null;
tncError = null;
super.dispose();
}
bool get isSSOSignup {
final loginTypeEntry =
_pangeaController.pStoreService.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;
@ -150,7 +164,11 @@ class UserSettingsState extends State<UserSettingsPage> {
}
Future<void> createUserInPangea() async {
setState(() => profileCreationError = null);
setState(() {
profileCreationError = null;
selectedLanguageError = null;
tncError = null;
});
if (selectedTargetLanguage == null) {
setState(() {
@ -159,6 +177,13 @@ class UserSettingsState extends State<UserSettingsPage> {
return;
}
if (isSSOSignup && !isTncChecked) {
setState(() {
tncError = L10n.of(context).pleaseAgreeToTOS;
});
return;
}
if (!formKey.currentState!.validate()) return;
setState(() => loading = true);

@ -3,6 +3,7 @@ import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pangea/pages/sign_up/full_width_button.dart';
import 'package:fluffychat/pangea/pages/sign_up/pangea_login_scaffold.dart';
import 'package:fluffychat/pangea/pages/sign_up/user_settings.dart';
import 'package:fluffychat/pangea/widgets/signup/tos_checkbox.dart';
import 'package:fluffychat/pangea/widgets/user_settings/p_language_dropdown.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
@ -93,7 +94,7 @@ class UserSettingsView extends StatelessWidget {
error: controller.selectedLanguageError,
),
),
if (controller.canSetDisplayName)
if (controller.isSSOSignup)
FullWidthTextField(
hintText: L10n.of(context).username,
validator: (username) {
@ -104,6 +105,12 @@ class UserSettingsView extends StatelessWidget {
},
controller: controller.displayNameController,
),
if (controller.isSSOSignup)
TosCheckbox(
controller.isTncChecked,
controller.setTncChecked,
error: controller.tncError,
),
FullWidthButton(
title: L10n.of(context).letsStart,
onPressed: controller.selectedTargetLanguage != null
@ -111,7 +118,8 @@ class UserSettingsView extends StatelessWidget {
: null,
error: controller.profileCreationError,
loading: controller.loading,
enabled: controller.selectedTargetLanguage != null,
enabled: controller.selectedTargetLanguage != null &&
(!controller.isSSOSignup || controller.isTncChecked),
),
],
),

@ -16,6 +16,8 @@ class PressableButton extends StatefulWidget {
final Stream? triggerAnimation;
final ClickPlayer? clickPlayer;
final bool? isShadow;
const PressableButton({
required this.borderRadius,
required this.child,
@ -25,6 +27,7 @@ class PressableButton extends StatefulWidget {
this.depressed = false,
this.triggerAnimation,
this.clickPlayer,
this.isShadow,
super.key,
});
@ -53,6 +56,7 @@ class PressableButtonState extends State<PressableButton>
);
_tweenAnimation =
Tween<double>(begin: 0, end: widget.buttonHeight).animate(_controller);
if (!_depressed) {
_triggerAnimationSubscription = widget.triggerAnimation?.listen((_) {
_animationCompleter = Completer<void>();
@ -77,6 +81,9 @@ class PressableButtonState extends State<PressableButton>
}
}
bool get _isShadow =>
widget.isShadow ?? Theme.of(context).brightness == Brightness.light;
void _onTapDown(TapDownDetails? details) {
if (_depressed) return;
_animationCompleter = Completer<void>();
@ -138,7 +145,7 @@ class PressableButtonState extends State<PressableButton>
return Container(
decoration: BoxDecoration(
color: Color.alphaBlend(
Theme.of(context).brightness == Brightness.light
_isShadow
? Colors.black.withOpacity(0.25)
: Colors.white.withOpacity(0.25),
widget.color,

@ -2,16 +2,19 @@
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/pangea/pages/sign_up/signup.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
class TosCheckbox extends StatefulWidget {
final SignupPageController controller;
final bool value;
final Function(bool?) onChange;
final String? error;
const TosCheckbox(
this.controller, {
this.value,
this.onChange, {
this.error,
super.key,
});
@ -57,12 +60,12 @@ class TosCheckboxState extends State<TosCheckbox>
),
AnimatedSize(
duration: FluffyThemes.animationDuration,
child: widget.controller.signupError == null
child: widget.error == null
? const SizedBox.shrink()
: Padding(
padding: const EdgeInsets.only(top: 4, left: 30),
child: Text(
widget.controller.signupError!,
widget.error!,
style: TextStyle(
color: Theme.of(context).colorScheme.error,
fontSize: 12,
@ -74,9 +77,9 @@ class TosCheckboxState extends State<TosCheckbox>
),
),
Checkbox(
value: widget.controller.isTnCChecked,
value: widget.value,
activeColor: Theme.of(context).colorScheme.primary,
onChanged: widget.controller.onTncChange,
onChanged: widget.onChange,
),
],
);

Loading…
Cancel
Save