import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '/data/models/contact_model.dart'; class ContactTile extends StatefulWidget { final Contact contact; final VoidCallback? onTap; const ContactTile({super.key, required this.contact, this.onTap}); @override State createState() => _ContactTileState(); } class _ContactTileState extends State { SharedPreferences? _prefs; Duration? offset; @override void initState() { super.initState(); DateTime now = DateTime.now(); offset = now.timeZoneOffset; _initPrefs(); } Future _initPrefs() async { final shared = await SharedPreferences.getInstance(); if (mounted) { setState(() { _prefs = shared; }); } } String get displayName { if (_prefs == null) return widget.contact.name; final id = widget.contact.id; final savedName = _prefs!.getString('firstname_$id'); final savedSurname = _prefs!.getString('lastname_$id'); final name = savedName ?? widget.contact.name; final surname = savedSurname ?? widget.contact.surname; final full = '${name != 'Unknown' ? name : ''} ${surname != 'Unknown' ? surname : ''}' .trim(); if (full.isNotEmpty) return full; if (widget.contact.username != 'Unknown') return widget.contact.username; return 'User'; } @override Widget build(BuildContext context) { final primary = Theme.of(context).colorScheme.primary; final username = widget.contact.username; final initials = (displayName.isNotEmpty ? displayName : (username != 'Unknown' ? username : 'U')) .trim() .split(RegExp(r'\s+')) .where((p) => p.isNotEmpty) .take(2) .map((p) => p[0].toUpperCase()) .join(); return ListTile( onTap: widget.onTap, contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), leading: CircleAvatar( radius: 28, backgroundColor: primary.withAlpha((0.1 * 255).round()), backgroundImage: widget.contact.effectiveAvatarUrl != null ? NetworkImage(widget.contact.effectiveAvatarUrl!) : null, child: widget.contact.effectiveAvatarUrl == null ? Text( initials, style: TextStyle( color: Theme.of(context).colorScheme.primary, fontWeight: FontWeight.bold, ), ) : null, ), title: Text( displayName, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16), ), subtitle: Text( widget.contact.isLastMsgDecrypted ? widget.contact.lastMessage ?? "Нет сообщений" : (widget.contact.lastMessage != null ? "Ожидание дешифровки..." : "Нет сообщений"), maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle(color: Colors.grey), ), trailing: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( _formatTime(widget.contact.lastMessageTime), style: const TextStyle(color: Colors.grey, fontSize: 12), ), const SizedBox(height: 4), if (widget.contact.unreadCount > 0) Container( padding: const EdgeInsets.all(6), decoration: BoxDecoration( color: primary.withAlpha((0.5 * 255).round()), shape: BoxShape.circle, ), child: Text( '${widget.contact.unreadCount}', style: const TextStyle(color: Colors.white, fontSize: 10), ), ), ], ), ); } String _formatTime(DateTime? time) { if (time == null) return ""; time = time.add(offset!); return "${time.hour}:${time.minute.toString().padLeft(2, '0')}"; } }