правки по лаунчеру

This commit is contained in:
2026-07-28 20:43:53 +04:00
parent 155922a3f1
commit 0b6f7fc647
51 changed files with 3158 additions and 437 deletions
+169 -56
View File
@@ -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,
),
),
),
),