422 lines
21 KiB
Dart
422 lines
21 KiB
Dart
import 'dart:developer';
|
|
import 'package:flutter/gestures.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:lottie/lottie.dart';
|
|
import 'package:taafee_mobile/common/const/const.dart';
|
|
import 'package:taafee_mobile/common/extensions/widget_extension.dart';
|
|
import 'package:taafee_mobile/common/widgets/loader.dart';
|
|
import 'package:taafee_mobile/common/widgets/text.dart';
|
|
import 'package:taafee_mobile/features/chat/business%20logic%20layer/chat_controller.dart';
|
|
import 'package:taafee_mobile/features/chat/data_layer/model/message.dart';
|
|
import 'package:taafee_mobile/features/chat/presentation_layer/widgets/appbar.dart';
|
|
import 'package:taafee_mobile/features/chat/presentation_layer/widgets/chat_date_divider.dart';
|
|
import 'package:taafee_mobile/features/chat/presentation_layer/widgets/chat_footer.dart';
|
|
import '../../../../common/widgets/toast.dart';
|
|
import '../../data_layer/model/room.dart';
|
|
import '../widgets/message_widget.dart';
|
|
|
|
class ChatDetails extends StatelessWidget {
|
|
ChatDetails({super.key});
|
|
|
|
final FocusNode textFieldFocusNode = FocusNode();
|
|
|
|
final ChatController chatController = Get.find<ChatController>();
|
|
final KeyboardVisibilityController _keyboardVisibilityController =
|
|
KeyboardVisibilityController();
|
|
Room room = Get.arguments;
|
|
|
|
void loadMessages() {
|
|
if (chatController.currentRoom.value!.messages.page < 2) {
|
|
chatController.getCurrentRoomMessages();
|
|
}
|
|
}
|
|
|
|
void loadMoreMessages() {
|
|
chatController.scrollController.value.addListener(() {
|
|
if (chatController.scrollController.value.offset >
|
|
((chatController.currentRoom.value!.messages.length - 2) * 40)) {
|
|
chatController.getCurrentRoomMessages();
|
|
}
|
|
});
|
|
}
|
|
|
|
void handleKeyBoardChanges() {
|
|
_keyboardVisibilityController.onChange.listen((bool visible) {
|
|
chatController.setkeyBoardOpened(visible);
|
|
if (visible) {
|
|
// Keyboard is opened
|
|
|
|
log('Keyboard opened!');
|
|
} else {
|
|
// Keyboard is closed
|
|
log('Keyboard closed!');
|
|
}
|
|
});
|
|
}
|
|
|
|
void checkTablet() {
|
|
if (Responsive.isTablet()) {
|
|
Future.delayed(Duration(seconds: 2), () {
|
|
chatController.getCurrentRoomMessages();
|
|
});
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
loadMessages();
|
|
loadMoreMessages();
|
|
checkTablet();
|
|
handleKeyBoardChanges();
|
|
return WillPopScope(
|
|
onWillPop: () async {
|
|
if (room.type == RoomType.private) {
|
|
chatController.updateRoom();
|
|
}
|
|
return true;
|
|
},
|
|
child: Scaffold(
|
|
backgroundColor: AppColors.backGroundColor,
|
|
body: Stack(
|
|
children: [
|
|
Column(
|
|
children: [
|
|
AppBarChatWidget(
|
|
chatUser: room.user,
|
|
roomType: room.type,
|
|
avatar: room.user?.avatar,
|
|
),
|
|
Expanded(
|
|
child: SingleChildScrollView(
|
|
physics: NeverScrollableScrollPhysics(),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Obx(() {
|
|
return SizedBox(
|
|
height: (chatController.keyBoardOpened.value)
|
|
? (Responsive.isTablet())
|
|
? Get.height * 0.6
|
|
: Get.height * 0.5
|
|
: (Responsive.isTablet())
|
|
? Get.height * 0.9
|
|
: Get.height * 0.8,
|
|
child: Obx(() {
|
|
if (chatController.currentRoom.value!.messages
|
|
.data.isEmpty &&
|
|
chatController.messagesState.anyLoading) {
|
|
return Loader().center();
|
|
}
|
|
return Obx(() {
|
|
return ListView.separated(
|
|
separatorBuilder: ((context, index) {
|
|
if (index ==
|
|
chatController.currentRoom.value!
|
|
.messages.data.length -
|
|
1) {
|
|
return ChatDateDivider(
|
|
dateTime: chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index]
|
|
.createdAt
|
|
.toString()
|
|
.substring(0, 10));
|
|
}
|
|
if (index <=
|
|
chatController.currentRoom.value!
|
|
.messages.data.length -
|
|
1 &&
|
|
chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index]
|
|
.createdAt
|
|
.toString()
|
|
.substring(0, 10) !=
|
|
chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index + 1]
|
|
.createdAt
|
|
.toString()
|
|
.substring(0, 10)) {
|
|
return ChatDateDivider(
|
|
dateTime: chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index]
|
|
.createdAt
|
|
.toString()
|
|
.substring(0, 10));
|
|
}
|
|
|
|
return Container();
|
|
}),
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
controller:
|
|
chatController.scrollController.value,
|
|
reverse: true,
|
|
physics: const BouncingScrollPhysics(),
|
|
itemCount: chatController.currentRoom.value!
|
|
.messages.data.length +
|
|
1,
|
|
itemBuilder: (context, index) {
|
|
if (index >
|
|
chatController.currentRoom.value!
|
|
.messages.data.length -
|
|
1) {
|
|
return Container();
|
|
}
|
|
if (index == 0) {
|
|
return Obx(() {
|
|
return MessageWidget(
|
|
messageModel: chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index],
|
|
textFieldFocusNode:
|
|
textFieldFocusNode,
|
|
).paddingOnly(
|
|
right: (Responsive.isTablet() &&
|
|
chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index]
|
|
.direction ==
|
|
MessageDirection
|
|
.received)
|
|
? Get.width * 0.5
|
|
: 0,
|
|
left: (Responsive.isTablet() &&
|
|
chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index]
|
|
.direction ==
|
|
MessageDirection.sent)
|
|
? Get.width * 0.5
|
|
: 0,
|
|
bottom: (chatController
|
|
.keyBoardOpened.value)
|
|
? 100
|
|
: 50,
|
|
);
|
|
});
|
|
}
|
|
if (index ==
|
|
chatController.currentRoom.value!
|
|
.messages.data.length -
|
|
1) {
|
|
if (chatController
|
|
.messagesState.anyLoading) {
|
|
return Column(
|
|
children: [
|
|
Loader(),
|
|
Obx(() {
|
|
return MessageWidget(
|
|
messageModel: chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index],
|
|
textFieldFocusNode:
|
|
textFieldFocusNode,
|
|
).paddingOnly(
|
|
right: (Responsive
|
|
.isTablet() &&
|
|
chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index]
|
|
.direction ==
|
|
MessageDirection
|
|
.received)
|
|
? Get.width * 0.5
|
|
: 0,
|
|
left: (Responsive
|
|
.isTablet() &&
|
|
chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index]
|
|
.direction ==
|
|
MessageDirection
|
|
.sent)
|
|
? Get.width * 0.5
|
|
: 0,
|
|
top: 16,
|
|
);
|
|
}),
|
|
],
|
|
);
|
|
}
|
|
if (index ==
|
|
chatController.currentRoom.value!
|
|
.messages.data.length) {
|
|
return Container();
|
|
}
|
|
return Obx(() {
|
|
return MessageWidget(
|
|
messageModel: chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index],
|
|
textFieldFocusNode:
|
|
textFieldFocusNode,
|
|
).paddingOnly(
|
|
right: (Responsive.isTablet() &&
|
|
chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index]
|
|
.direction ==
|
|
MessageDirection
|
|
.received)
|
|
? Get.width * 0.5
|
|
: 0,
|
|
left: (Responsive.isTablet() &&
|
|
chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index]
|
|
.direction ==
|
|
MessageDirection.sent)
|
|
? Get.width * 0.5
|
|
: 0,
|
|
top: 16,
|
|
);
|
|
});
|
|
}
|
|
return Obx(() {
|
|
return MessageWidget(
|
|
messageModel: chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index],
|
|
textFieldFocusNode:
|
|
textFieldFocusNode,
|
|
).paddingOnly(
|
|
right: (Responsive.isTablet() &&
|
|
chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index]
|
|
.direction ==
|
|
MessageDirection.received)
|
|
? Get.width * 0.5
|
|
: 0,
|
|
left: (Responsive.isTablet() &&
|
|
chatController
|
|
.currentRoom
|
|
.value!
|
|
.messages
|
|
.data[index]
|
|
.direction ==
|
|
MessageDirection.sent)
|
|
? Get.width * 0.5
|
|
: 0,
|
|
);
|
|
});
|
|
});
|
|
});
|
|
}),
|
|
).paddingSymmetric(horizontal: 12);
|
|
}),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
Obx(() {
|
|
return Visibility(
|
|
visible: (chatController.currentRoom.value!.state ==
|
|
RoomState.active),
|
|
child: ChatFooterWidget(
|
|
focusNode: textFieldFocusNode,
|
|
),
|
|
);
|
|
}),
|
|
Obx(() {
|
|
return Visibility(
|
|
visible: (chatController.currentRoom.value!.state !=
|
|
RoomState.active),
|
|
child: Material(
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(16),
|
|
topRight: Radius.circular(16),
|
|
),
|
|
elevation: 15,
|
|
child: Container(
|
|
width: Get.width,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(16),
|
|
topRight: Radius.circular(16),
|
|
),
|
|
),
|
|
child: Column(
|
|
children: [
|
|
RegularTextWidget(
|
|
(room.state == RoomState.blocked)
|
|
? 'you_have_blocked_this_user'.tr
|
|
: 'this_user_has_blocked_you'.tr,
|
|
fontSize: 15,
|
|
),
|
|
Visibility(
|
|
visible: (room.state == RoomState.blocked),
|
|
child: TextButton(
|
|
onPressed: () {
|
|
if (chatController.connectionState.value ==
|
|
SocketConnectionState.connected) {
|
|
chatController.unblockRoom();
|
|
} else {
|
|
Toast.showToast(
|
|
'you_have_no_internet_connection'.tr);
|
|
}
|
|
},
|
|
child: Text('unblock'.tr),
|
|
)),
|
|
],
|
|
).paddingOnly(top: 12, bottom: 16),
|
|
),
|
|
),
|
|
);
|
|
})
|
|
],
|
|
).makeSafeArea(),
|
|
Obx(() {
|
|
return Visibility(
|
|
visible: (chatController.connectionState.value !=
|
|
SocketConnectionState.connected) &&
|
|
chatController
|
|
.currentRoom.value!.messages.data.isNotEmpty,
|
|
child: SizedBox(
|
|
width: 160,
|
|
height: 160,
|
|
child: Lottie.asset(
|
|
'assets/animations/Wifi Lottie.json')))
|
|
.align(alignment: Alignment.center);
|
|
}),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|