From 147529d780c0e375740436e2e4bd483cf69de74f Mon Sep 17 00:00:00 2001 From: Jganenokk Date: Thu, 23 Jul 2026 20:24:53 +0700 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=BF=D0=BE=D1=81=D0=BC=D0=BE=D1=82?= =?UTF-8?q?=D1=80=D0=B5=D1=82=D1=8C=20=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D0=B5?= =?UTF-8?q?=20=D0=B8=D0=BC=D1=8F=20=D1=87=D0=B5=D0=BB=D0=BE=D0=B2=D0=B5?= =?UTF-8?q?=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../screens/chats/chat_info_screen.dart | 75 ++++++++++++++++--- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/lib/frontend/screens/chats/chat_info_screen.dart b/lib/frontend/screens/chats/chat_info_screen.dart index c264390..2789b30 100644 --- a/lib/frontend/screens/chats/chat_info_screen.dart +++ b/lib/frontend/screens/chats/chat_info_screen.dart @@ -11,6 +11,7 @@ import '../../../core/utils/format.dart'; import '../../../l10n/app_localizations.dart'; import '../../../models/chat_info.dart'; import '../../../models/contact_info.dart'; +import '../../widgets/animated_text_swap.dart'; import '../../widgets/avatar_history_screen.dart'; import '../../widgets/chat_info/shared_content_tabs.dart'; import '../../widgets/connection_status.dart'; @@ -75,6 +76,7 @@ class _ChatInfoScreenState extends State { ChatInfo? _chatInfo; String _selectedTab = ''; bool _descExpanded = false; + bool _showRealName = false; int? _otherId; ContactInfo? _contactData; @@ -294,15 +296,7 @@ class _ChatInfoScreenState extends State { const SizedBox(height: 4), _avatar(), const SizedBox(height: 14), - Text( - widget.name, - style: TextStyle( - color: cs.onSurface, - fontSize: 22, - fontWeight: FontWeight.w700, - ), - textAlign: TextAlign.center, - ), + _buildNameRow(cs), const SizedBox(height: 4), Text( _subtitle(), @@ -322,6 +316,69 @@ class _ChatInfoScreenState extends State { ); } + String? get _realName { + final data = _contactData; + if (data == null) return null; + for (final n in data.names) { + if (n.type == 'ONEME') { + final combined = [n.firstName, n.lastName] + .where((s) => s != null && s.trim().isNotEmpty) + .map((s) => s!.trim()) + .join(' '); + if (combined.isNotEmpty) return combined; + final label = n.label; + if (label != null && label.isNotEmpty) return label; + } + } + return null; + } + + Widget _buildNameRow(ColorScheme cs) { + final nameStyle = TextStyle( + color: cs.onSurface, + fontSize: 22, + fontWeight: FontWeight.w700, + ); + final real = _realName; + final hasToggle = + widget.chatType == 'DIALOG' && real != null && real != widget.name; + + final nameSwap = AnimatedTextSwap( + showAlternate: _showRealName, + alignment: Alignment.center, + alternate: Text( + real ?? widget.name, + style: nameStyle, + textAlign: TextAlign.center, + ), + child: Text(widget.name, style: nameStyle, textAlign: TextAlign.center), + ); + + if (!hasToggle) return nameSwap; + + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const SizedBox(width: 36), + Flexible(child: nameSwap), + SizedBox( + width: 36, + child: IconButton( + padding: EdgeInsets.zero, + visualDensity: VisualDensity.compact, + iconSize: 20, + color: _showRealName ? cs.primary : cs.onSurfaceVariant, + icon: Icon( + _showRealName ? Symbols.visibility : Symbols.visibility_off, + ), + tooltip: real, + onPressed: () => setState(() => _showRealName = !_showRealName), + ), + ), + ], + ); + } + String _subtitle() { final l10n = AppLocalizations.of(context)!; switch (widget.chatType) {