refactor: Improve sso login UX on web

pull/1577/head
krille-chan 9 months ago
parent e4b8d45715
commit 7cbc518951
No known key found for this signature in database

@ -2822,5 +2822,13 @@
"addLink": "Add link",
"unableToJoinChat": "Unable to join chat. Maybe the other party has already closed the conversation.",
"previous": "Previous",
"otherPartyNotLoggedIn": "The other party is currently not logged in and therefore cannot receive messages!"
"otherPartyNotLoggedIn": "The other party is currently not logged in and therefore cannot receive messages!",
"appWantsToUseForLogin": "Use '{server}' to log in",
"@appWantsToUseForLogin": {
"type": "text",
"placeholders": {
"server": {}
}
},
"appWantsToUseForLoginDescription": "You hereby allow the app and website to share information about you."
}

@ -33,7 +33,6 @@ class HomeserverPicker extends StatefulWidget {
class HomeserverPickerController extends State<HomeserverPicker> {
bool isLoading = false;
bool isLoggingIn = false;
final TextEditingController homeserverController = TextEditingController(
text: AppConfig.defaultHomeserver,
@ -61,58 +60,29 @@ class HomeserverPickerController extends State<HomeserverPicker> {
isTorBrowser = isTor;
}
String? _lastCheckedUrl;
Timer? _checkHomeserverCooldown;
tryCheckHomeserverActionWithCooldown([_]) {
_checkHomeserverCooldown?.cancel();
_checkHomeserverCooldown = Timer(
const Duration(milliseconds: 500),
checkHomeserverAction,
);
}
void tryCheckHomeserverActionWithoutCooldown([_]) {
_checkHomeserverCooldown?.cancel();
_lastCheckedUrl = null;
checkHomeserverAction();
}
void onSubmitted([_]) {
if (isLoading || _checkHomeserverCooldown?.isActive == true) {
return tryCheckHomeserverActionWithoutCooldown();
}
if (supportsSso) return ssoLoginAction();
if (supportsPasswordLogin) return login();
return tryCheckHomeserverActionWithoutCooldown();
}
/// Starts an analysis of the given homeserver. It uses the current domain and
/// makes sure that it is prefixed with https. Then it searches for the
/// well-known information and forwards to the login page depending on the
/// login type.
Future<void> checkHomeserverAction([_]) async {
Future<void> checkHomeserverAction({bool legacyPasswordLogin = false}) async {
final homeserverInput =
homeserverController.text.trim().toLowerCase().replaceAll(' ', '-');
if (homeserverInput.isEmpty || !homeserverInput.contains('.')) {
if (homeserverInput.isEmpty) {
setState(() {
error = loginFlows = null;
isLoading = false;
Matrix.of(context).getLoginClient().homeserver = null;
_lastCheckedUrl = null;
});
return;
}
if (_lastCheckedUrl == homeserverInput) return;
_lastCheckedUrl = homeserverInput;
setState(() {
error = loginFlows = null;
isLoading = true;
});
final l10n = L10n.of(context);
try {
var homeserver = Uri.parse(homeserverInput);
if (homeserver.scheme.isEmpty) {
@ -121,6 +91,21 @@ class HomeserverPickerController extends State<HomeserverPicker> {
final client = Matrix.of(context).getLoginClient();
final (_, _, loginFlows) = await client.checkHomeserver(homeserver);
this.loginFlows = loginFlows;
if (supportsSso && !legacyPasswordLogin) {
if (!PlatformInfos.isMobile) {
final consent = await showOkCancelAlertDialog(
context: context,
title: l10n.appWantsToUseForLogin(homeserverInput),
message: l10n.appWantsToUseForLoginDescription,
okLabel: l10n.continueText,
);
if (consent != OkCancelResult.ok) return;
}
return ssoLoginAction();
}
context.push(
'${GoRouter.of(context).routeInformationProvider.value.uri.path}/login',
);
} catch (e) {
setState(
() => error = (e).toLocalizedString(
@ -176,7 +161,7 @@ class HomeserverPickerController extends State<HomeserverPicker> {
setState(() {
error = null;
isLoading = isLoggingIn = true;
isLoading = true;
});
try {
await Matrix.of(context).getLoginClient().login(
@ -191,27 +176,16 @@ class HomeserverPickerController extends State<HomeserverPicker> {
} finally {
if (mounted) {
setState(() {
isLoading = isLoggingIn = false;
isLoading = false;
});
}
}
}
void login() async {
if (!supportsPasswordLogin) {
homeserverController.text = AppConfig.defaultHomeserver;
await checkHomeserverAction();
}
context.push(
'${GoRouter.of(context).routeInformationProvider.value.uri.path}/login',
);
}
@override
void initState() {
_checkTorBrowser();
super.initState();
WidgetsBinding.instance.addPostFrameCallback(checkHomeserverAction);
}
@override
@ -223,7 +197,7 @@ class HomeserverPickerController extends State<HomeserverPicker> {
if (file == null) return;
setState(() {
error = null;
isLoading = isLoggingIn = true;
isLoading = true;
});
try {
final client = Matrix.of(context).getLoginClient();
@ -236,7 +210,7 @@ class HomeserverPickerController extends State<HomeserverPicker> {
} finally {
if (mounted) {
setState(() {
isLoading = isLoggingIn = false;
isLoading = false;
});
}
}
@ -245,7 +219,7 @@ class HomeserverPickerController extends State<HomeserverPicker> {
void onMoreAction(MoreLoginActions action) {
switch (action) {
case MoreLoginActions.passwordLogin:
login();
checkHomeserverAction(legacyPasswordLogin: true);
case MoreLoginActions.privacy:
launchUrlString(AppConfig.privacyUrl);
case MoreLoginActions.about:

@ -142,30 +142,13 @@ class HomeserverPickerView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextField(
onChanged:
controller.tryCheckHomeserverActionWithCooldown,
onSubmitted: controller.onSubmitted,
onTap:
controller.tryCheckHomeserverActionWithCooldown,
onSubmitted: (_) =>
controller.checkHomeserverAction(),
controller: controller.homeserverController,
autocorrect: false,
keyboardType: TextInputType.url,
decoration: InputDecoration(
prefixIcon: controller.isLoading
? Container(
width: 16,
height: 16,
alignment: Alignment.center,
child: const SizedBox(
width: 16,
height: 16,
child:
CircularProgressIndicator.adaptive(
strokeWidth: 2,
),
),
)
: const Icon(Icons.search_outlined),
prefixIcon: const Icon(Icons.search_outlined),
filled: false,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(
@ -219,25 +202,21 @@ class HomeserverPickerView extends StatelessWidget {
backgroundColor: theme.colorScheme.primary,
foregroundColor: theme.colorScheme.onPrimary,
),
onPressed:
controller.isLoggingIn || controller.isLoading
? null
: controller.supportsSso
? controller.ssoLoginAction
: controller.supportsPasswordLogin
? controller.login
: null,
child: Text(L10n.of(context).continueText),
onPressed: controller.isLoading
? null
: controller.checkHomeserverAction,
child: controller.isLoading
? const LinearProgressIndicator()
: Text(L10n.of(context).continueText),
),
TextButton(
style: TextButton.styleFrom(
foregroundColor: theme.colorScheme.secondary,
textStyle: theme.textTheme.labelMedium,
),
onPressed:
controller.isLoggingIn || controller.isLoading
? null
: controller.restoreBackup,
onPressed: controller.isLoading
? null
: controller.restoreBackup,
child: Text(L10n.of(context).hydrate),
),
],

Loading…
Cancel
Save