Login signup fixes (#1277)
* made button same height when loading, added timeout to language settings / avatar page * fix: make button click always work, shrink inputs and add more space between logo and page content * fix: don't open keyboard automatically in signup/login pages * fix: make language dropdown hint text accurate * feat: if a user logs in with SSO, allow them to set their username in the account setup page
This commit is contained in:
parent
940b65d007
commit
c8bf68e4cd
18 changed files with 220 additions and 199 deletions
|
|
@ -4647,5 +4647,6 @@
|
|||
"letsStart": "Let's start",
|
||||
"pleaseAgreeToTOS": "Please agree to the Terms and Conditions",
|
||||
"pleaseEnterEmail": "Please enter a valid email address.",
|
||||
"pleaseSelectALanguage": "Please select a language"
|
||||
"pleaseSelectALanguage": "Please select a language",
|
||||
"myBaseLanguage": "My base language"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||
import 'package:fluffychat/pangea/constants/local.key.dart';
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/pages/sign_up/pangea_login_view.dart';
|
||||
import 'package:fluffychat/pangea/utils/firebase_analytics.dart';
|
||||
|
|
@ -146,6 +147,8 @@ class LoginController extends State<Login> {
|
|||
password: passwordController.text,
|
||||
initialDeviceDisplayName: PlatformInfos.clientName,
|
||||
);
|
||||
MatrixState.pangeaController.pStoreService
|
||||
.save(PLocalKey.loginType, 'password');
|
||||
// #Pangea
|
||||
GoogleAnalytics.login("pangea", loginRes.userId);
|
||||
// Pangea#
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ class LoginView extends StatelessWidget {
|
|||
child: TextField(
|
||||
readOnly: controller.loading,
|
||||
autocorrect: false,
|
||||
autofocus: true,
|
||||
// #Pangea
|
||||
// autofocus: true,
|
||||
// onChanged: controller.checkWellKnownWithCoolDown,
|
||||
// Pangea#
|
||||
controller: controller.usernameController,
|
||||
|
|
|
|||
|
|
@ -9,4 +9,5 @@ class PLocalKey {
|
|||
static const String justInputtedCode = 'justInputtedCode';
|
||||
static const String availableSubscriptionInfo = 'availableSubscriptionInfo';
|
||||
static const String showedUpdateDialog = 'showedUpdateDialog';
|
||||
static const String loginType = 'loginType';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ class LanguageController {
|
|||
_userL2Code != LanguageKeys.unknownLanguage;
|
||||
|
||||
LanguageModel? get systemLanguage {
|
||||
final String systemLang = Platform.localeName.split('-').first;
|
||||
if (Platform.localeName.length < 2) return null;
|
||||
final String systemLang = Platform.localeName.substring(0, 2);
|
||||
return PangeaLanguage.byLangCode(systemLang);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,21 +89,15 @@ class PangeaSsoButtonState extends State<PangeaSsoButton> {
|
|||
depressed: _loading,
|
||||
error: _error,
|
||||
loading: _loading,
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
widget.provider.asset,
|
||||
height: 20,
|
||||
width: 20,
|
||||
colorFilter: ColorFilter.mode(
|
||||
Theme.of(context).colorScheme.onPrimary,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(widget.title),
|
||||
],
|
||||
title: widget.title,
|
||||
icon: SvgPicture.asset(
|
||||
widget.provider.asset,
|
||||
height: 20,
|
||||
width: 20,
|
||||
colorFilter: ColorFilter.mode(
|
||||
Theme.of(context).colorScheme.onPrimary,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
onPressed: _runSSOLogin,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ import 'package:fluffychat/pangea/widgets/pressable_button.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class FullWidthButton extends StatefulWidget {
|
||||
final Widget title;
|
||||
final String title;
|
||||
final Widget? icon;
|
||||
|
||||
final void Function()? onPressed;
|
||||
final bool depressed;
|
||||
final String? error;
|
||||
|
|
@ -13,6 +15,7 @@ class FullWidthButton extends StatefulWidget {
|
|||
const FullWidthButton({
|
||||
required this.title,
|
||||
required this.onPressed,
|
||||
this.icon,
|
||||
this.depressed = false,
|
||||
this.error,
|
||||
this.loading = false,
|
||||
|
|
@ -31,7 +34,7 @@ class FullWidthButtonState extends State<FullWidthButton> {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(4, 4, 4, widget.error == null ? 4 : 0),
|
||||
padding: EdgeInsets.fromLTRB(6, 6, 6, widget.error == null ? 6 : 0),
|
||||
child: AnimatedOpacity(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
opacity: widget.enabled ? 1 : 0.5,
|
||||
|
|
@ -40,40 +43,44 @@ class FullWidthButtonState extends State<FullWidthButton> {
|
|||
onPressed: widget.onPressed,
|
||||
borderRadius: BorderRadius.circular(36),
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
return ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: widget.enabled
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Theme.of(context).disabledColor,
|
||||
foregroundColor: Theme.of(context).colorScheme.onPrimary,
|
||||
disabledForegroundColor:
|
||||
Theme.of(context).colorScheme.onPrimary,
|
||||
textStyle: const TextStyle(fontSize: 18),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(36),
|
||||
),
|
||||
),
|
||||
onPressed: widget.enabled
|
||||
? () => ButtonPressedNotification().dispatch(context)
|
||||
: null,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
widget.loading
|
||||
? const Expanded(
|
||||
child: SizedBox(
|
||||
height: 18,
|
||||
child:
|
||||
Center(child: LinearProgressIndicator()),
|
||||
child: Container(
|
||||
// internal padding
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
color: widget.enabled
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Theme.of(context).disabledColor,
|
||||
borderRadius: BorderRadius.circular(36),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
widget.loading
|
||||
? const Expanded(
|
||||
child: SizedBox(
|
||||
height: 18,
|
||||
child: Center(child: LinearProgressIndicator()),
|
||||
),
|
||||
)
|
||||
: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (widget.icon != null) widget.icon!,
|
||||
if (widget.icon != null)
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
widget.title,
|
||||
style: TextStyle(
|
||||
color:
|
||||
Theme.of(context).colorScheme.onPrimary,
|
||||
fontSize: 16,
|
||||
),
|
||||
)
|
||||
: widget.title,
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -104,7 +111,6 @@ class FullWidthButtonState extends State<FullWidthButton> {
|
|||
class FullWidthTextField extends StatelessWidget {
|
||||
final String hintText;
|
||||
final bool autocorrect;
|
||||
final bool autofocus;
|
||||
final bool obscureText;
|
||||
final TextInputAction? textInputAction;
|
||||
final TextInputType? keyboardType;
|
||||
|
|
@ -115,7 +121,6 @@ class FullWidthTextField extends StatelessWidget {
|
|||
const FullWidthTextField({
|
||||
required this.hintText,
|
||||
this.autocorrect = false,
|
||||
this.autofocus = false,
|
||||
this.obscureText = false,
|
||||
this.textInputAction,
|
||||
this.keyboardType,
|
||||
|
|
@ -128,11 +133,10 @@ class FullWidthTextField extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
padding: const EdgeInsets.all(6.0),
|
||||
child: TextFormField(
|
||||
obscureText: obscureText,
|
||||
autocorrect: autocorrect,
|
||||
autofocus: autofocus,
|
||||
textInputAction: textInputAction,
|
||||
keyboardType: keyboardType,
|
||||
decoration: InputDecoration(
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ class LoginOrSignupView extends StatelessWidget {
|
|||
return PangeaLoginScaffold(
|
||||
children: [
|
||||
FullWidthButton(
|
||||
title: Text(L10n.of(context).createAnAccount),
|
||||
title: L10n.of(context).createAnAccount,
|
||||
onPressed: () => context.go('/home/signup'),
|
||||
),
|
||||
FullWidthButton(
|
||||
title: Text(L10n.of(context).signIn),
|
||||
title: L10n.of(context).signIn,
|
||||
onPressed: () => context.go('/home/login'),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -32,14 +32,14 @@ class PangeaLoginScaffold extends StatelessWidget {
|
|||
child: Center(
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 450,
|
||||
maxWidth: 300,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 200,
|
||||
height: 200,
|
||||
width: 175,
|
||||
height: 175,
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.transparent,
|
||||
|
|
@ -56,13 +56,13 @@ class PangeaLoginScaffold extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const SizedBox(height: 24),
|
||||
if (showAppName)
|
||||
Text(
|
||||
AppConfig.applicationName,
|
||||
style: Theme.of(context).textTheme.displaySmall,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
if (showAppName) const SizedBox(height: 12),
|
||||
...children,
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ class PangeaLoginView extends StatelessWidget {
|
|||
children: [
|
||||
FullWidthTextField(
|
||||
hintText: L10n.of(context).username,
|
||||
autofocus: true,
|
||||
textInputAction: TextInputAction.next,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
|
|
@ -44,16 +43,10 @@ class PangeaLoginView extends StatelessWidget {
|
|||
errorText: controller.passwordError,
|
||||
),
|
||||
FullWidthButton(
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
PangeaLogoSvg(
|
||||
width: 20,
|
||||
forceColor: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(L10n.of(context).signIn),
|
||||
],
|
||||
title: L10n.of(context).signIn,
|
||||
icon: PangeaLogoSvg(
|
||||
width: 20,
|
||||
forceColor: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
onPressed: controller.enabledSignIn ? controller.login : null,
|
||||
loading: controller.loading,
|
||||
|
|
|
|||
|
|
@ -19,18 +19,12 @@ class SignupPageView extends StatelessWidget {
|
|||
return PangeaLoginScaffold(
|
||||
children: [
|
||||
FullWidthButton(
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
PangeaLogoSvg(
|
||||
width: 20,
|
||||
forceColor: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(L10n.of(context).signUpWithEmail),
|
||||
],
|
||||
),
|
||||
title: L10n.of(context).signUpWithEmail,
|
||||
onPressed: () => context.go('/home/signup/email'),
|
||||
icon: PangeaLogoSvg(
|
||||
width: 20,
|
||||
forceColor: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
PangeaSsoButton(
|
||||
provider: SSOProvider.google,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ class SignupWithEmailView extends StatelessWidget {
|
|||
children: [
|
||||
FullWidthTextField(
|
||||
hintText: L10n.of(context).yourUsername,
|
||||
autofocus: true,
|
||||
textInputAction: TextInputAction.next,
|
||||
validator: (text) {
|
||||
if (text == null || text.isEmpty) {
|
||||
|
|
@ -47,16 +46,10 @@ class SignupWithEmailView extends StatelessWidget {
|
|||
),
|
||||
TosCheckbox(controller),
|
||||
FullWidthButton(
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
PangeaLogoSvg(
|
||||
width: 20,
|
||||
forceColor: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(L10n.of(context).signUp),
|
||||
],
|
||||
title: L10n.of(context).signUp,
|
||||
icon: PangeaLogoSvg(
|
||||
width: 20,
|
||||
forceColor: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
onPressed: controller.enableSignUp ? controller.signup : null,
|
||||
error: controller.error,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:fluffychat/pangea/constants/local.key.dart';
|
||||
import 'package:fluffychat/pangea/controllers/language_list_controller.dart';
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/models/language_model.dart';
|
||||
|
|
@ -51,11 +52,26 @@ class UserSettingsState extends State<UserSettingsPage> {
|
|||
: PangeaLanguage.byLangCode(systemLangCode);
|
||||
}
|
||||
|
||||
bool canSetDisplayName = false;
|
||||
TextEditingController displayNameController = TextEditingController();
|
||||
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
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();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void setSelectedTargetLanguage(LanguageModel? language) {
|
||||
|
|
@ -118,6 +134,15 @@ class UserSettingsState extends State<UserSettingsPage> {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> _setDisplayName() async {
|
||||
final displayName = displayNameController.text.trim();
|
||||
if (displayName.isEmpty) return;
|
||||
|
||||
final client = Matrix.of(context).client;
|
||||
if (client.userID == null) return;
|
||||
await client.setDisplayName(client.userID!, displayName);
|
||||
}
|
||||
|
||||
Future<void> createUserInPangea() async {
|
||||
setState(() => profileCreationError = null);
|
||||
|
||||
|
|
@ -128,10 +153,12 @@ class UserSettingsState extends State<UserSettingsPage> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!formKey.currentState!.validate()) return;
|
||||
setState(() => loading = true);
|
||||
|
||||
try {
|
||||
final updateFuture = [
|
||||
_setDisplayName(),
|
||||
_setAvatar(),
|
||||
_pangeaController.subscriptionController.reinitialize(),
|
||||
_pangeaController.userController.updateProfile(
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ class UserSettingsView extends StatelessWidget {
|
|||
super.key,
|
||||
});
|
||||
|
||||
final double avatarSize = 55.0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final List<Widget> avatarOptions = controller.avatarPaths
|
||||
|
|
@ -25,6 +27,7 @@ class UserSettingsView extends StatelessWidget {
|
|||
onTap: () => controller.setSelectedAvatarPath(index),
|
||||
path: path,
|
||||
selected: controller.selectedAvatarIndex == index,
|
||||
size: avatarSize,
|
||||
),
|
||||
);
|
||||
})
|
||||
|
|
@ -37,8 +40,8 @@ class UserSettingsView extends StatelessWidget {
|
|||
child: InkWell(
|
||||
onTap: controller.uploadAvatar,
|
||||
child: Container(
|
||||
width: 50,
|
||||
height: 50,
|
||||
width: avatarSize,
|
||||
height: avatarSize,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.white,
|
||||
|
|
@ -51,7 +54,7 @@ class UserSettingsView extends StatelessWidget {
|
|||
),
|
||||
child: Icon(
|
||||
Icons.upload,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
size: 30,
|
||||
),
|
||||
),
|
||||
|
|
@ -59,48 +62,59 @@ class UserSettingsView extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
|
||||
return PangeaLoginScaffold(
|
||||
showAppName: false,
|
||||
mainAssetPath: controller.selectedAvatarPath ?? "",
|
||||
mainAssetBytes: controller.avatar,
|
||||
children: [
|
||||
Opacity(
|
||||
opacity: 0.9,
|
||||
child: Text(
|
||||
L10n.of(context).chooseYourAvatar,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w100,
|
||||
fontStyle: FontStyle.italic,
|
||||
return Form(
|
||||
key: controller.formKey,
|
||||
child: PangeaLoginScaffold(
|
||||
showAppName: false,
|
||||
mainAssetPath: controller.selectedAvatarPath ?? "",
|
||||
mainAssetBytes: controller.avatar,
|
||||
children: [
|
||||
Opacity(
|
||||
opacity: 0.9,
|
||||
child: Text(
|
||||
L10n.of(context).chooseYourAvatar,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w100,
|
||||
fontStyle: FontStyle.italic,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: avatarOptions,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: PLanguageDropdown(
|
||||
languages: controller.targetOptions,
|
||||
onChange: controller.setSelectedTargetLanguage,
|
||||
initialLanguage: controller.selectedTargetLanguage,
|
||||
isL2List: true,
|
||||
error: controller.selectedLanguageError,
|
||||
Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
children: avatarOptions,
|
||||
),
|
||||
),
|
||||
FullWidthButton(
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [Text(L10n.of(context).letsStart)],
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: PLanguageDropdown(
|
||||
languages: controller.targetOptions,
|
||||
onChange: controller.setSelectedTargetLanguage,
|
||||
initialLanguage: controller.selectedTargetLanguage,
|
||||
isL2List: true,
|
||||
error: controller.selectedLanguageError,
|
||||
),
|
||||
),
|
||||
onPressed: controller.selectedTargetLanguage != null
|
||||
? controller.createUserInPangea
|
||||
: null,
|
||||
error: controller.profileCreationError,
|
||||
loading: controller.loading,
|
||||
enabled: controller.selectedTargetLanguage != null,
|
||||
),
|
||||
],
|
||||
if (controller.canSetDisplayName)
|
||||
FullWidthTextField(
|
||||
hintText: L10n.of(context).username,
|
||||
validator: (username) {
|
||||
if (username == null || username.isEmpty) {
|
||||
return L10n.of(context).pleaseChooseAUsername;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
controller: controller.displayNameController,
|
||||
),
|
||||
FullWidthButton(
|
||||
title: L10n.of(context).letsStart,
|
||||
onPressed: controller.selectedTargetLanguage != null
|
||||
? controller.createUserInPangea
|
||||
: null,
|
||||
error: controller.profileCreationError,
|
||||
loading: controller.loading,
|
||||
enabled: controller.selectedTargetLanguage != null,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -115,7 +129,7 @@ class AvatarOption extends StatelessWidget {
|
|||
super.key,
|
||||
required this.onTap,
|
||||
required this.path,
|
||||
this.size = 50.0,
|
||||
this.size = 40.0,
|
||||
this.selected = false,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pages/homeserver_picker/homeserver_picker.dart';
|
||||
import 'package:fluffychat/pangea/constants/local.key.dart';
|
||||
import 'package:fluffychat/pangea/utils/firebase_analytics.dart';
|
||||
import 'package:fluffychat/utils/platform_infos.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
|
@ -42,7 +43,6 @@ Future<void> pangeaSSOLoginAction(
|
|||
result = await FlutterWebAuth2.authenticate(
|
||||
url: url.toString(),
|
||||
callbackUrlScheme: urlScheme,
|
||||
options: const FlutterWebAuth2Options(),
|
||||
);
|
||||
} catch (err) {
|
||||
if (err is PlatformException && err.code == 'CANCELED') {
|
||||
|
|
@ -60,5 +60,6 @@ Future<void> pangeaSSOLoginAction(
|
|||
token: token,
|
||||
initialDeviceDisplayName: PlatformInfos.clientName,
|
||||
);
|
||||
MatrixState.pangeaController.pStoreService.save(PLocalKey.loginType, 'sso');
|
||||
GoogleAnalytics.login(provider.name!, loginRes.userId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,12 +126,8 @@ class PressableButtonState extends State<PressableButton>
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return NotificationListener<ButtonPressedNotification>(
|
||||
onNotification: (notification) {
|
||||
_onTapDown(null);
|
||||
_onTapUp(null);
|
||||
return true; // Stop the notification from bubbling further
|
||||
},
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTapDown: _onTapDown,
|
||||
onTapUp: _onTapUp,
|
||||
|
|
@ -167,5 +163,3 @@ class PressableButtonState extends State<PressableButton>
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ButtonPressedNotification extends Notification {}
|
||||
|
|
|
|||
|
|
@ -23,65 +23,62 @@ class TosCheckboxState extends State<TosCheckbox>
|
|||
with SingleTickerProviderStateMixin {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () => UrlLauncher(context, AppConfig.termsOfServiceUrl)
|
||||
.launchUrl(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 15),
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
text: L10n.of(context).iAgreeToThe,
|
||||
children: [
|
||||
TextSpan(
|
||||
text: L10n.of(context).termsAndConditions,
|
||||
style: const TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () => UrlLauncher(context, AppConfig.termsOfServiceUrl)
|
||||
.launchUrl(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 15),
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
text: L10n.of(context).iAgreeToThe,
|
||||
children: [
|
||||
TextSpan(
|
||||
text: L10n.of(context).termsAndConditions,
|
||||
style: const TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
],
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
],
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
AnimatedSize(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
child: widget.controller.signupError == null
|
||||
? const SizedBox.shrink()
|
||||
: Padding(
|
||||
padding: const EdgeInsets.only(top: 4, left: 30),
|
||||
child: Text(
|
||||
widget.controller.signupError!,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
AnimatedSize(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
child: widget.controller.signupError == null
|
||||
? const SizedBox.shrink()
|
||||
: Padding(
|
||||
padding: const EdgeInsets.only(top: 4, left: 30),
|
||||
child: Text(
|
||||
widget.controller.signupError!,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Checkbox(
|
||||
value: widget.controller.isTnCChecked,
|
||||
activeColor: Theme.of(context).colorScheme.primary,
|
||||
onChanged: widget.controller.onTncChange,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Checkbox(
|
||||
value: widget.controller.isTnCChecked,
|
||||
activeColor: Theme.of(context).colorScheme.primary,
|
||||
onChanged: widget.controller.onTncChange,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,11 @@ class _PLanguageDropdownState extends State<PLanguageDropdown> {
|
|||
children: [
|
||||
const Icon(Icons.language_outlined),
|
||||
const SizedBox(width: 10),
|
||||
Text(L10n.of(context).iWantToLearn),
|
||||
Text(
|
||||
widget.isL2List
|
||||
? L10n.of(context).iWantToLearn
|
||||
: L10n.of(context).myBaseLanguage,
|
||||
),
|
||||
],
|
||||
),
|
||||
isExpanded: true,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue