Skip to content

Commit 9f74be0

Browse files
committed
refactor: 优化 User Profile
1 parent 3e843c0 commit 9f74be0

1 file changed

Lines changed: 73 additions & 122 deletions

File tree

lib/screens/user_profile_screen.dart

Lines changed: 73 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import '../models/settings_service.dart';
99
import '../widgets/account/profile_picture.dart';
1010
import '../utils/talker.dart';
1111

12+
const double _kProfileMaxWidth = 680;
13+
1214
class UserProfileScreen extends StatelessWidget {
1315
final String userId;
1416

@@ -27,7 +29,7 @@ class UserProfileScreen extends StatelessWidget {
2729
// App Bar with background
2830
SliverAppBar(
2931
pinned: true,
30-
expandedHeight: 200,
32+
expandedHeight: 160,
3133
leading: IconButton(
3234
icon: const Icon(Icons.close),
3335
onPressed: () => context.pop(),
@@ -36,7 +38,6 @@ class UserProfileScreen extends StatelessWidget {
3638
IconButton(
3739
icon: const Icon(Symbols.share),
3840
onPressed: () {
39-
// Share profile
4041
ScaffoldMessenger.of(context).showSnackBar(
4142
SnackBar(
4243
content: Text('Share ${profile.username}'),
@@ -61,37 +62,44 @@ class UserProfileScreen extends StatelessWidget {
6162
),
6263
),
6364
),
64-
65+
6566
// Content
6667
SliverToBoxAdapter(
67-
child: SingleChildScrollView(
68-
padding: const EdgeInsets.all(16),
69-
child: Column(
70-
crossAxisAlignment: CrossAxisAlignment.start,
71-
children: [
72-
// Avatar and basic info
73-
_buildBasicInfoCard(context, profile, l10n, colorScheme),
74-
const SizedBox(height: 16),
75-
76-
// Personal sign
77-
if (profile.personalSign != null && profile.personalSign!.isNotEmpty)
78-
_buildBioCard(context, profile, l10n, colorScheme),
79-
80-
// Details card
81-
_buildDetailsCard(context, profile, l10n, colorScheme),
82-
const SizedBox(height: 16),
83-
84-
// Introduction
85-
if (profile.introduction != null && profile.introduction!.isNotEmpty)
86-
_buildIntroductionCard(context, profile, l10n, colorScheme),
87-
88-
const SizedBox(height: 16),
89-
90-
// Action buttons
91-
_buildActionButtons(context, profile, l10n),
92-
93-
const SizedBox(height: 32),
94-
],
68+
child: Center(
69+
child: ConstrainedBox(
70+
constraints: const BoxConstraints(maxWidth: _kProfileMaxWidth),
71+
child: Padding(
72+
padding: const EdgeInsets.symmetric(horizontal: 16),
73+
child: Column(
74+
crossAxisAlignment: CrossAxisAlignment.stretch,
75+
children: [
76+
// Avatar + name header
77+
_buildProfileHeader(context, profile, l10n, colorScheme),
78+
79+
// Action buttons
80+
_buildActionButtons(context, profile, l10n),
81+
const SizedBox(height: 16),
82+
83+
// Personal sign
84+
if (profile.personalSign != null && profile.personalSign!.isNotEmpty) ...[
85+
_buildBioCard(context, profile, l10n, colorScheme),
86+
const SizedBox(height: 16),
87+
],
88+
89+
// Details card
90+
_buildDetailsCard(context, profile, l10n, colorScheme),
91+
const SizedBox(height: 16),
92+
93+
// Introduction
94+
if (profile.introduction != null && profile.introduction!.isNotEmpty) ...[
95+
_buildIntroductionCard(context, profile, l10n, colorScheme),
96+
const SizedBox(height: 16),
97+
],
98+
99+
const SizedBox(height: 16),
100+
],
101+
),
102+
),
95103
),
96104
),
97105
),
@@ -100,105 +108,48 @@ class UserProfileScreen extends StatelessWidget {
100108
);
101109
}
102110

103-
Widget _buildBasicInfoCard(
111+
Widget _buildProfileHeader(
104112
BuildContext context,
105113
UserProfile profile,
106114
AppLocalizations l10n,
107115
ColorScheme colorScheme,
108116
) {
109-
return Card(
110-
child: Padding(
111-
padding: const EdgeInsets.all(20),
112-
child: Row(
113-
crossAxisAlignment: CrossAxisAlignment.start,
114-
children: [
115-
// Avatar
116-
ProfilePictureWidget(
117-
avatarUrl: profile.avatar,
118-
radius: 40,
119-
),
120-
const SizedBox(width: 16),
121-
122-
// Name and stats
123-
Expanded(
124-
child: Column(
125-
crossAxisAlignment: CrossAxisAlignment.start,
126-
children: [
127-
Row(
128-
crossAxisAlignment: CrossAxisAlignment.end,
129-
children: [
130-
Flexible(
131-
child: Text(
132-
profile.username,
133-
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
134-
fontWeight: FontWeight.bold,
135-
),
136-
),
137-
),
138-
const SizedBox(width: 8),
139-
Flexible(
140-
child: Padding(
141-
padding: const EdgeInsets.only(bottom: 2),
142-
child: Text(
143-
'@${profile.username}',
144-
style: TextStyle(
145-
fontSize: 13,
146-
color: colorScheme.onSurfaceVariant,
147-
),
148-
),
149-
),
150-
),
151-
],
152-
),
153-
const SizedBox(height: 4),
154-
_buildPermissionBadge(context, profile, l10n, colorScheme),
155-
],
156-
),
117+
return Column(
118+
children: [
119+
const SizedBox(height: 24),
120+
Container(
121+
decoration: BoxDecoration(
122+
shape: BoxShape.circle,
123+
border: Border.all(
124+
color: colorScheme.surface,
125+
width: 4,
157126
),
158-
],
127+
),
128+
child: ProfilePictureWidget(
129+
avatarUrl: profile.avatar,
130+
radius: 72,
131+
fallbackText: profile.username,
132+
),
159133
),
160-
),
161-
);
162-
}
163-
164-
Widget _buildPermissionBadge(
165-
BuildContext context,
166-
UserProfile profile,
167-
AppLocalizations l10n,
168-
ColorScheme colorScheme,
169-
) {
170-
String permissionText;
171-
Color badgeColor;
172-
173-
switch (profile.stat.toLowerCase()) {
174-
case 'admin':
175-
permissionText = l10n.userProfilePermissionAdmin;
176-
badgeColor = Colors.red;
177-
break;
178-
case 'moderator':
179-
permissionText = l10n.userProfilePermissionModerator;
180-
badgeColor = Colors.orange;
181-
break;
182-
default:
183-
permissionText = l10n.userProfilePermissionUser;
184-
badgeColor = colorScheme.primary;
185-
}
186-
187-
return Container(
188-
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
189-
decoration: BoxDecoration(
190-
color: badgeColor.withOpacity(0.1),
191-
borderRadius: BorderRadius.circular(4),
192-
border: Border.all(color: badgeColor.withOpacity(0.3)),
193-
),
194-
child: Text(
195-
permissionText,
196-
style: TextStyle(
197-
color: badgeColor,
198-
fontSize: 12,
199-
fontWeight: FontWeight.w500,
134+
const SizedBox(height: 12),
135+
Text(
136+
profile.username,
137+
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
138+
fontWeight: FontWeight.bold,
139+
),
140+
textAlign: TextAlign.center,
200141
),
201-
),
142+
const SizedBox(height: 4),
143+
Text(
144+
'@${profile.username}',
145+
style: TextStyle(
146+
fontSize: 14,
147+
color: colorScheme.onSurfaceVariant,
148+
),
149+
textAlign: TextAlign.center,
150+
),
151+
const SizedBox(height: 20),
152+
],
202153
);
203154
}
204155

0 commit comments

Comments
 (0)