chat info not finished

This commit is contained in:
InviseDivine
2026-04-28 19:11:43 +02:00
parent 602c924503
commit 5db5dfabf5
3 changed files with 198 additions and 117 deletions
@@ -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<ChatInfoScreen> createState() => _ChatInfoScreenState();
}
class _ChatInfoScreenState extends State<ChatInfoScreen>{
@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),
),
],
),
),
);
}
}
+77 -63
View File
@@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:komet/backend/modules/chats.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 'package:material_symbols_icons/symbols.dart';
import '../../../main.dart'; import '../../../main.dart';
import '../../../backend/api.dart'; import '../../../backend/api.dart';
@@ -256,71 +257,84 @@ class _ChatScreenState extends State<ChatScreen>
String? status = chat?.type == "CHAT" ? "${chat?.participants.length.toString()} участников" : "last seen recently"; String? status = chat?.type == "CHAT" ? "${chat?.participants.length.toString()} участников" : "last seen recently";
return Scaffold( return Scaffold(
backgroundColor: cs.surface, backgroundColor: cs.surface,
appBar: AppBar( appBar: PreferredSize(
backgroundColor: cs.surfaceContainerHigh, preferredSize: Size.fromHeight(kToolbarHeight),
foregroundColor: cs.onSurface, child: InkWell(
elevation: 0, onTap: () => Navigator.push(
surfaceTintColor: Colors.transparent, context,
iconTheme: IconThemeData(color: cs.onSurface), MaterialPageRoute(builder: (context) => ChatInfoScreen(
leading: IconButton( chatId: widget.chatId,
icon: const Icon(Symbols.arrow_back, weight: 400), name: widget.name,
onPressed: () => Navigator.pop(context), imageUrl: widget.imageUrl,
), chatType: widget.chatType)
titleSpacing: 0, )
title: Row( ),
children: [ child: AppBar(
if (widget.imageUrl.isNotEmpty) backgroundColor: cs.surfaceContainerHigh,
CircleAvatar( foregroundColor: cs.onSurface,
radius: 18, elevation: 0,
backgroundImage: NetworkImage(widget.imageUrl), surfaceTintColor: Colors.transparent,
) iconTheme: IconThemeData(color: cs.onSurface),
else leading: IconButton(
CircleAvatar( icon: const Icon(Symbols.arrow_back, weight: 400),
radius: 18, onPressed: () => Navigator.pop(context),
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,
),
),
],
),
), ),
], titleSpacing: 0,
), title: Row(
actions: [ children: [
IconButton( if (widget.imageUrl.isNotEmpty)
icon: const Icon(Symbols.call, weight: 400), CircleAvatar(
onPressed: () {}, 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( body: Column(
children: [ children: [
Expanded( Expanded(
+60 -54
View File
@@ -292,61 +292,67 @@ class MessageBubble extends StatelessWidget {
String? senderAvatar = ContactCache.getAvatar(message.senderId); String? senderAvatar = ContactCache.getAvatar(message.senderId);
String? displaySender = ContactCache.get(message.senderId); String? displaySender = ContactCache.get(message.senderId);
return Padding( return GestureDetector(
padding: EdgeInsets.only( // TODO: действия с сообщением
left: isMe ? 12 : 12, onTap: () => print("test"),
right: isMe ? 12 : 12, child: Padding(
top: topMargin, padding: EdgeInsets.only(
bottom: bottomMargin, left: isMe ? 12 : 12,
), right: isMe ? 12 : 12,
child: Align( top: topMargin,
child: Row( bottom: bottomMargin,
mainAxisAlignment: isMe ? MainAxisAlignment.end : MainAxisAlignment.start, ),
crossAxisAlignment: CrossAxisAlignment.end, child: Align(
children: [ child: Row(
if (!isMe && chatType == "CHAT" && nextMessage?.senderId != message.senderId && prevMessage?.senderId == message.senderId) mainAxisAlignment: isMe ? MainAxisAlignment.end : MainAxisAlignment.start,
...(senderAvatar != null && senderAvatar.isNotEmpty) spacing: 8,
? [
CircleAvatar( crossAxisAlignment: CrossAxisAlignment.end,
radius: 15, children: [
backgroundImage: NetworkImage(senderAvatar), if (!isMe && chatType == "CHAT" && nextMessage?.senderId != message.senderId && prevMessage?.senderId == message.senderId)
backgroundColor: cs.primaryContainer, ...(senderAvatar != null && senderAvatar.isNotEmpty)
) ? [
] CircleAvatar(
: [ radius: 15,
CircleAvatar( backgroundImage: NetworkImage(senderAvatar),
radius: 15, backgroundColor: cs.primaryContainer,
backgroundColor: cs.primaryContainer, )
child: Text( ]
displaySender != null && displaySender.isNotEmpty : [
? displaySender[0].toUpperCase() CircleAvatar(
: '?', radius: 15,
style: TextStyle(fontSize: 9, color: cs.onPrimaryContainer), backgroundColor: cs.primaryContainer,
), child: Text(
) displaySender != null && displaySender.isNotEmpty
] ? displaySender[0].toUpperCase()
else if (!isMe && chatType != "CHAT") : '?',
SizedBox(width: 0) style: TextStyle(fontSize: 9, color: cs.onPrimaryContainer),
else if (!isMe) ),
CircleAvatar(radius: 15, backgroundColor: Color(0x00000000)), )
Container( ]
constraints: BoxConstraints( else if (!isMe && chatType != "CHAT")
maxWidth: MediaQuery.of(context).size.width * 0.75, 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),
),
],
)
),
); );
} }