правки по лаунчеру
This commit is contained in:
@@ -2,21 +2,39 @@ import 'package:flutter/material.dart';
|
||||
import 'package:moonwell_launcher/app/design_system/mw_shells.dart';
|
||||
import 'package:moonwell_launcher/app/theme/moonwell_design_system.dart';
|
||||
|
||||
enum MwAuthenticationMode { login, registration }
|
||||
|
||||
class MwAuthenticationForm extends StatefulWidget {
|
||||
const MwAuthenticationForm({
|
||||
super.key,
|
||||
required this.usernameController,
|
||||
required this.passwordController,
|
||||
required this.onSubmit,
|
||||
this.emailController,
|
||||
this.passwordConfirmationController,
|
||||
this.inviteCodeController,
|
||||
this.mode = MwAuthenticationMode.login,
|
||||
this.onModeChanged,
|
||||
this.termsAccepted = false,
|
||||
this.onTermsChanged,
|
||||
this.loading = false,
|
||||
this.error,
|
||||
this.success,
|
||||
});
|
||||
|
||||
final TextEditingController usernameController;
|
||||
final TextEditingController passwordController;
|
||||
final TextEditingController? emailController;
|
||||
final TextEditingController? passwordConfirmationController;
|
||||
final TextEditingController? inviteCodeController;
|
||||
final VoidCallback onSubmit;
|
||||
final MwAuthenticationMode mode;
|
||||
final ValueChanged<MwAuthenticationMode>? onModeChanged;
|
||||
final bool termsAccepted;
|
||||
final ValueChanged<bool>? onTermsChanged;
|
||||
final bool loading;
|
||||
final String? error;
|
||||
final String? success;
|
||||
|
||||
@override
|
||||
State<MwAuthenticationForm> createState() => _MwAuthenticationFormState();
|
||||
@@ -28,6 +46,7 @@ class _MwAuthenticationFormState extends State<MwAuthenticationForm> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final accent = MoonWellDesignTokens.of(context).accent;
|
||||
final registering = widget.mode == MwAuthenticationMode.registration;
|
||||
return AutofillGroup(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
@@ -35,13 +54,13 @@ class _MwAuthenticationFormState extends State<MwAuthenticationForm> {
|
||||
const MwBrandMark(width: 210, compact: true),
|
||||
const SizedBox(height: 28),
|
||||
Text(
|
||||
'ВХОД',
|
||||
registering ? 'РЕГИСТРАЦИЯ' : 'ВХОД',
|
||||
style: TextStyle(color: accent, fontSize: 10, letterSpacing: 2.4),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
const Text(
|
||||
'С возвращением',
|
||||
style: TextStyle(
|
||||
Text(
|
||||
registering ? 'Создать аккаунт' : 'С возвращением',
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Cinzel',
|
||||
color: Color(0xFFECE4D0),
|
||||
fontSize: 30,
|
||||
@@ -49,9 +68,11 @@ class _MwAuthenticationFormState extends State<MwAuthenticationForm> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 7),
|
||||
const Text(
|
||||
'Войди в свой аккаунт, чтобы продолжить путь.',
|
||||
style: TextStyle(
|
||||
Text(
|
||||
registering
|
||||
? 'Зарегистрируй игровой аккаунт MoonWell.'
|
||||
: 'Войди в свой аккаунт, чтобы продолжить путь.',
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Cormorant Garamond',
|
||||
fontStyle: FontStyle.italic,
|
||||
color: Color(0x80ECE4D0),
|
||||
@@ -61,12 +82,30 @@ class _MwAuthenticationFormState extends State<MwAuthenticationForm> {
|
||||
const SizedBox(height: 22),
|
||||
Row(
|
||||
children: [
|
||||
_Tab(label: 'ВХОД', selected: true, accent: accent),
|
||||
_Tab(label: 'РЕГИСТРАЦИЯ', accent: accent),
|
||||
_Tab(
|
||||
label: 'ВХОД',
|
||||
selected: !registering,
|
||||
accent: accent,
|
||||
onTap: widget.loading
|
||||
? null
|
||||
: () => widget.onModeChanged?.call(
|
||||
MwAuthenticationMode.login,
|
||||
),
|
||||
),
|
||||
_Tab(
|
||||
label: 'РЕГИСТРАЦИЯ',
|
||||
selected: registering,
|
||||
accent: accent,
|
||||
onTap: widget.loading
|
||||
? null
|
||||
: () => widget.onModeChanged?.call(
|
||||
MwAuthenticationMode.registration,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 18),
|
||||
_FieldLabel(text: 'ЛОГИН ИЛИ EMAIL'),
|
||||
_FieldLabel(text: registering ? 'ЛОГИН' : 'ЛОГИН ИЛИ EMAIL'),
|
||||
const SizedBox(height: 7),
|
||||
TextField(
|
||||
controller: widget.usernameController,
|
||||
@@ -75,6 +114,19 @@ class _MwAuthenticationFormState extends State<MwAuthenticationForm> {
|
||||
autofillHints: const [AutofillHints.username],
|
||||
decoration: const InputDecoration(hintText: 'Aranthel'),
|
||||
),
|
||||
if (registering) ...[
|
||||
const SizedBox(height: 14),
|
||||
const _FieldLabel(text: 'EMAIL'),
|
||||
const SizedBox(height: 7),
|
||||
TextField(
|
||||
controller: widget.emailController,
|
||||
enabled: !widget.loading,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
textInputAction: TextInputAction.next,
|
||||
autofillHints: const [AutofillHints.email],
|
||||
decoration: const InputDecoration(hintText: 'player@example.com'),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 14),
|
||||
_FieldLabel(text: 'ПАРОЛЬ'),
|
||||
const SizedBox(height: 7),
|
||||
@@ -82,10 +134,35 @@ class _MwAuthenticationFormState extends State<MwAuthenticationForm> {
|
||||
controller: widget.passwordController,
|
||||
enabled: !widget.loading,
|
||||
obscureText: true,
|
||||
textInputAction: TextInputAction.done,
|
||||
autofillHints: const [AutofillHints.password],
|
||||
onSubmitted: (_) => widget.onSubmit(),
|
||||
textInputAction: registering
|
||||
? TextInputAction.next
|
||||
: TextInputAction.done,
|
||||
autofillHints: [
|
||||
registering ? AutofillHints.newPassword : AutofillHints.password,
|
||||
],
|
||||
onSubmitted: registering ? null : (_) => widget.onSubmit(),
|
||||
),
|
||||
if (registering) ...[
|
||||
const SizedBox(height: 14),
|
||||
const _FieldLabel(text: 'ПОВТОРИТЕ ПАРОЛЬ'),
|
||||
const SizedBox(height: 7),
|
||||
TextField(
|
||||
controller: widget.passwordConfirmationController,
|
||||
enabled: !widget.loading,
|
||||
obscureText: true,
|
||||
textInputAction: TextInputAction.next,
|
||||
autofillHints: const [AutofillHints.newPassword],
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
const _FieldLabel(text: 'ИНВАЙТ-КОД (НЕОБЯЗАТЕЛЬНО)'),
|
||||
const SizedBox(height: 7),
|
||||
TextField(
|
||||
controller: widget.inviteCodeController,
|
||||
enabled: !widget.loading,
|
||||
textInputAction: TextInputAction.done,
|
||||
onSubmitted: (_) => widget.onSubmit(),
|
||||
),
|
||||
],
|
||||
if (widget.error != null) ...[
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
@@ -93,30 +170,61 @@ class _MwAuthenticationFormState extends State<MwAuthenticationForm> {
|
||||
style: const TextStyle(color: Color(0xFFD76A78), fontSize: 12),
|
||||
),
|
||||
],
|
||||
if (widget.success != null) ...[
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
widget.success!,
|
||||
style: const TextStyle(color: Color(0xFF6FC28A), fontSize: 12),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 24,
|
||||
child: Checkbox(
|
||||
value: _remember,
|
||||
onChanged: widget.loading
|
||||
? null
|
||||
: (value) => setState(() => _remember = value ?? false),
|
||||
if (registering)
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 24,
|
||||
child: Checkbox(
|
||||
value: widget.termsAccepted,
|
||||
onChanged: widget.loading
|
||||
? null
|
||||
: (value) =>
|
||||
widget.onTermsChanged?.call(value ?? false),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Text(
|
||||
'Запомнить меня',
|
||||
style: TextStyle(color: Color(0x9AECE4D0), fontSize: 11),
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
'Забыли пароль?',
|
||||
style: TextStyle(color: accent, fontSize: 11),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Expanded(
|
||||
child: Text(
|
||||
'Я принимаю правила сервера и пользовательское соглашение',
|
||||
style: TextStyle(color: Color(0x9AECE4D0), fontSize: 11),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
else
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 24,
|
||||
child: Checkbox(
|
||||
value: _remember,
|
||||
onChanged: widget.loading
|
||||
? null
|
||||
: (value) => setState(() => _remember = value ?? false),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Text(
|
||||
'Запомнить меня',
|
||||
style: TextStyle(color: Color(0x9AECE4D0), fontSize: 11),
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
'Забыли пароль?',
|
||||
style: TextStyle(color: accent, fontSize: 11),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 18),
|
||||
SizedBox(
|
||||
height: 54,
|
||||
@@ -134,18 +242,18 @@ class _MwAuthenticationFormState extends State<MwAuthenticationForm> {
|
||||
dimension: 18,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: const Row(
|
||||
: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'ВОЙТИ',
|
||||
style: TextStyle(
|
||||
registering ? 'СОЗДАТЬ АККАУНТ' : 'ВОЙТИ',
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Cinzel',
|
||||
letterSpacing: 2.5,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 14),
|
||||
Icon(Icons.arrow_forward, size: 18),
|
||||
const SizedBox(width: 14),
|
||||
const Icon(Icons.arrow_forward, size: 18),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -153,7 +261,7 @@ class _MwAuthenticationFormState extends State<MwAuthenticationForm> {
|
||||
const SizedBox(height: 28),
|
||||
const Center(
|
||||
child: Text(
|
||||
'MOONWELL · V 1.0.0 · LOGIN.MOONWELL.GG',
|
||||
'MOONWELL · V 1.0.0 · PLAY.MOON-WELL.ONLINE',
|
||||
style: TextStyle(
|
||||
fontFamily: 'JetBrains Mono',
|
||||
color: Color(0x52ECE4D0),
|
||||
@@ -187,30 +295,35 @@ class _Tab extends StatelessWidget {
|
||||
const _Tab({
|
||||
required this.label,
|
||||
required this.accent,
|
||||
this.onTap,
|
||||
this.selected = false,
|
||||
});
|
||||
final String label;
|
||||
final Color accent;
|
||||
final VoidCallback? onTap;
|
||||
final bool selected;
|
||||
@override
|
||||
Widget build(BuildContext context) => Expanded(
|
||||
child: Container(
|
||||
height: 38,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: selected ? accent : const Color(0x247FB8D4),
|
||||
child: InkWell(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
height: 38,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: selected ? accent : const Color(0x247FB8D4),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Cinzel',
|
||||
color: selected ? const Color(0xFFECE4D0) : const Color(0x80ECE4D0),
|
||||
fontSize: 9,
|
||||
letterSpacing: 1.5,
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Cinzel',
|
||||
color: selected ? const Color(0xFFECE4D0) : const Color(0x80ECE4D0),
|
||||
fontSize: 9,
|
||||
letterSpacing: 1.5,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user