From ff93286021aac143c21297e7036ce563397985d6 Mon Sep 17 00:00:00 2001 From: InviseDivine Date: Tue, 28 Apr 2026 19:11:43 +0200 Subject: [PATCH] chat info not finished --- .../screens/chats/chat_info_screen.dart | 61 ++++++++ lib/frontend/screens/chats/chat_screen.dart | 140 ++++++++++-------- lib/frontend/widgets/message_bubble.dart | 114 +++++++------- 3 files changed, 198 insertions(+), 117 deletions(-) create mode 100644 lib/frontend/screens/chats/chat_info_screen.dart diff --git a/lib/frontend/screens/chats/chat_info_screen.dart b/lib/frontend/screens/chats/chat_info_screen.dart new file mode 100644 index 0000000..c50ae93 --- /dev/null +++ b/lib/frontend/screens/chats/chat_info_screen.dart @@ -0,0 +1,61 @@ +import 'package:flutter/material.dart'; + +class ChatInfoScreen extends StatefulWidget { + final int chatId; + final String name; + final String imageUrl; + final String chatType; + + const ChatInfoScreen({ + super.key, + required this.chatId, + required this.name, + required this.imageUrl, + required this.chatType, + }); + @override + State createState() => _ChatInfoScreenState(); +} +class _ChatInfoScreenState extends State{ + + @override + Widget build(BuildContext context) { + final cs = Theme.of(context).colorScheme; + + return Scaffold( + backgroundColor: cs.surface, + appBar: AppBar( + + ), + body: + SizedBox( + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + if (widget.imageUrl.isNotEmpty) + CircleAvatar( + radius: 36, + backgroundImage: NetworkImage(widget.imageUrl), + ) + else + CircleAvatar( + radius: 36, + backgroundColor: cs.primaryContainer, + child: Text( + widget.name.isNotEmpty ? widget.name[0].toUpperCase() : '?', + style: TextStyle(color: cs.onPrimaryContainer, fontSize: 12), + ), + ), + Text( + widget.name, + style: TextStyle(color: Colors.white, fontSize: 24, height: 1.3), + ), + + ], + ), + ), + ); + } +} + diff --git a/lib/frontend/screens/chats/chat_screen.dart b/lib/frontend/screens/chats/chat_screen.dart index f127ce2..41069ac 100644 --- a/lib/frontend/screens/chats/chat_screen.dart +++ b/lib/frontend/screens/chats/chat_screen.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:komet/backend/modules/chats.dart'; +import 'package:komet/frontend/screens/chats/chat_info_screen.dart'; import 'package:material_symbols_icons/symbols.dart'; import '../../../main.dart'; import '../../../backend/api.dart'; @@ -256,71 +257,84 @@ class _ChatScreenState extends State String? status = chat?.type == "CHAT" ? "${chat?.participants.length.toString()} участников" : "last seen recently"; return Scaffold( backgroundColor: cs.surface, - appBar: AppBar( - backgroundColor: cs.surfaceContainerHigh, - foregroundColor: cs.onSurface, - elevation: 0, - surfaceTintColor: Colors.transparent, - iconTheme: IconThemeData(color: cs.onSurface), - leading: IconButton( - icon: const Icon(Symbols.arrow_back, weight: 400), - onPressed: () => Navigator.pop(context), - ), - titleSpacing: 0, - title: Row( - children: [ - if (widget.imageUrl.isNotEmpty) - CircleAvatar( - radius: 18, - backgroundImage: NetworkImage(widget.imageUrl), - ) - else - CircleAvatar( - radius: 18, - backgroundColor: cs.primaryContainer, - child: Text( - widget.name.isNotEmpty ? widget.name[0].toUpperCase() : '?', - style: TextStyle(color: cs.onPrimaryContainer, fontSize: 12), - ), - ), - const SizedBox(width: 12), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - widget.name, - style: TextStyle( - color: cs.onSurface, - fontSize: 16, - fontWeight: FontWeight.w600, - fontFamily: 'Outfit', - ), - ), - Text( - status ?? "", - style: TextStyle( - color: cs.onSurfaceVariant, - fontSize: 12, - fontWeight: FontWeight.w400, - ), - ), - ], - ), + appBar: PreferredSize( + preferredSize: Size.fromHeight(kToolbarHeight), + child: InkWell( + onTap: () => Navigator.push( + context, + MaterialPageRoute(builder: (context) => ChatInfoScreen( + chatId: widget.chatId, + name: widget.name, + imageUrl: widget.imageUrl, + chatType: widget.chatType) + ) + ), + child: AppBar( + backgroundColor: cs.surfaceContainerHigh, + foregroundColor: cs.onSurface, + elevation: 0, + surfaceTintColor: Colors.transparent, + iconTheme: IconThemeData(color: cs.onSurface), + leading: IconButton( + icon: const Icon(Symbols.arrow_back, weight: 400), + onPressed: () => Navigator.pop(context), ), - ], - ), - actions: [ - IconButton( - icon: const Icon(Symbols.call, weight: 400), - onPressed: () {}, + titleSpacing: 0, + title: Row( + children: [ + if (widget.imageUrl.isNotEmpty) + CircleAvatar( + radius: 18, + backgroundImage: NetworkImage(widget.imageUrl), + ) + else + CircleAvatar( + radius: 18, + backgroundColor: cs.primaryContainer, + child: Text( + widget.name.isNotEmpty ? widget.name[0].toUpperCase() : '?', + style: TextStyle(color: cs.onPrimaryContainer, fontSize: 12), + ), + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.name, + style: TextStyle( + color: cs.onSurface, + fontSize: 16, + fontWeight: FontWeight.w600, + fontFamily: 'Outfit', + ), + ), + Text( + status ?? "", + style: TextStyle( + color: cs.onSurfaceVariant, + fontSize: 12, + fontWeight: FontWeight.w400, + ), + ), + ], + ), + ), + ], + ), + actions: [ + IconButton( + icon: const Icon(Symbols.call, weight: 400), + onPressed: () {}, + ), + IconButton( + icon: const Icon(Symbols.more_vert, weight: 400), + onPressed: () {}, + ), + ], ), - IconButton( - icon: const Icon(Symbols.more_vert, weight: 400), - onPressed: () {}, - ), - ], - ), + )), body: Column( children: [ Expanded( diff --git a/lib/frontend/widgets/message_bubble.dart b/lib/frontend/widgets/message_bubble.dart index 1fc12c2..1217554 100644 --- a/lib/frontend/widgets/message_bubble.dart +++ b/lib/frontend/widgets/message_bubble.dart @@ -292,61 +292,67 @@ class MessageBubble extends StatelessWidget { String? senderAvatar = ContactCache.getAvatar(message.senderId); String? displaySender = ContactCache.get(message.senderId); - return Padding( - padding: EdgeInsets.only( - left: isMe ? 12 : 12, - right: isMe ? 12 : 12, - top: topMargin, - bottom: bottomMargin, - ), - child: Align( - child: Row( - mainAxisAlignment: isMe ? MainAxisAlignment.end : MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - if (!isMe && chatType == "CHAT" && nextMessage?.senderId != message.senderId && prevMessage?.senderId == message.senderId) - ...(senderAvatar != null && senderAvatar.isNotEmpty) - ? [ - CircleAvatar( - radius: 15, - backgroundImage: NetworkImage(senderAvatar), - backgroundColor: cs.primaryContainer, - ) - ] - : [ - CircleAvatar( - radius: 15, - backgroundColor: cs.primaryContainer, - child: Text( - displaySender != null && displaySender.isNotEmpty - ? displaySender[0].toUpperCase() - : '?', - style: TextStyle(fontSize: 9, color: cs.onPrimaryContainer), - ), - ) - ] - else if (!isMe && chatType != "CHAT") - SizedBox(width: 0) - else if (!isMe) - CircleAvatar(radius: 15, backgroundColor: Color(0x00000000)), - Container( - constraints: BoxConstraints( - maxWidth: MediaQuery.of(context).size.width * 0.75, + return GestureDetector( + // TODO: действия с сообщением + onTap: () => print("test"), + child: Padding( + padding: EdgeInsets.only( + left: isMe ? 12 : 12, + right: isMe ? 12 : 12, + top: topMargin, + bottom: bottomMargin, + ), + child: Align( + child: Row( + mainAxisAlignment: isMe ? MainAxisAlignment.end : MainAxisAlignment.start, + spacing: 8, + + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + if (!isMe && chatType == "CHAT" && nextMessage?.senderId != message.senderId && prevMessage?.senderId == message.senderId) + ...(senderAvatar != null && senderAvatar.isNotEmpty) + ? [ + CircleAvatar( + radius: 15, + backgroundImage: NetworkImage(senderAvatar), + backgroundColor: cs.primaryContainer, + ) + ] + : [ + CircleAvatar( + radius: 15, + backgroundColor: cs.primaryContainer, + child: Text( + displaySender != null && displaySender.isNotEmpty + ? displaySender[0].toUpperCase() + : '?', + style: TextStyle(fontSize: 9, color: cs.onPrimaryContainer), + ), + ) + ] + else if (!isMe && chatType != "CHAT") + SizedBox(width: 0) + else if (!isMe) + CircleAvatar(radius: 15, backgroundColor: Color(0x00000000)), + Container( + constraints: BoxConstraints( + maxWidth: MediaQuery.of(context).size.width * 0.75, + ), + decoration: BoxDecoration( + color: isMe + ? (isDark ? const Color(0xFF2C5F8D) : const Color(0xFF007AFF)) + : (isDark + ? cs.surfaceContainerHighest + : const Color(0xFFE9E9EB)), + borderRadius: _borderRadius, + ), + padding: padding, + child: _buildContent(context), ), - decoration: BoxDecoration( - color: isMe - ? (isDark ? const Color(0xFF2C5F8D) : const Color(0xFF007AFF)) - : (isDark - ? cs.surfaceContainerHighest - : const Color(0xFFE9E9EB)), - borderRadius: _borderRadius, - ), - padding: padding, - child: _buildContent(context), - ), - ], - ) - ), + ], + ) + ), + ) ); }