forked from eatvio/eatvio_app
socket fixed
This commit is contained in:
@@ -2,13 +2,9 @@ import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
import 'package:dart_pusher_channels/dart_pusher_channels.dart';
|
||||
import 'package:easy_debounce/easy_debounce.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/image_compressing/image_compress_utility.dart';
|
||||
import 'package:eatvio_app/core/initialization_cubit/initialization_cubit.dart';
|
||||
import 'package:eatvio_app/core/initialization_cubit/initialization_state.dart';
|
||||
import 'package:eatvio_app/core/token_storage.dart';
|
||||
import 'package:eatvio_app/core/initialization_cubit/ws_manager.dart';
|
||||
import 'package:eatvio_app/features/chat/models/chat_message_model.dart';
|
||||
import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_state.dart';
|
||||
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
|
||||
@@ -16,41 +12,42 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
final ChatRepository chatRepository;
|
||||
final InitializationCubit initializationCubit;
|
||||
final WsManager wsManager;
|
||||
|
||||
int currentPage = 1;
|
||||
late final int lastPage;
|
||||
bool isLoading = false;
|
||||
|
||||
late final PusherChannelsClient client;
|
||||
late final PrivateChannel privateChatChannel;
|
||||
|
||||
ChatRoomCubit({
|
||||
required this.chatRepository,
|
||||
required this.initializationCubit,
|
||||
required this.wsManager,
|
||||
}) : super(ChatRoomState.loading());
|
||||
|
||||
loadNextPage(String chatId) async {
|
||||
if (currentPage < lastPage && !isLoading) {
|
||||
isLoading = true;
|
||||
|
||||
emit(ChatRoomState.loaded(
|
||||
chatRoom: (state as ChatRoomStateLoaded).chatRoom,
|
||||
chatMessages: (state as ChatRoomStateLoaded).chatMessages,
|
||||
isTyping: (state as ChatRoomStateLoaded).isTyping,
|
||||
isLoading: isLoading,
|
||||
),);
|
||||
emit(
|
||||
ChatRoomState.loaded(
|
||||
chatRoom: (state as ChatRoomStateLoaded).chatRoom,
|
||||
chatMessages: (state as ChatRoomStateLoaded).chatMessages,
|
||||
isTyping: (state as ChatRoomStateLoaded).isTyping,
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
|
||||
try {
|
||||
final chatMessages = await chatRepository.getChatMessages(chatId, currentPage + 1);
|
||||
|
||||
isLoading = false;
|
||||
emit(ChatRoomState.loaded(
|
||||
chatRoom: (state as ChatRoomStateLoaded).chatRoom,
|
||||
chatMessages: [...(state as ChatRoomStateLoaded).chatMessages, ...chatMessages.messagesList],
|
||||
isTyping: (state as ChatRoomStateLoaded).isTyping,
|
||||
isLoading: isLoading,
|
||||
),);
|
||||
emit(
|
||||
ChatRoomState.loaded(
|
||||
chatRoom: (state as ChatRoomStateLoaded).chatRoom,
|
||||
chatMessages: [...(state as ChatRoomStateLoaded).chatMessages, ...chatMessages.messagesList],
|
||||
isTyping: (state as ChatRoomStateLoaded).isTyping,
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
|
||||
currentPage++;
|
||||
} catch (e) {
|
||||
@@ -66,38 +63,29 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
final chatMessages = await chatRepository.getChatMessages(chatId, currentPage);
|
||||
lastPage = chatMessages.meta.lastPage;
|
||||
|
||||
await _subscribeToChatChannel(initCubit: initializationCubit, chatId: chatId);
|
||||
await _subscribeToChatChannel(chatId: chatId);
|
||||
|
||||
emit(ChatRoomState.loaded(
|
||||
chatRoom: chatRoom,
|
||||
chatMessages: chatMessages.messagesList,
|
||||
isTyping: false,
|
||||
isLoading: isLoading,
|
||||
),);
|
||||
emit(
|
||||
ChatRoomState.loaded(
|
||||
chatRoom: chatRoom,
|
||||
chatMessages: chatMessages.messagesList,
|
||||
isTyping: false,
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
emit(ChatRoomState.error(errorMessage: 'Ошибка получеия данных'));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _subscribeToChatChannel({
|
||||
required InitializationCubit initCubit,
|
||||
required String chatId,
|
||||
}) async {
|
||||
client = (initCubit.state as InitializationStateSuccess).client;
|
||||
|
||||
privateChatChannel = await client.privateChannel(
|
||||
'private-direct-chat.$chatId',
|
||||
authorizationDelegate: EndpointAuthorizableChannelTokenAuthorizationDelegate.forPrivateChannel(
|
||||
authorizationEndpoint: Uri.parse(baseUrl + '/broadcasting/auth'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer ${await TokenStorage.getTokenFromStorage()}',
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
privateChatChannel.subscribe();
|
||||
|
||||
privateChatChannel.bind('App\\Events\\ChatMessageUpdated').listen((event) {
|
||||
final client = wsManager.client;
|
||||
if (client == null) return;
|
||||
await wsManager.initPrivateDirectChatChannel(chatId);
|
||||
wsManager.subscribeDirectChatChannel();
|
||||
wsManager.directChatStream?.listen((event) {
|
||||
AudioPlayer().play((AssetSource('audio/recive_message.wav')));
|
||||
List<ChatMessageModel> messagesList = [
|
||||
ChatMessageModel.fromJson(jsonDecode(event.data)['message']),
|
||||
@@ -113,7 +101,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
);
|
||||
});
|
||||
|
||||
privateChatChannel.bind('client-typing').listen((event) {
|
||||
wsManager.clientTypingStream?.listen((event) {
|
||||
emit(
|
||||
ChatRoomState.loaded(
|
||||
chatRoom: (state as ChatRoomStateLoaded).chatRoom,
|
||||
@@ -152,7 +140,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
privateChatChannel.unsubscribe();
|
||||
wsManager.unsubscribeDirectChatChannel();
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart';
|
||||
@@ -78,6 +79,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
resizeToAvoidBottomInset: true,
|
||||
appBar: AppBar(
|
||||
titleSpacing: 0,
|
||||
backgroundColor: appTheme.gray100,
|
||||
centerTitle: false,
|
||||
title: Row(
|
||||
children: [
|
||||
@@ -136,7 +138,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
color: Color(0xFFF0F2F5),
|
||||
color: appTheme.whiteA700,
|
||||
width: double.maxFinite,
|
||||
child: CustomScrollView(
|
||||
physics: BouncingScrollPhysics(),
|
||||
@@ -149,20 +151,16 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) {
|
||||
if (index < state.chatMessages.length) {
|
||||
return Column(
|
||||
children: [
|
||||
if ((index + 1 != state.chatMessages.length &&
|
||||
DateTime.parse(state.chatMessages[index].updatedAt).day !=
|
||||
DateTime.parse(state.chatMessages[index + 1].updatedAt).day) ||
|
||||
index + 1 == state.chatMessages.length)
|
||||
_messageDate(state.chatMessages[index].updatedAt),
|
||||
ChatBubbleWidget(
|
||||
sendTime: state.chatMessages[index].updatedAt,
|
||||
text: state.chatMessages[index].data.trim(),
|
||||
isCurrentUser: state.chatRoom.users['to_chat_user']!.id != state.chatMessages[index].authorId,
|
||||
mediaData: state.chatMessages[index].mediaData ?? [],
|
||||
),
|
||||
],
|
||||
if ((index + 1 != state.chatMessages.length &&
|
||||
DateTime.parse(state.chatMessages[index].updatedAt).day != DateTime.parse(state.chatMessages[index + 1].updatedAt).day) ||
|
||||
index + 1 == state.chatMessages.length) {
|
||||
return _messageDate(state.chatMessages[index].updatedAt);
|
||||
}
|
||||
return ChatBubbleWidget(
|
||||
sendTime: state.chatMessages[index].updatedAt,
|
||||
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(
|
||||
@@ -181,13 +179,6 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: Colors.black.withValues(alpha: 0.1),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
@@ -231,57 +222,60 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
},
|
||||
customBorder: CircleBorder(),
|
||||
child: Ink(
|
||||
height: 32,
|
||||
width: 32,
|
||||
height: 40,
|
||||
width: 40,
|
||||
child: Transform.rotate(
|
||||
angle: 3.8,
|
||||
angle: pi / 4,
|
||||
child: Icon(
|
||||
Icons.attach_file_rounded,
|
||||
size: 24,
|
||||
size: 30,
|
||||
color: Color(0xFF858E99),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width - 96,
|
||||
child: TextFormField(
|
||||
controller: textEditingController,
|
||||
maxLines: 5,
|
||||
minLines: 1,
|
||||
keyboardType: TextInputType.multiline,
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w400, color: Colors.black, height: 1),
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
hintText: 'Сообщение',
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
height: 1,
|
||||
color: Color(0xFFAEAEB2),
|
||||
),
|
||||
filled: true,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFFD1D1D6),
|
||||
width: 1,
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextFormField(
|
||||
expands: true,
|
||||
controller: textEditingController,
|
||||
maxLines: null,
|
||||
minLines: null,
|
||||
keyboardType: TextInputType.multiline,
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w400, color: Colors.black, height: 1),
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
hintText: 'Сообщение',
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
height: 1,
|
||||
color: Color(0xFFAEAEB2),
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFFD1D1D6),
|
||||
width: 1,
|
||||
filled: true,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFFD1D1D6),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFFD1D1D6),
|
||||
width: 1,
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFFD1D1D6),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFFD1D1D6),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -306,11 +300,11 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
color: appTheme.blueA400,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
height: 32,
|
||||
width: 32,
|
||||
height: 40,
|
||||
width: 40,
|
||||
child: Icon(
|
||||
Icons.arrow_upward_rounded,
|
||||
size: 20,
|
||||
size: 24,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
@@ -326,16 +320,18 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
}
|
||||
|
||||
_messageDate(String date) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Text(
|
||||
DateFormat.MMMMd('RU').format(
|
||||
DateTime.parse(date),
|
||||
),
|
||||
style: const TextStyle(
|
||||
height: 1,
|
||||
color: Color(0xFF8393A1),
|
||||
fontWeight: FontWeight.w500,
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Text(
|
||||
DateFormat.yMMMMd('RU').format(
|
||||
DateTime.parse(date),
|
||||
),
|
||||
style: const TextStyle(
|
||||
height: 1,
|
||||
color: Color(0xFF8393A1),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:dismissible_page/dismissible_page.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/theme/custom_text_style.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/core/utils/date_time_utils.dart';
|
||||
import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -28,7 +30,7 @@ class ChatBubbleWidget extends StatelessWidget {
|
||||
alignment: isCurrentUser ? Alignment.centerRight : Alignment.centerLeft,
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: isCurrentUser ? Color(0xFF7F9CF5) : Colors.white,
|
||||
color: isCurrentUser ? appTheme.gray50 : appTheme.gray60004,
|
||||
borderRadius: mediaData.length > 0
|
||||
? BorderRadius.circular(24)
|
||||
: BorderRadius.horizontal(
|
||||
@@ -108,15 +110,15 @@ class ChatBubbleWidget extends StatelessWidget {
|
||||
if (text.isNotEmpty)
|
||||
Text(
|
||||
text,
|
||||
style: TextStyle(color: isCurrentUser ? Colors.white : Color(0xFF323F4B), height: 1),
|
||||
style: TextStyles.textFS13FW400.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
SizedBox(height: 8),
|
||||
Padding(
|
||||
padding: mediaData.length > 0 ? const EdgeInsets.only(right: 8, top: 4, left: 8) : EdgeInsets.zero,
|
||||
child: Text(
|
||||
DateTime.parse(sendTime).format('hh:mm'),
|
||||
style: TextStyle(
|
||||
color: isCurrentUser ? Colors.white.withValues(alpha: 0.4) : Color(0xFF323F4B).withValues(alpha: 0.4),
|
||||
color: Color(0xFF7B8794),
|
||||
height: 1,
|
||||
fontSize: 10,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user