Files
eatvio_app_old/lib/features/chat/presentation/pages/chat_screen.dart
2024-07-09 17:50:32 +03:00

253 lines
9.4 KiB
Dart

import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart';
import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_state.dart';
import 'package:eatvio_app/features/chat/presentation/widgets/chat_bubble_widget.dart';
import 'package:eatvio_app/locator_service.dart';
import 'package:flutter/cupertino.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:flutter/material.dart';
import 'package:lazy_load_scrollview/lazy_load_scrollview.dart';
class ChatScreen extends StatefulWidget {
final String chatId;
const ChatScreen({
required this.chatId,
super.key,
});
@override
State<ChatScreen> createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
final scrollController = ScrollController();
final TextEditingController textEditingController = TextEditingController();
Widget build(BuildContext context) {
return BlocProvider<ChatRoomCubit>(
create: (BuildContext context) => sl()..initChat(widget.chatId),
child: BlocBuilder<ChatRoomCubit, ChatRoomState>(
builder: (context, state) {
if (state is ChatRoomStateLoaded) {
return _buildChat(context, state);
} else if (state is ChatRoomStateError) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text(state.errorMessage),
),
);
} else {
return Scaffold(
body: Center(
child: CupertinoActivityIndicator(),
),
);
}
},
),
);
}
_buildChat(BuildContext context, ChatRoomStateLoaded state) {
return Scaffold(
resizeToAvoidBottomInset: true,
backgroundColor: PrimaryColors().gray50,
appBar: AppBar(
titleSpacing: 0,
centerTitle: false,
backgroundColor: Colors.white,
forceMaterialTransparency: true,
elevation: 0,
title: Row(
children: [
Container(
width: 40,
height: 40,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Color(0xFFEBF4FF),
shape: BoxShape.circle,
),
child: Text(
state.chatRoom.users['to_chat_user']!.name.split(' ').first[0] + state.chatRoom.users['to_chat_user']!.name.split(' ')[1][0],
style: TextStyle(
color: Color(0xFF7F9CF5),
fontWeight: FontWeight.w400,
fontSize: 20,
),
),
),
SizedBox(width: 16),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
state.chatRoom.users['to_chat_user']!.name,
style: CustomTextStyles.titleSmallBold.copyWith(
color: PrimaryColors().blueGray800,
),
),
AnimatedCrossFade(
firstChild: Text(
'Печатает...',
style: CustomTextStyles.bodySmallMulishPrimary,
),
firstCurve: Curves.easeIn,
secondCurve: Curves.easeOut,
secondChild: const SizedBox.shrink(),
crossFadeState: state.isTyping ? CrossFadeState.showFirst : CrossFadeState.showSecond,
duration: Duration(milliseconds: 150),
),
],
),
],
),
),
body: SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: Container(
color: Color(0xFFF0F2F5),
width: double.maxFinite,
child: LazyLoadScrollView(
onEndOfPage: () => context.read<ChatRoomCubit>().loadNextPage(widget.chatId),
isLoading: state.isLoading,
scrollOffset: MediaQuery.of(context).size.height.toInt(),
child: CustomScrollView(
physics: BouncingScrollPhysics(),
controller: scrollController,
reverse: true,
slivers: [
SliverPadding(
padding: EdgeInsets.symmetric(vertical: 16),
sliver: SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
if (index < state.chatMessages.length) {
return ChatBubbleWidget(
text: state.chatMessages[index].data.trim(),
isCurrentUser: state.chatRoom.users['to_chat_user']!.id != state.chatMessages[index].authorId,
mediaData: state.chatMessages[index].mediaData ?? [],
);
} else {
return Padding(
padding: const EdgeInsets.all(8),
child: Center(child: CupertinoActivityIndicator()),
);
}
},
childCount: state.chatMessages.length + (state.isLoading ? 1 : 0),
),
),
),
],
),
),
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 8),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(width: 8),
InkWell(
onTap: () {
},
borderRadius: BorderRadiusStyle.circleBorder17,
child: Ink(
height: 32,
width: 32,
child: Icon(
Icons.attach_file_rounded,
size: 28,
color: Color(0xFF858E99),
),
),
),
SizedBox(width: 8),
SizedBox(
width: mediaQueryData.size.width - 96,
child: TextFormField(
controller: textEditingController,
maxLines: 5,
minLines: 1,
keyboardType: TextInputType.multiline,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: Colors.black,
),
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 4),
hintText: 'Сообщение',
hintStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: Color(0xFFAEAEB2),
),
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadiusStyle.circleBorder17,
borderSide: BorderSide(
color: Color(0xFFD1D1D6),
width: 1,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadiusStyle.circleBorder17,
borderSide: BorderSide(
color: Color(0xFFD1D1D6),
width: 1,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadiusStyle.circleBorder17,
borderSide: BorderSide(
color: Color(0xFFD1D1D6),
width: 1,
),
),
),
),
),
SizedBox(width: 8),
InkWell(
borderRadius: BorderRadiusStyle.circleBorder17,
onTap: () {
if (textEditingController.text.isNotEmpty) {
context.read<ChatRoomCubit>().sendMessage(
chatId: widget.chatId,
data: textEditingController.text.trim(),
filesList: [],
);
setState(() {
textEditingController.clear();
});
}
},
child: Ink(
height: 32,
width: 32,
child: Icon(
Icons.send_outlined,
size: 28,
color: Color(0xFF858E99),
),
),
),
SizedBox(width: 8),
],
),
),
],
),
),
);
}
}