INFRA: Set Up Project.
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
import 'package:customer/models/conversation_model.dart';
|
||||
|
||||
class ChatVideoContainer {
|
||||
Url videoUrl;
|
||||
|
||||
String thumbnailUrl;
|
||||
|
||||
ChatVideoContainer({required this.videoUrl, required this.thumbnailUrl});
|
||||
}
|
||||
310
lib/screen_ui/multi_vendor_service/chat_screens/chat_screen.dart
Normal file
310
lib/screen_ui/multi_vendor_service/chat_screens/chat_screen.dart
Normal file
@@ -0,0 +1,310 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:customer/constant/constant.dart';
|
||||
import 'package:customer/controllers/chat_controller.dart';
|
||||
import 'package:customer/models/conversation_model.dart';
|
||||
import 'package:customer/themes/app_them_data.dart';
|
||||
import '../../../controllers/theme_controller.dart';
|
||||
import 'package:customer/utils/network_image_widget.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import '../../../service/fire_store_utils.dart';
|
||||
import '../../../widget/firebase_pagination/src/fireStore_pagination.dart';
|
||||
import '../../../widget/firebase_pagination/src/models/view_type.dart';
|
||||
import 'ChatVideoContainer.dart';
|
||||
import 'full_screen_image_viewer.dart';
|
||||
import 'full_screen_video_viewer.dart';
|
||||
|
||||
class ChatScreen extends StatelessWidget {
|
||||
const ChatScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final isDark = themeController.isDark.value;
|
||||
return GetX(
|
||||
init: ChatController(),
|
||||
builder: (controller) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
|
||||
centerTitle: false,
|
||||
titleSpacing: 0,
|
||||
title: Text(
|
||||
controller.restaurantName.value,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontFamily: AppThemeData.medium, fontSize: 16, color: isDark ? AppThemeData.grey50 : AppThemeData.grey900),
|
||||
),
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
FocusScope.of(context).unfocus();
|
||||
},
|
||||
child: FirestorePagination(
|
||||
controller: controller.scrollController,
|
||||
physics: const BouncingScrollPhysics(),
|
||||
itemBuilder: (context, documentSnapshots, index) {
|
||||
ConversationModel inboxModel = ConversationModel.fromJson(documentSnapshots[index].data() as Map<String, dynamic>);
|
||||
return chatItemView(isDark, inboxModel.senderId == FireStoreUtils.getCurrentUid(), inboxModel);
|
||||
},
|
||||
onEmpty: Constant.showEmptyView(message: "No Conversion found".tr),
|
||||
// orderBy is compulsory to enable pagination
|
||||
query: FirebaseFirestore.instance
|
||||
.collection(
|
||||
controller.chatType.value == "Driver"
|
||||
? 'chat_driver'
|
||||
: controller.chatType.value == "Provider" || controller.chatType.value == "provider"
|
||||
? 'chat_provider'
|
||||
: controller.chatType.value == "worker" || controller.chatType.value == "Worker"
|
||||
? 'chat_worker'
|
||||
: 'chat_store',
|
||||
)
|
||||
.doc(controller.orderId.value)
|
||||
.collection("thread")
|
||||
.orderBy('createdAt', descending: false),
|
||||
isLive: true,
|
||||
viewType: ViewType.list,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
color: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
onCameraClick(context, controller);
|
||||
},
|
||||
child: SvgPicture.asset("assets/icons/ic_picture_one.svg"),
|
||||
),
|
||||
Flexible(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
child: TextField(
|
||||
textInputAction: TextInputAction.send,
|
||||
keyboardType: TextInputType.text,
|
||||
textCapitalization: TextCapitalization.sentences,
|
||||
controller: controller.messageController.value,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: const EdgeInsets.only(top: 3, left: 10),
|
||||
focusedBorder: InputBorder.none,
|
||||
enabledBorder: InputBorder.none,
|
||||
hintText: 'Type message here....'.tr,
|
||||
),
|
||||
onSubmitted: (value) async {
|
||||
if (controller.messageController.value.text.isNotEmpty) {
|
||||
controller.sendMessage(controller.messageController.value.text, null, '', 'text');
|
||||
Timer(const Duration(milliseconds: 500), () => controller.scrollController.jumpTo(controller.scrollController.position.maxScrollExtent));
|
||||
controller.messageController.value.clear();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
if (controller.messageController.value.text.isNotEmpty) {
|
||||
controller.sendMessage(controller.messageController.value.text, null, '', 'text');
|
||||
controller.messageController.value.clear();
|
||||
// Timer(const Duration(milliseconds: 500), () => controller.scrollController.jumpTo(controller.scrollController.position.maxScrollExtent));
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(left: 10),
|
||||
decoration: BoxDecoration(color: isDark ? AppThemeData.grey700 : AppThemeData.grey200, borderRadius: BorderRadius.circular(30)),
|
||||
child: Padding(padding: const EdgeInsets.all(10), child: SvgPicture.asset("assets/icons/ic_send.svg")),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget chatItemView(isDark, bool isMe, ConversationModel data) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
|
||||
child:
|
||||
isMe
|
||||
? Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
data.messageType == "text"
|
||||
? Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12), bottomLeft: Radius.circular(12)),
|
||||
color: AppThemeData.primary300,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
child: Text(data.message.toString(), style: const TextStyle(fontFamily: AppThemeData.medium, fontSize: 16, color: AppThemeData.grey50)),
|
||||
)
|
||||
: data.messageType == "image"
|
||||
? ClipRRect(
|
||||
borderRadius: const BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12), bottomLeft: Radius.circular(12)),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Get.to(FullScreenImageViewer(imageUrl: data.url!.url));
|
||||
},
|
||||
child: Hero(tag: data.url!.url, child: NetworkImageWidget(imageUrl: data.url!.url, height: 100, width: 100, fit: BoxFit.cover)),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: FloatingActionButton(
|
||||
mini: true,
|
||||
heroTag: data.id,
|
||||
backgroundColor: AppThemeData.primary300,
|
||||
onPressed: () {
|
||||
Get.to(FullScreenVideoViewer(heroTag: data.id.toString(), videoUrl: data.url!.url));
|
||||
},
|
||||
child: const Icon(Icons.play_arrow, color: Colors.white),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
DateFormat('MMM d, yyyy hh:mm aa').format(DateTime.fromMillisecondsSinceEpoch(data.createdAt!.millisecondsSinceEpoch)),
|
||||
style: const TextStyle(color: Colors.grey, fontSize: 12),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
data.messageType == "text"
|
||||
? Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12), bottomRight: Radius.circular(12)),
|
||||
color: isDark ? AppThemeData.grey700 : AppThemeData.grey200,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
child: Text(data.message.toString(), style: TextStyle(fontFamily: AppThemeData.medium, fontSize: 16, color: isDark ? AppThemeData.grey100 : AppThemeData.grey800)),
|
||||
)
|
||||
: data.messageType == "image"
|
||||
? ConstrainedBox(
|
||||
constraints: const BoxConstraints(minWidth: 50, maxWidth: 200),
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12), bottomRight: Radius.circular(12)),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Get.to(FullScreenImageViewer(imageUrl: data.url!.url));
|
||||
},
|
||||
child: Hero(tag: data.url!.url, child: NetworkImageWidget(imageUrl: data.url!.url)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: FloatingActionButton(
|
||||
mini: true,
|
||||
heroTag: data.id,
|
||||
backgroundColor: AppThemeData.primary300,
|
||||
onPressed: () {
|
||||
Get.to(FullScreenVideoViewer(heroTag: data.id.toString(), videoUrl: data.url!.url));
|
||||
},
|
||||
child: const Icon(Icons.play_arrow, color: Colors.white),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
DateFormat('MMM d, yyyy hh:mm aa').format(DateTime.fromMillisecondsSinceEpoch(data.createdAt!.millisecondsSinceEpoch)),
|
||||
style: const TextStyle(color: Colors.grey, fontSize: 12),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void onCameraClick(BuildContext context, ChatController controller) {
|
||||
final action = CupertinoActionSheet(
|
||||
message: Text('Send Media'.tr, style: const TextStyle(fontSize: 15.0)),
|
||||
actions: <Widget>[
|
||||
CupertinoActionSheetAction(
|
||||
isDefaultAction: false,
|
||||
onPressed: () async {
|
||||
Get.back();
|
||||
XFile? image = await controller.imagePicker.pickImage(source: ImageSource.gallery);
|
||||
if (image != null) {
|
||||
Url url = await FireStoreUtils.uploadChatImageToFireStorage(File(image.path), context);
|
||||
controller.sendMessage('', url, '', 'image');
|
||||
}
|
||||
},
|
||||
child: Text("Choose image from gallery".tr),
|
||||
),
|
||||
CupertinoActionSheetAction(
|
||||
isDefaultAction: false,
|
||||
onPressed: () async {
|
||||
Get.back();
|
||||
XFile? galleryVideo = await controller.imagePicker.pickVideo(source: ImageSource.gallery);
|
||||
if (galleryVideo != null) {
|
||||
ChatVideoContainer? videoContainer = await FireStoreUtils.uploadChatVideoToFireStorage(context, File(galleryVideo.path));
|
||||
if (videoContainer != null) {
|
||||
controller.sendMessage('', videoContainer.videoUrl, videoContainer.thumbnailUrl, 'video');
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Text("Choose video from gallery".tr),
|
||||
),
|
||||
CupertinoActionSheetAction(
|
||||
isDestructiveAction: false,
|
||||
onPressed: () async {
|
||||
Get.back();
|
||||
XFile? image = await controller.imagePicker.pickImage(source: ImageSource.camera);
|
||||
if (image != null) {
|
||||
Url url = await FireStoreUtils.uploadChatImageToFireStorage(File(image.path), context);
|
||||
controller.sendMessage('', url, '', 'image');
|
||||
}
|
||||
},
|
||||
child: Text("Take a picture".tr),
|
||||
),
|
||||
// CupertinoActionSheetAction(
|
||||
// isDestructiveAction: false,
|
||||
// onPressed: () async {
|
||||
// Get.back();
|
||||
// XFile? recordedVideo = await controller.imagePicker.pickVideo(source: ImageSource.camera);
|
||||
// if (recordedVideo != null) {
|
||||
// ChatVideoContainer videoContainer = await FireStoreUtils.uploadChatVideoToFireStorage(File(recordedVideo.path), context);
|
||||
// controller.sendMessage('', videoContainer.videoUrl, videoContainer.thumbnailUrl, 'video');
|
||||
// }
|
||||
// },
|
||||
// child: Text("Record video".tr),
|
||||
// )
|
||||
],
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
child: Text('Cancel'.tr),
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
),
|
||||
);
|
||||
showCupertinoModalPopup(context: context, builder: (context) => action);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:customer/constant/constant.dart';
|
||||
import 'package:customer/models/inbox_model.dart';
|
||||
import 'package:customer/models/user_model.dart';
|
||||
import 'package:customer/themes/app_them_data.dart';
|
||||
import 'package:customer/themes/responsive.dart';
|
||||
import 'package:customer/utils/network_image_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../../controllers/theme_controller.dart';
|
||||
import '../../../service/fire_store_utils.dart';
|
||||
import '../../../themes/show_toast_dialog.dart';
|
||||
import '../../../widget/firebase_pagination/src/fireStore_pagination.dart';
|
||||
import '../../../widget/firebase_pagination/src/models/view_type.dart';
|
||||
import 'chat_screen.dart';
|
||||
|
||||
class DriverInboxScreen extends StatelessWidget {
|
||||
const DriverInboxScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final isDark = themeController.isDark.value;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
|
||||
centerTitle: false,
|
||||
titleSpacing: 0,
|
||||
title: Text("Driver Inbox".tr, textAlign: TextAlign.start, style: TextStyle(fontFamily: AppThemeData.medium, fontSize: 16, color: isDark ? AppThemeData.grey50 : AppThemeData.grey900)),
|
||||
),
|
||||
body: FirestorePagination(
|
||||
//item builder type is compulsory.
|
||||
physics: const BouncingScrollPhysics(),
|
||||
itemBuilder: (context, documentSnapshots, index) {
|
||||
final data = documentSnapshots[index].data() as Map<String, dynamic>?;
|
||||
InboxModel inboxModel = InboxModel.fromJson(data!);
|
||||
return InkWell(
|
||||
onTap: () async {
|
||||
ShowToastDialog.showLoader("Please wait...".tr);
|
||||
|
||||
UserModel? customer = await FireStoreUtils.getUserProfile(inboxModel.customerId.toString());
|
||||
UserModel? restaurantUser = await FireStoreUtils.getUserProfile(inboxModel.restaurantId.toString());
|
||||
ShowToastDialog.closeLoader();
|
||||
|
||||
Get.to(
|
||||
const ChatScreen(),
|
||||
arguments: {
|
||||
"customerName": customer!.fullName(),
|
||||
"restaurantName": restaurantUser!.fullName(),
|
||||
"orderId": inboxModel.orderId,
|
||||
"restaurantId": restaurantUser.id,
|
||||
"customerId": customer.id,
|
||||
"customerProfileImage": customer.profilePictureURL,
|
||||
"restaurantProfileImage": restaurantUser.profilePictureURL,
|
||||
"token": restaurantUser.fcmToken,
|
||||
"chatType": inboxModel.chatType,
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 5),
|
||||
child: Container(
|
||||
decoration: ShapeDecoration(color: isDark ? AppThemeData.grey900 : AppThemeData.grey50, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8))),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
||||
child: NetworkImageWidget(
|
||||
imageUrl: inboxModel.restaurantProfileImage.toString(),
|
||||
fit: BoxFit.cover,
|
||||
height: Responsive.height(6, context),
|
||||
width: Responsive.width(12, context),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
"${inboxModel.restaurantName}",
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontFamily: AppThemeData.semiBold, fontSize: 16, color: isDark ? AppThemeData.grey100 : AppThemeData.grey800),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
Constant.timestampToDate(inboxModel.createdAt!),
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontFamily: AppThemeData.regular, fontSize: 16, color: isDark ? AppThemeData.grey400 : AppThemeData.grey500),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
"${inboxModel.lastMessage}",
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontFamily: AppThemeData.medium, fontSize: 14, color: isDark ? AppThemeData.grey200 : AppThemeData.grey700),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
shrinkWrap: true,
|
||||
onEmpty: Constant.showEmptyView(message: "No Conversion found".tr),
|
||||
// orderBy is compulsory to enable pagination
|
||||
query: FirebaseFirestore.instance.collection('chat_driver').where("customerId", isEqualTo: FireStoreUtils.getCurrentUid()).orderBy('createdAt', descending: true),
|
||||
//Change types customerId
|
||||
viewType: ViewType.list,
|
||||
initialLoader: Constant.loader(),
|
||||
// to fetch real-time data
|
||||
isLive: true,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
|
||||
class FullScreenImageViewer extends StatelessWidget {
|
||||
final String imageUrl;
|
||||
final File? imageFile;
|
||||
|
||||
const FullScreenImageViewer({super.key, required this.imageUrl, this.imageFile});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
elevation: 0.0,
|
||||
backgroundColor: Colors.black,
|
||||
iconTheme: const IconThemeData(color: Colors.white),
|
||||
systemOverlayStyle: SystemUiOverlayStyle.light,
|
||||
),
|
||||
body: Container(
|
||||
color: Colors.black,
|
||||
child: Hero(
|
||||
tag: imageUrl,
|
||||
child: PhotoView(
|
||||
imageProvider: imageFile == null ? NetworkImage(imageUrl) : Image.file(imageFile!).image,
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
|
||||
class FullScreenVideoViewer extends StatefulWidget {
|
||||
final String videoUrl;
|
||||
final String heroTag;
|
||||
final File? videoFile;
|
||||
|
||||
const FullScreenVideoViewer({super.key, required this.videoUrl, required this.heroTag, this.videoFile});
|
||||
|
||||
@override
|
||||
_FullScreenVideoViewerState createState() => _FullScreenVideoViewerState();
|
||||
}
|
||||
|
||||
class _FullScreenVideoViewerState extends State<FullScreenVideoViewer> {
|
||||
late VideoPlayerController _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = widget.videoFile == null ? VideoPlayerController.networkUrl(Uri.parse(widget.videoUrl)) : VideoPlayerController.file(widget.videoFile!)
|
||||
..initialize().then((_) {
|
||||
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
|
||||
setState(() {});
|
||||
});
|
||||
_controller.setLooping(true);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
elevation: 0.0,
|
||||
backgroundColor: Colors.black,
|
||||
iconTheme: const IconThemeData(color: Colors.white),
|
||||
systemOverlayStyle: SystemUiOverlayStyle.light,
|
||||
),
|
||||
body: Container(
|
||||
color: Colors.black,
|
||||
child: Hero(
|
||||
tag: widget.videoUrl,
|
||||
child: Center(
|
||||
child: _controller.value.isInitialized
|
||||
? AspectRatio(
|
||||
aspectRatio: _controller.value.aspectRatio,
|
||||
child: VideoPlayer(_controller),
|
||||
)
|
||||
: Container(),
|
||||
),
|
||||
)),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
heroTag: widget.heroTag,
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_controller.value.isPlaying ? _controller.pause() : _controller.play();
|
||||
});
|
||||
},
|
||||
child: Icon(
|
||||
_controller.value.isPlaying ? CupertinoIcons.pause : CupertinoIcons.play_arrow_solid,
|
||||
),
|
||||
),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
_controller.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:customer/constant/constant.dart';
|
||||
import 'package:customer/models/inbox_model.dart';
|
||||
import 'package:customer/models/user_model.dart';
|
||||
import 'package:customer/models/vendor_model.dart';
|
||||
import 'package:customer/themes/app_them_data.dart';
|
||||
import 'package:customer/themes/responsive.dart';
|
||||
import 'package:customer/utils/network_image_widget.dart';
|
||||
import 'package:customer/widget/firebase_pagination/src/fireStore_pagination.dart';
|
||||
import 'package:customer/widget/firebase_pagination/src/models/view_type.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../../controllers/theme_controller.dart';
|
||||
import '../../../service/fire_store_utils.dart';
|
||||
import '../../../themes/show_toast_dialog.dart';
|
||||
import 'chat_screen.dart';
|
||||
|
||||
class RestaurantInboxScreen extends StatelessWidget {
|
||||
const RestaurantInboxScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final isDark = themeController.isDark.value;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: isDark ? AppThemeData.surfaceDark : AppThemeData.surface,
|
||||
centerTitle: false,
|
||||
titleSpacing: 0,
|
||||
title: Text("Store Inbox".tr, textAlign: TextAlign.start, style: TextStyle(fontFamily: AppThemeData.medium, fontSize: 16, color: isDark ? AppThemeData.grey50 : AppThemeData.grey900)),
|
||||
),
|
||||
body: FirestorePagination(
|
||||
//item builder type is compulsory.
|
||||
physics: const BouncingScrollPhysics(),
|
||||
itemBuilder: (context, documentSnapshots, index) {
|
||||
final data = documentSnapshots[index].data() as Map<String, dynamic>?;
|
||||
InboxModel inboxModel = InboxModel.fromJson(data!);
|
||||
return InkWell(
|
||||
onTap: () async {
|
||||
ShowToastDialog.showLoader("Please wait...".tr);
|
||||
|
||||
UserModel? customer = await FireStoreUtils.getUserProfile(inboxModel.customerId.toString());
|
||||
UserModel? restaurantUser = await FireStoreUtils.getUserProfile(inboxModel.restaurantId.toString());
|
||||
VendorModel? vendorModel = await FireStoreUtils.getVendorById(restaurantUser!.vendorID.toString());
|
||||
ShowToastDialog.closeLoader();
|
||||
|
||||
Get.to(
|
||||
const ChatScreen(),
|
||||
arguments: {
|
||||
"customerName": customer!.fullName(),
|
||||
"restaurantName": vendorModel!.title,
|
||||
"orderId": inboxModel.orderId,
|
||||
"restaurantId": restaurantUser.id,
|
||||
"customerId": customer.id,
|
||||
"customerProfileImage": customer.profilePictureURL,
|
||||
"restaurantProfileImage": vendorModel.photo,
|
||||
"token": restaurantUser.fcmToken,
|
||||
"chatType": inboxModel.chatType,
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 5),
|
||||
child: Container(
|
||||
decoration: ShapeDecoration(color: isDark ? AppThemeData.grey900 : AppThemeData.grey50, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8))),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
||||
child: NetworkImageWidget(
|
||||
imageUrl: inboxModel.restaurantProfileImage.toString(),
|
||||
fit: BoxFit.cover,
|
||||
height: Responsive.height(6, context),
|
||||
width: Responsive.width(12, context),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
"${inboxModel.restaurantName}",
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontFamily: AppThemeData.semiBold, fontSize: 16, color: isDark ? AppThemeData.grey100 : AppThemeData.grey800),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
Constant.timestampToDate(inboxModel.createdAt!),
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontFamily: AppThemeData.regular, fontSize: 16, color: isDark ? AppThemeData.grey400 : AppThemeData.grey500),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
"${inboxModel.lastMessage}",
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontFamily: AppThemeData.medium, fontSize: 14, color: isDark ? AppThemeData.grey200 : AppThemeData.grey700),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
shrinkWrap: true,
|
||||
onEmpty: Constant.showEmptyView(message: "No Conversion found".tr),
|
||||
// orderBy is compulsory to enable pagination
|
||||
query: FirebaseFirestore.instance.collection('chat_store').where("customerId", isEqualTo: FireStoreUtils.getCurrentUid()).orderBy('createdAt', descending: true),
|
||||
//Change types customerId
|
||||
viewType: ViewType.list,
|
||||
initialLoader: Constant.loader(),
|
||||
// to fetch real-time data
|
||||
isLive: true,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user