Create account field validation

This commit is contained in:
LittleSheep 2024-12-08 15:10:35 +08:00
parent add904cc41
commit 45f61533ee
8 changed files with 137 additions and 65 deletions

View File

@ -84,8 +84,12 @@
"fieldEmail": "Email address",
"fieldPassword": "Password",
"fieldDescription": "Description",
"fieldUsernameAlphanumOnly": "Username can only contain alphanumeric characters.",
"fieldUsernameLengthLimit": "Username must be between {} and {} characters.",
"fieldUsernameCannotEditHint": "Username cannot be edited after created",
"fieldUsernameLookupHint": "You can use username, phone number or email to login",
"fieldNicknameLengthLimit": "Nickname must be between {} and {} characters.",
"fieldEmailAddressMustBeValid": "Email address must be an email address.",
"fieldFirstName": "First name",
"fieldLastName": "Last name",
"fieldBirthday": "Birthday",
@ -408,5 +412,6 @@
"accountDeletionSubmitted": "Account deletion request has been sent, you can check your inbox and follow the instructions in the email to complete the deletion operation.",
"channelNewChannel": "New Channel",
"channelNewDirectMessage": "New Direct Message",
"channelDirectMessageDescription": "Direct Message with {}"
"channelDirectMessageDescription": "Direct Message with {}",
"fieldCannotBeEmpty": "This field cannot be empty."
}

View File

@ -69,8 +69,12 @@
"fieldNickname": "显示名",
"fieldEmail": "电子邮箱地址",
"fieldPassword": "密码",
"fieldUsernameAlphanumOnly": "用户名只能包含英文大小写字母和数字。",
"fieldUsernameLengthLimit": "用户名必须在 {} 和 {} 之间。",
"fieldUsernameCannotEditHint": "用户名在创建后无法修改",
"fieldUsernameLookupHint": "支持用户名、电话号码或邮箱地址",
"fieldNicknameLengthLimit": "昵称必须在 {} 和 {} 之间。",
"fieldEmailAddressMustBeValid": "电子邮箱地址必须是一个电子邮箱地址。",
"fieldFirstName": "名",
"fieldLastName": "姓",
"fieldBirthday": "生日",
@ -408,5 +412,6 @@
"accountDeletionSubmitted": "帐户删除申请已发出,你可以检查你的收件箱并根据邮件内的指示完成删除操作。",
"channelNewChannel": "新建频道",
"channelNewDirectMessage": "发起私信",
"channelDirectMessageDescription": "与 {} 的私聊"
"channelDirectMessageDescription": "与 {} 的私聊",
"fieldCannotBeEmpty": "此字段不能为空。"
}

View File

