taafee-mobile/lib/features/chat/presentation_layer/screens/chat_details.dart
2023-10-25 11:25:44 +03:00

424 lines
22 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';
// ignore: must_be_immutable
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['room'];
void Function()? onBack = Get.arguments['onBack'];
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(const 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,
onBack: onBack,
),
Expanded(
child: SingleChildScrollView(
physics: const 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: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
elevation: 15,
child: Container(
width: Get.width,
decoration: const 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.json')))
.align(alignment: Alignment.center);
}),
],
),
),
);
}
}