refactor: Improve sso login UX on web
This commit is contained in:
parent
e4b8d45715
commit
7cbc518951
3 changed files with 45 additions and 84 deletions
|
|
@ -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…
Add table
Reference in a new issue