@ -1,4 +1,5 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:email_validator/email_validator.dart';
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:go_router/go_router.dart';
@ -16,20 +17,21 @@ class RegisterScreen extends StatefulWidget {
}
class _RegisterScreenState extends State<RegisterScreen> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final _emailController = TextEditingController();
final _usernameController = TextEditingController();
final _nicknameController = TextEditingController();
final _passwordController = TextEditingController();
void _performAction(BuildContext context) async {
if (!_formKey.currentState!.validate()) return;
final email = _emailController.value.text;
final username = _usernameController.value.text;
final nickname = _nicknameController.value.text;
final password = _passwordController.value.text;
if (email.isEmpty ||
username.isEmpty ||
nickname.isEmpty ||
password.isEmpty) {
if (email.isEmpty || username.isEmpty || nickname.isEmpty || password.isEmpty) {
return;
}
@ -42,8 +44,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
'password': password,
});
if (!mounted) return;
if (!context.mounted) return;
GoRouter.of(context).replaceNamed("authLogin");
} catch (err) {
context.showErrorDialog(err);
@ -75,67 +76,96 @@ class _RegisterScreenState extends State<RegisterScreen> {
fontWeight: FontWeight.w900,
),
).tr().padding(left: 4, bottom: 16),
Column(
children: [
TextField(
autocorrect: false,
enableSuggestions: false,
controller: _usernameController,
autofillHints: const [AutofillHints.username],
decoration: InputDecoration(
isDense: true,
border: const UnderlineInputBorder(),
labelText: 'fieldUsername'.tr(),
Form(
key: _formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Column(
children: [
TextFormField(
validator: (value) {
if (value == null || value.length < 4 || value.length > 32) {
return 'fieldUsernameLengthLimit'.tr(args: [4.toString(), 32.toString()]);
}
if (!RegExp(r'^[a-zA-Z0-9_]+$').hasMatch(value)) {
return 'fieldUsernameAlphanumOnly'.tr();
}
return null;
},
autocorrect: false,
enableSuggestions: false,
controller: _usernameController,
autofillHints: const [AutofillHints.username],
decoration: InputDecoration(
isDense: true,
border: const UnderlineInputBorder(),
labelText: 'fieldUsername'.tr(),
),
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
),
onTapOutside: (_) =>
FocusManager.instance.primaryFocus?.unfocus(),
),
const Gap(12),
TextField(
autocorrect: false,
enableSuggestions: false,
controller: _nicknameController,
autofillHints: const [AutofillHints.nickname],
decoration: InputDecoration(
isDense: true,
border: const UnderlineInputBorder(),
labelText: 'fieldNickname'.tr(),
const Gap(12),
TextFormField(
validator: (value) {
if (value == null || value.length < 4 || value.length > 32) {
return 'fieldNicknameLengthLimit'.tr(args: [4.toString(), 32.toString()]);
}
return null;
},
autocorrect: false,
enableSuggestions: false,
controller: _nicknameController,
autofillHints: const [AutofillHints.nickname],
decoration: InputDecoration(
isDense: true,
border: const UnderlineInputBorder(),
labelText: 'fieldNickname'.tr(),
),
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
),
onTapOutside: (_) =>
FocusManager.instance.primaryFocus?.unfocus(),
),
const Gap(12),
TextField(
autocorrect: false,
enableSuggestions: false,
controller: _emailController,
autofillHints: const [AutofillHints.email],
decoration: InputDecoration(
isDense: true,
border: const UnderlineInputBorder(),
labelText: 'fieldEmail'.tr(),
const Gap(12),
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'fieldCannotBeEmpty'.tr();
}
if (!EmailValidator.validate(value)) {
return 'fieldEmailAddressMustBeValid'.tr();
}
return null;
},
autocorrect: false,
enableSuggestions: false,
controller: _emailController,
autofillHints: const [AutofillHints.email],
decoration: InputDecoration(
isDense: true,
border: const UnderlineInputBorder(),
labelText: 'fieldEmail'.tr(),
),
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
),
onTapOutside: (_) =>
FocusManager.instance.primaryFocus?.unfocus(),
),
const Gap(12),
TextField(
obscureText: true,
autocorrect: false,
enableSuggestions: false,
autofillHints: const [AutofillHints.password],
controller: _passwordController,
decoration: InputDecoration(
isDense: true,
border: const UnderlineInputBorder(),
labelText: 'fieldPassword'.tr(),
const Gap(12),
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'fieldCannotBeEmpty'.tr();
}
return null;
},
obscureText: true,
autocorrect: false,
enableSuggestions: false,
autofillHints: const [AutofillHints.password],
controller: _passwordController,
decoration: InputDecoration(
isDense: true,
border: const UnderlineInputBorder(),
labelText: 'fieldPassword'.tr(),
),
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
),
onTapOutside: (_) =>
FocusManager.instance.primaryFocus?.unfocus(),
onSubmitted: (_) => _performAction(context),
),
],
).padding(horizontal: 7),
],
).padding(horizontal: 7),
),
const Gap(16),
Align(
alignment: Alignment.centerRight,

View File

@ -23,6 +23,7 @@ import pasteboard
import path_provider_foundation
import screen_brightness_macos
import sentry_flutter
import share_plus
import shared_preferences_foundation
import sqflite_darwin
import url_launcher_macos
@ -47,6 +48,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
ScreenBrightnessMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenBrightnessMacosPlugin"))
SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin"))
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))

View File

@ -454,6 +454,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.0.2"
email_validator:
dependency: "direct main"
description:
name: email_validator
sha256: b19aa5d92fdd76fbc65112060c94d45ba855105a28bb6e462de7ff03b12fa1fb
url: "https://pub.dev"
source: hosted
version: "3.0.0"
equatable:
dependency: transitive
description:
@ -1538,6 +1546,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "8.10.1"
share_plus:
dependency: "direct main"
description:
name: share_plus
sha256: "9c9bafd4060728d7cdb2464c341743adbd79d327cb067ec7afb64583540b47c8"
url: "https://pub.dev"
source: hosted
version: "10.1.2"
share_plus_platform_interface:
dependency: transitive
description:
name: share_plus_platform_interface
sha256: c57c0bbfec7142e3a0f55633be504b796af72e60e3c791b44d5a017b985f7a48
url: "https://pub.dev"
source: hosted
version: "5.0.1"
shared_preferences:
dependency: "direct main"
description:

View File

@ -96,6 +96,8 @@ dependencies:
sliver_tools: ^0.2.12
bitsdojo_window: ^0.1.6
gal: ^2.3.0
share_plus: ^10.1.2
email_validator: ^3.0.0
dev_dependencies:
flutter_test:

View File

@ -20,6 +20,7 @@
#include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <screen_brightness_windows/screen_brightness_windows_plugin.h>
#include <sentry_flutter/sentry_flutter_plugin.h>
#include <share_plus/share_plus_windows_plugin_c_api.h>
#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
@ -51,6 +52,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("ScreenBrightnessWindowsPlugin"));
SentryFlutterPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SentryFlutterPlugin"));
SharePlusWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
}

View File

@ -17,6 +17,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
permission_handler_windows
screen_brightness_windows
sentry_flutter
share_plus
url_launcher_windows
)