颜色,基础组件重新封装,降低理解难度,分层更明显。入口更抽象

This commit is contained in:
Cody
2026-03-10 09:38:07 +08:00
parent ea3192bd65
commit ed93d556d6
13 changed files with 590 additions and 537 deletions

View File

@@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:im_app/core/ui/base/context_theme_ext.dart';
import 'package:im_app/core/ui/components/app_button.dart';
import 'package:im_app/features/login/presentation/login_state.dart';
/// 登录步骤 2 — 输入验证码并完成登录
@@ -31,21 +33,22 @@ class LoginOtpStep extends StatelessWidget {
@override
Widget build(BuildContext context) {
final s = context.styles;
final c = context.colors;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'输入验证码',
style: Theme.of(context).textTheme.headlineSmall,
style: s.headlineSmall,
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
Text(
'验证码已发送至 ${state.countryCode} ${state.maskedContact}',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
style: s.bodyMedium?.copyWith(color: c.textSecondary),
textAlign: TextAlign.center,
),
const SizedBox(height: 32),
@@ -55,7 +58,6 @@ class LoginOtpStep extends StatelessWidget {
maxLength: 4,
decoration: const InputDecoration(
labelText: '4 位验证码',
border: OutlineInputBorder(),
counterText: '',
),
autofillHints: const [AutofillHints.oneTimeCode],
@@ -66,24 +68,19 @@ class LoginOtpStep extends StatelessWidget {
padding: const EdgeInsets.only(bottom: 16),
child: Text(
state.error!,
style: TextStyle(color: Theme.of(context).colorScheme.error),
style: s.bodyError,
textAlign: TextAlign.center,
),
),
FilledButton(
AppButton.primary(
label: '登录',
onPressed: state.isLoading ? null : onVerifyAndLogin,
child: state.isLoading
? const SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Text('登录'),
isLoading: state.isLoading,
),
const SizedBox(height: 12),
TextButton(
AppButton.text(
label: '返回修改手机号',
onPressed: state.isLoading ? null : onBackToPhone,
child: const Text('返回修改手机号'),
),
],
);

View File

@@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:im_app/core/ui/base/context_theme_ext.dart';
import 'package:im_app/core/ui/components/app_button.dart';
import 'package:im_app/features/login/presentation/login_state.dart';
/// 登录步骤 1 — 输入国家代码 + 手机号
@@ -28,13 +30,16 @@ class LoginPhoneStep extends StatelessWidget {
@override
Widget build(BuildContext context) {
final s = context.styles;
final c = context.colors;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'手机号登录',
style: Theme.of(context).textTheme.headlineSmall,
style: s.headlineSmall,
textAlign: TextAlign.center,
),
const SizedBox(height: 40),
@@ -43,25 +48,17 @@ class LoginPhoneStep extends StatelessWidget {
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).colorScheme.outline,
),
border: Border.all(color: c.borderDefault),
borderRadius: BorderRadius.circular(4),
),
child: Text(
state.countryCode,
style: Theme.of(context).textTheme.bodyLarge,
),
child: Text(state.countryCode, style: s.bodyLarge),
),
const SizedBox(width: 8),
Expanded(
child: TextField(
controller: phoneCtrl,
keyboardType: TextInputType.phone,
decoration: const InputDecoration(
labelText: '手机号',
border: OutlineInputBorder(),
),
decoration: const InputDecoration(labelText: '手机号'),
autofillHints: const [AutofillHints.telephoneNumber],
),
),
@@ -73,19 +70,14 @@ class LoginPhoneStep extends StatelessWidget {
padding: const EdgeInsets.only(bottom: 16),
child: Text(
state.error!,
style: TextStyle(color: Theme.of(context).colorScheme.error),
style: s.bodyError,
textAlign: TextAlign.center,
),
),
FilledButton(
AppButton.primary(
label: '获取验证码',
onPressed: state.isLoading ? null : onSendOtp,
child: state.isLoading
? const SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Text('获取验证码'),
isLoading: state.isLoading,
),
],
);

View File

@@ -29,11 +29,11 @@ class ThemeOptionTile extends StatelessWidget {
@override
Widget build(BuildContext context) {
final s = context.styles;
final c = context.colors;
return ListTile(
title: Text(label),
trailing: isSelected ? Icon(Icons.check, color: s.primary) : null,
trailing: isSelected ? Icon(Icons.check, color: c.brandPrimary) : null,
onTap: onTap,
);
}