fix: tema correto na lista de murais, borda nos itens de chat e ajustes no perfil

This commit is contained in:
2026-09-23 12:14:18 -03:00
parent 48a50744de
commit c0463e51f9
3 changed files with 263 additions and 218 deletions

View File

@@ -31,10 +31,10 @@ import 'package:tatchat/widgets/qr_code_viewer.dart';
/// Shows the profile of the active account: avatar, display name, status, the
/// own QR code, the global user ID and an optional QR code scanner.
Future<void> showSelfProfileDialog(BuildContext context) => showAdaptiveDialog(
context: context,
barrierDismissible: true,
builder: (context) => const SelfProfileDialog(),
);
context: context,
barrierDismissible: true,
builder: (context) => const SelfProfileDialog(),
);
class SelfProfileDialog extends StatefulWidget {
const SelfProfileDialog({super.key});
@@ -236,120 +236,126 @@ class _SelfProfileDialogState extends State<SelfProfileDialog> {
final userId = client.userID;
final l10n = L10n.of(context);
_profileFuture ??= client.fetchOwnProfile();
return AlertDialog.adaptive(
insetPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24),
content: SingleChildScrollView(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 420),
child: Column(
mainAxisSize: .min,
crossAxisAlignment: .stretch,
children: [
FutureBuilder<Profile>(
future: _profileFuture,
builder: (context, snapshot) {
final profile = snapshot.data;
final avatar = profile?.avatarUrl;
final displayname =
profile?.displayName ?? userId?.localpart ?? l10n.user;
return Column(
children: [
Center(
child: Stack(
alignment: .center,
children: [
Avatar(
mxContent: avatar,
name: displayname,
size: 96,
shapeBorder: const CircleBorder(),
onTap: avatar != null
? () => showDialog(
context: context,
builder: (_) => MxcImageViewer(avatar),
)
: null,
),
Positioned(
right: 0,
bottom: 0,
child: Material(
color: theme.colorScheme.primary,
shape: const CircleBorder(),
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: _editAvatar,
child: SizedBox(
width: 30,
height: 30,
child: Icon(
Icons.edit_outlined,
size: 16,
color: theme.colorScheme.onPrimary,
child: SizedBox(
width: MediaQuery.of(context).size.width > 720 ? 420 : MediaQuery.of(context).size.width,
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 800),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
FutureBuilder<Profile>(
future: _profileFuture,
builder: (context, snapshot) {
final profile = snapshot.data;
final avatar = profile?.avatarUrl;
final displayname =
profile?.displayName ?? userId?.localpart ?? l10n.user;
return Column(
children: [
Center(
child: Stack(
alignment: Alignment.center,
children: [
Avatar(
mxContent: avatar,
name: displayname,
size: 96,
shapeBorder: const CircleBorder(),
onTap: avatar != null
? () => showDialog(
context: context,
builder: (_) =>
MxcImageViewer(avatar),
)
: null,
),
Positioned(
right: 0,
bottom: 0,
child: Material(
color: theme.colorScheme.primary,
shape: const CircleBorder(),
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: _editAvatar,
child: SizedBox(
width: 30,
height: 30,
child: Icon(
Icons.camera_alt_outlined,
size: 18,
color: theme.colorScheme.onPrimary,
),
),
),
),
),
),
],
],
),
),
const SizedBox(height: 16),
_EditableLine(
text: displayname,
style: theme.textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
),
tooltip: l10n.editDisplayname,
onEdit: _editDisplayName,
),
const SizedBox(height: 0),
_EditableLine(
text: _statusMsg?.trim().isNotEmpty == true
? _statusMsg!
: l10n.setStatus,
style: _statusMsg?.trim().isNotEmpty == true
? theme.textTheme.bodyMedium
: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
fontStyle: FontStyle.italic,
),
tooltip: l10n.setStatus,
onEdit: _editStatus,
),
],
);
},
),
const SizedBox(height: 24),
if (userId != null) ...[
Center(
child: Material(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
AppConfig.borderRadius,
),
side: BorderSide(
width: 2,
color: theme.colorScheme.primary,
),
),
const SizedBox(height: 16),
_EditableLine(
text: displayname,
style: theme.textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
color: Colors.transparent,
clipBehavior: Clip.hardEdge,
child: InkWell(
borderRadius: BorderRadius.circular(
AppConfig.borderRadius,
),
tooltip: l10n.editDisplayname,
onEdit: _editDisplayName,
),
const SizedBox(height: 8),
_EditableLine(
text: _statusMsg?.trim().isNotEmpty == true
? _statusMsg!
: l10n.setStatus,
style: _statusMsg?.trim().isNotEmpty == true
? theme.textTheme.bodyMedium
: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
fontStyle: FontStyle.italic,
),
tooltip: l10n.setStatus,
onEdit: _editStatus,
),
],
);
},
),
const SizedBox(height: 24),
if (userId != null) ...[
Center(
child: Material(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
AppConfig.borderRadius,
),
side: BorderSide(
width: 2,
color: theme.colorScheme.primary,
),
),
color: Colors.transparent,
clipBehavior: Clip.hardEdge,
child: InkWell(
borderRadius: BorderRadius.circular(
AppConfig.borderRadius,
),
onTap: () => showQrCodeViewer(context, userId),
child: Padding(
padding: const EdgeInsets.all(16),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 160),
child: PrettyQrView.data(
data: 'https://matrix.to/#/$userId',
decoration: PrettyQrDecoration(
shape: PrettyQrSmoothSymbol(
roundFactor: 1,
color: theme.colorScheme.primary,
onTap: () => showQrCodeViewer(context, userId),
child: Padding(
padding: const EdgeInsets.all(16),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 160),
child: PrettyQrView.data(
data: 'https://matrix.to/#/$userId',
decoration: PrettyQrDecoration(
shape: PrettyQrSmoothSymbol(
roundFactor: 1,
color: theme.colorScheme.primary,
),
),
),
),
@@ -357,72 +363,72 @@ class _SelfProfileDialogState extends State<SelfProfileDialog> {
),
),
),
),
const SizedBox(height: 12),
Center(
child: Material(
color: theme.colorScheme.surfaceContainerHigh,
borderRadius: BorderRadius.circular(99),
child: InkWell(
const SizedBox(height: 12),
Center(
child: Material(
color: theme.colorScheme.surfaceContainerHigh,
borderRadius: BorderRadius.circular(99),
onTap: _copyUserId,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 8,
),
child: Row(
mainAxisSize: .min,
children: [
Flexible(
child: Text(
userId,
maxLines: 1,
overflow: .ellipsis,
style: theme.textTheme.bodySmall?.copyWith(
fontFamily: 'RobotoMono',
color: theme.colorScheme.onSurfaceVariant,
child: InkWell(
borderRadius: BorderRadius.circular(99),
onTap: _copyUserId,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 8,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: Text(
userId,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: theme.textTheme.bodySmall?.copyWith(
fontFamily: 'RobotoMono',
color: theme.colorScheme.onSurfaceVariant,
),
),
),
),
const SizedBox(width: 8),
Icon(
_copied
? Icons.check_circle
: Icons.copy_outlined,
size: 14,
color: _copied
? Colors.green
: theme.colorScheme.onSurfaceVariant,
),
],
const SizedBox(width: 8),
Icon(
_copied
? Icons.check_circle
: Icons.copy_outlined,
size: 14,
color: _copied
? Colors.green
: theme.colorScheme.onSurfaceVariant,
),
],
),
),
),
),
),
),
],
const Divider(height: 32),
if (PlatformInfos.isMobile)
],
const Divider(height: 32),
if (PlatformInfos.isMobile)
ListTile(
contentPadding: EdgeInsets.zero,
dense: true,
leading: CircleAvatar(
backgroundColor: theme.colorScheme.primaryContainer,
foregroundColor: theme.colorScheme.onPrimaryContainer,
child: const Icon(Icons.qr_code_scanner_outlined),
),
title: Text(l10n.scanQrCode),
onTap: _openQrScanner,
),
ListTile(
contentPadding: EdgeInsets.zero,
dense: true,
leading: CircleAvatar(
backgroundColor: theme.colorScheme.primaryContainer,
foregroundColor: theme.colorScheme.onPrimaryContainer,
child: const Icon(Icons.qr_code_scanner_outlined),
),
title: Text(l10n.scanQrCode),
onTap: _openQrScanner,
leading: const Icon(Icons.settings_outlined),
title: Text(l10n.settings),
onTap: _openSettingsAction,
),
ListTile(
contentPadding: EdgeInsets.zero,
dense: true,
leading: const Icon(Icons.settings_outlined),
title: Text(l10n.settings),
onTap: _openSettingsAction,
),
],
],
),
),
),
),
@@ -448,14 +454,14 @@ class _EditableLine extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: .center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Flexible(
child: Text(
text,
maxLines: 3,
overflow: .ellipsis,
textAlign: .center,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: style,
),
),
@@ -473,4 +479,4 @@ class _EditableLine extends StatelessWidget {
}
}
enum _AvatarAction { camera, file, remove }
enum _AvatarAction { camera, file, remove }