Refactor profile tab layout: replace SingleChildScrollView with Stack for improved logout button positioning and enhance avatar display
This commit is contained in:
@@ -326,101 +326,111 @@ class _AccountSettingsDialogState extends State<AccountSettingsDialog> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildProfileTab() {
|
Widget _buildProfileTab() {
|
||||||
return SingleChildScrollView(
|
return Stack(
|
||||||
child: Column(
|
children: [
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
SingleChildScrollView(
|
||||||
children: [
|
child: Column(
|
||||||
// Avatar
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
Center(
|
children: [
|
||||||
child: Column(
|
// Avatar
|
||||||
children: [
|
Center(
|
||||||
SizedBox(height: 16),
|
child: Column(
|
||||||
GestureDetector(
|
children: [
|
||||||
onTap: _pickAndUploadAvatar,
|
SizedBox(height: 16),
|
||||||
child: CircleAvatar(
|
GestureDetector(
|
||||||
radius: 50,
|
onTap: _pickAndUploadAvatar,
|
||||||
backgroundColor: AppTheme.secondaryText.withValues(
|
child: CircleAvatar(
|
||||||
alpha: 0.2,
|
radius: 50,
|
||||||
|
backgroundColor: AppTheme.secondaryText.withValues(
|
||||||
|
alpha: 0.2,
|
||||||
|
),
|
||||||
|
child: _avatarUrl != null && _blurHash != null
|
||||||
|
? ClipOval(
|
||||||
|
child: flutter_blurhash.BlurHash(
|
||||||
|
hash: _blurHash!,
|
||||||
|
image: _avatarUrl,
|
||||||
|
imageFit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Icon(
|
||||||
|
Icons.person,
|
||||||
|
size: 50,
|
||||||
|
color: AppTheme.secondaryText,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: _avatarUrl != null && _blurHash != null
|
const SizedBox(height: 8),
|
||||||
? ClipOval(
|
Text(
|
||||||
child: flutter_blurhash.BlurHash(
|
'Tap to change avatar',
|
||||||
hash: _blurHash!,
|
style: TextStyle(
|
||||||
image: _avatarUrl,
|
color: AppTheme.secondaryText,
|
||||||
imageFit: BoxFit.cover,
|
fontSize: 12,
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
: Icon(
|
],
|
||||||
Icons.person,
|
),
|
||||||
size: 50,
|
),
|
||||||
color: AppTheme.secondaryText,
|
const SizedBox(height: 24),
|
||||||
),
|
|
||||||
|
// Display Name
|
||||||
|
Text(
|
||||||
|
'Display Name',
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppTheme.primaryText,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppTheme.primaryBackground.withValues(alpha: 0.5),
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppTheme.accentColor.withValues(alpha: 0.3),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
child: TextFormField(
|
||||||
Text(
|
controller: _displayNameController,
|
||||||
'Tap to change avatar',
|
cursorColor: AppTheme.accentColor,
|
||||||
style: TextStyle(color: AppTheme.secondaryText, fontSize: 12),
|
style: TextStyle(color: AppTheme.primaryText),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'Enter display name',
|
||||||
|
hintStyle: TextStyle(color: AppTheme.secondaryText),
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: const EdgeInsets.all(12),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 24),
|
|
||||||
|
|
||||||
// Display Name
|
|
||||||
Text(
|
|
||||||
'Display Name',
|
|
||||||
style: TextStyle(
|
|
||||||
color: AppTheme.primaryText,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppTheme.primaryBackground.withValues(alpha: 0.5),
|
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
border: Border.all(
|
|
||||||
color: AppTheme.accentColor.withValues(alpha: 0.3),
|
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: 24),
|
||||||
child: TextFormField(
|
|
||||||
controller: _displayNameController,
|
|
||||||
cursorColor: AppTheme.accentColor,
|
|
||||||
style: TextStyle(color: AppTheme.primaryText),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: 'Enter display name',
|
|
||||||
hintStyle: TextStyle(color: AppTheme.secondaryText),
|
|
||||||
border: InputBorder.none,
|
|
||||||
contentPadding: const EdgeInsets.all(12),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 24),
|
|
||||||
|
|
||||||
// Save Button
|
// Save Button
|
||||||
Center(
|
Center(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 104,
|
width: 104,
|
||||||
child: ModernGlassButton(
|
child: ModernGlassButton(
|
||||||
onPressed: _updateProfile,
|
onPressed: _updateProfile,
|
||||||
child: const Text('Save Changes'),
|
child: const Text('Save Changes'),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: 80), // Space for logout button
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
),
|
||||||
|
// Logout Button in bottom right corner of profile tab
|
||||||
// Logout Button
|
Positioned(
|
||||||
Center(
|
bottom: 16,
|
||||||
child: IconButton(
|
right: 16,
|
||||||
onPressed: _logout,
|
child: IconButton(
|
||||||
icon: Icon(Icons.logout, color: AppTheme.errorColor),
|
onPressed: _logout,
|
||||||
tooltip: 'Logout',
|
icon: Icon(Icons.logout, color: AppTheme.errorColor),
|
||||||
iconSize: 28,
|
tooltip: 'Logout',
|
||||||
),
|
iconSize: 28,
|
||||||
|
splashColor: Colors.transparent,
|
||||||
|
highlightColor: Colors.transparent,
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user