mirror of
https://github.com/immich-app/immich.git
synced 2025-01-01 16:41:59 +00:00
feat(mobile): autofill login form (#1128)
This commit is contained in:
parent
e824b55c20
commit
8ee7504c45
1 changed files with 97 additions and 89 deletions
|
@ -94,105 +94,107 @@ class LoginForm extends HookConsumerWidget {
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: const BoxConstraints(maxWidth: 300),
|
constraints: const BoxConstraints(maxWidth: 300),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Wrap(
|
child: AutofillGroup (
|
||||||
spacing: 16,
|
child: Wrap(
|
||||||
runSpacing: 16,
|
spacing: 16,
|
||||||
alignment: WrapAlignment.center,
|
runSpacing: 16,
|
||||||
children: [
|
alignment: WrapAlignment.center,
|
||||||
GestureDetector(
|
children: [
|
||||||
onDoubleTap: () => populateTestLoginInfo(),
|
GestureDetector(
|
||||||
child: const Image(
|
onDoubleTap: () => populateTestLoginInfo(),
|
||||||
image: AssetImage('assets/immich-logo-no-outline.png'),
|
child: const Image(
|
||||||
width: 100,
|
image: AssetImage('assets/immich-logo-no-outline.png'),
|
||||||
filterQuality: FilterQuality.high,
|
width: 100,
|
||||||
|
filterQuality: FilterQuality.high,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Text(
|
||||||
Text(
|
'IMMICH',
|
||||||
'IMMICH',
|
|
||||||
style: TextStyle(
|
|
||||||
fontFamily: 'SnowburstOne',
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 48,
|
|
||||||
color: Theme.of(context).primaryColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
EmailInput(controller: usernameController),
|
|
||||||
PasswordInput(controller: passwordController),
|
|
||||||
ServerEndpointInput(
|
|
||||||
controller: serverEndpointController,
|
|
||||||
focusNode: serverEndpointFocusNode,
|
|
||||||
),
|
|
||||||
CheckboxListTile(
|
|
||||||
activeColor: Theme.of(context).primaryColor,
|
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 8),
|
|
||||||
dense: true,
|
|
||||||
side: const BorderSide(color: Colors.grey, width: 1.5),
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(5),
|
|
||||||
),
|
|
||||||
enableFeedback: true,
|
|
||||||
title: const Text(
|
|
||||||
"login_form_save_login",
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontFamily: 'SnowburstOne',
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Colors.grey,
|
fontSize: 48,
|
||||||
),
|
color: Theme.of(context).primaryColor,
|
||||||
).tr(),
|
|
||||||
value: isSaveLoginInfo.value,
|
|
||||||
onChanged: (switchValue) {
|
|
||||||
if (switchValue != null) {
|
|
||||||
isSaveLoginInfo.value = switchValue;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
if (isLoading.value)
|
|
||||||
const SizedBox(
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (!isLoading.value)
|
EmailInput(controller: usernameController),
|
||||||
Column(
|
PasswordInput(controller: passwordController),
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
ServerEndpointInput(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
controller: serverEndpointController,
|
||||||
children: [
|
focusNode: serverEndpointFocusNode,
|
||||||
LoginButton(
|
),
|
||||||
emailController: usernameController,
|
CheckboxListTile(
|
||||||
passwordController: passwordController,
|
activeColor: Theme.of(context).primaryColor,
|
||||||
serverEndpointController: serverEndpointController,
|
contentPadding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
isSavedLoginInfo: isSaveLoginInfo.value,
|
dense: true,
|
||||||
|
side: const BorderSide(color: Colors.grey, width: 1.5),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
),
|
||||||
|
enableFeedback: true,
|
||||||
|
title: const Text(
|
||||||
|
"login_form_save_login",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.grey,
|
||||||
),
|
),
|
||||||
if (isOauthEnable.value) ...[
|
).tr(),
|
||||||
Padding(
|
value: isSaveLoginInfo.value,
|
||||||
padding: const EdgeInsets.symmetric(
|
onChanged: (switchValue) {
|
||||||
horizontal: 16.0,
|
if (switchValue != null) {
|
||||||
),
|
isSaveLoginInfo.value = switchValue;
|
||||||
child: Divider(
|
}
|
||||||
color: Brightness.dark == Theme.of(context).brightness
|
},
|
||||||
? Colors.white
|
),
|
||||||
: Colors.black,
|
if (isLoading.value)
|
||||||
),
|
const SizedBox(
|
||||||
),
|
width: 24,
|
||||||
OAuthLoginButton(
|
height: 24,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (!isLoading.value)
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
LoginButton(
|
||||||
|
emailController: usernameController,
|
||||||
|
passwordController: passwordController,
|
||||||
serverEndpointController: serverEndpointController,
|
serverEndpointController: serverEndpointController,
|
||||||
isSavedLoginInfo: isSaveLoginInfo.value,
|
isSavedLoginInfo: isSaveLoginInfo.value,
|
||||||
buttonLabel: oAuthButtonLabel.value,
|
|
||||||
isLoading: isLoading,
|
|
||||||
onLoginSuccess: () {
|
|
||||||
isLoading.value = false;
|
|
||||||
ref.watch(backupProvider.notifier).resumeBackup();
|
|
||||||
AutoRouter.of(context).replace(
|
|
||||||
const TabControllerRoute(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
|
if (isOauthEnable.value) ...[
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 16.0,
|
||||||
|
),
|
||||||
|
child: Divider(
|
||||||
|
color: Brightness.dark == Theme.of(context).brightness
|
||||||
|
? Colors.white
|
||||||
|
: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
OAuthLoginButton(
|
||||||
|
serverEndpointController: serverEndpointController,
|
||||||
|
isSavedLoginInfo: isSaveLoginInfo.value,
|
||||||
|
buttonLabel: oAuthButtonLabel.value,
|
||||||
|
isLoading: isLoading,
|
||||||
|
onLoginSuccess: () {
|
||||||
|
isLoading.value = false;
|
||||||
|
ref.watch(backupProvider.notifier).resumeBackup();
|
||||||
|
AutoRouter.of(context).replace(
|
||||||
|
const TabControllerRoute(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
],
|
)
|
||||||
)
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -229,6 +231,8 @@ class ServerEndpointInput extends StatelessWidget {
|
||||||
validator: _validateInput,
|
validator: _validateInput,
|
||||||
autovalidateMode: AutovalidateMode.always,
|
autovalidateMode: AutovalidateMode.always,
|
||||||
focusNode: focusNode,
|
focusNode: focusNode,
|
||||||
|
autofillHints: const [AutofillHints.url],
|
||||||
|
keyboardType: TextInputType.url,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,6 +263,8 @@ class EmailInput extends StatelessWidget {
|
||||||
),
|
),
|
||||||
validator: _validateInput,
|
validator: _validateInput,
|
||||||
autovalidateMode: AutovalidateMode.always,
|
autovalidateMode: AutovalidateMode.always,
|
||||||
|
autofillHints: const [AutofillHints.email],
|
||||||
|
keyboardType: TextInputType.emailAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,6 +284,8 @@ class PasswordInput extends StatelessWidget {
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
hintText: 'login_form_password_hint'.tr(),
|
hintText: 'login_form_password_hint'.tr(),
|
||||||
),
|
),
|
||||||
|
autofillHints: const [AutofillHints.password],
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue