You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
398 lines
18 KiB
Dart
398 lines
18 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:easy_localization/easy_localization.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
|
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart';
|
|
import 'package:mohem_flutter_app/app_state/app_state.dart';
|
|
import 'package:mohem_flutter_app/classes/colors.dart';
|
|
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
|
|
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
|
|
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
|
|
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
|
|
import 'package:mohem_flutter_app/models/chat/call.dart';
|
|
import 'package:mohem_flutter_app/ui/chat/call/chat_outgoing_call_screen.dart';
|
|
import 'package:mohem_flutter_app/ui/chat/chat_bubble.dart';
|
|
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
|
|
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
|
import 'package:swipe_to/swipe_to.dart';
|
|
|
|
class ChatDetailScreen extends StatefulWidget {
|
|
// ignore: prefer_const_constructors_in_immutables
|
|
ChatDetailScreen({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<ChatDetailScreen> createState() => _ChatDetailScreenState();
|
|
}
|
|
|
|
class _ChatDetailScreenState extends State<ChatDetailScreen> {
|
|
dynamic userDetails;
|
|
late ChatProviderModel data;
|
|
final RefreshController _rc = RefreshController(initialRefresh: false);
|
|
|
|
void getMoreChat() async {
|
|
if (userDetails != null) {
|
|
data.paginationVal = data.paginationVal + 10;
|
|
if (userDetails != null)
|
|
data.getSingleUserChatHistory(
|
|
senderUID: AppState().chatDetails!.response!.id!.toInt(),
|
|
receiverUID: userDetails["targetUser"].id,
|
|
loadMore: true,
|
|
isNewChat: false,
|
|
);
|
|
}
|
|
await Future.delayed(
|
|
const Duration(
|
|
milliseconds: 1000,
|
|
),
|
|
);
|
|
_rc.loadComplete();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
userDetails = ModalRoute.of(context)!.settings.arguments;
|
|
data = Provider.of<ChatProviderModel>(context, listen: false);
|
|
if (userDetails != null)
|
|
data.getSingleUserChatHistory(
|
|
senderUID: AppState().chatDetails!.response!.id!.toInt(),
|
|
receiverUID: userDetails["targetUser"].id,
|
|
loadMore: false,
|
|
isNewChat: userDetails["isNewChat"],
|
|
);
|
|
|
|
return Scaffold(
|
|
backgroundColor: const Color(0xFFF8F8F8),
|
|
appBar: AppBarWidget(context,
|
|
title: userDetails["targetUser"].userName.toString().replaceAll(".", " ").capitalizeFirstofEach,
|
|
showHomeButton: false,
|
|
image: userDetails["targetUser"].image,
|
|
actions: [
|
|
IconButton(
|
|
onPressed: () {
|
|
makeCall("AUDIO");
|
|
},
|
|
icon: SvgPicture.asset(
|
|
"assets/icons/chat/call.svg",
|
|
width: 22,
|
|
height: 22,
|
|
),
|
|
),
|
|
IconButton(
|
|
onPressed: () {
|
|
makeCall("VIDEO");
|
|
},
|
|
icon: SvgPicture.asset(
|
|
"assets/icons/chat/video_call.svg",
|
|
width: 20,
|
|
height: 20,
|
|
),
|
|
),
|
|
10.width,
|
|
]),
|
|
body: Consumer<ChatProviderModel>(
|
|
builder: (BuildContext context, ChatProviderModel m, Widget? child) {
|
|
return (m.isLoading
|
|
? ChatHomeShimmer()
|
|
: Column(
|
|
children: <Widget>[
|
|
Expanded(
|
|
flex: 2,
|
|
child: SmartRefresher(
|
|
enablePullDown: false,
|
|
enablePullUp: true,
|
|
onLoading: () {
|
|
getMoreChat();
|
|
},
|
|
header: const MaterialClassicHeader(
|
|
color: MyColors.gradiantEndColor,
|
|
),
|
|
controller: _rc,
|
|
reverse: true,
|
|
child: ListView.builder(
|
|
controller: m.scrollController,
|
|
shrinkWrap: true,
|
|
physics: const BouncingScrollPhysics(),
|
|
reverse: true,
|
|
itemCount: m.userChatHistory.length,
|
|
padding: const EdgeInsets.only(top: 20),
|
|
itemBuilder: (BuildContext context, int i) {
|
|
return SwipeTo(
|
|
iconColor: MyColors.lightGreenColor,
|
|
child: ChatBubble(
|
|
text: m.userChatHistory[i].contant.toString(),
|
|
replyText: m.userChatHistory[i].userChatReplyResponse != null ? m.userChatHistory[i].userChatReplyResponse!.contant.toString() : "",
|
|
isSeen: m.userChatHistory[i].isSeen == true ? true : false,
|
|
isCurrentUser: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id ? true : false,
|
|
isDelivered: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id && m.userChatHistory[i].isDelivered == true ? true : false,
|
|
dateTime: m.dateFormte(m.userChatHistory[i].createdDate!),
|
|
isReplied: m.userChatHistory[i].userChatReplyResponse != null ? true : false,
|
|
userName: AppState().chatDetails!.response!.userName == m.userChatHistory[i].currentUserName.toString() ? "You" : m.userChatHistory[i].currentUserName.toString(),
|
|
),
|
|
onRightSwipe: () {
|
|
m.chatReply(
|
|
m.userChatHistory[i],
|
|
);
|
|
},
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
if (m.isMsgReply)
|
|
Row(
|
|
children: <Widget>[
|
|
Container(
|
|
height: 80,
|
|
color: MyColors.textMixColor,
|
|
width: 6,
|
|
),
|
|
Expanded(
|
|
child: Container(
|
|
height: 80,
|
|
color: MyColors.black.withOpacity(0.10),
|
|
child: ListTile(
|
|
title: (AppState().chatDetails!.response!.userName == m.repliedMsg.first.currentUserName.toString()
|
|
? "You"
|
|
: m.repliedMsg.first.currentUserName.toString().replaceAll(".", " "))
|
|
.toText14(color: MyColors.lightGreenColor),
|
|
subtitle: (m.repliedMsg.isNotEmpty ? m.repliedMsg.first.contant! : "").toText12(
|
|
color: MyColors.white,
|
|
maxLine: 2,
|
|
),
|
|
trailing: GestureDetector(
|
|
onTap: m.closeMe,
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
color: MyColors.white.withOpacity(0.5),
|
|
borderRadius: const BorderRadius.all(
|
|
Radius.circular(20),
|
|
),
|
|
),
|
|
child: const Icon(
|
|
Icons.close,
|
|
size: 23,
|
|
color: MyColors.white,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
if (m.isFileSelected && m.sFileType == ".png" || m.sFileType == ".jpeg" || m.sFileType == ".jpg")
|
|
Card(
|
|
margin: EdgeInsets.zero,
|
|
elevation: 0,
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(
|
|
left: 20,
|
|
right: 20,
|
|
top: 20,
|
|
bottom: 0,
|
|
),
|
|
child: Card(
|
|
margin: EdgeInsets.zero,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(0),
|
|
),
|
|
elevation: 0,
|
|
child: Container(
|
|
height: 200,
|
|
decoration: BoxDecoration(
|
|
image: DecorationImage(
|
|
image: FileImage(
|
|
m.selectedFile,
|
|
),
|
|
fit: BoxFit.cover,
|
|
),
|
|
borderRadius: const BorderRadius.all(
|
|
Radius.circular(0),
|
|
),
|
|
),
|
|
child: const SizedBox(
|
|
width: double.infinity,
|
|
height: 200,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
Card(
|
|
margin: EdgeInsets.zero,
|
|
child: TextField(
|
|
controller: m.message,
|
|
decoration: InputDecoration(
|
|
hintText: m.isFileSelected ? m.selectedFile.path.split("/").last : LocaleKeys.typeheretoreply.tr(),
|
|
hintStyle: TextStyle(
|
|
color: m.isFileSelected ? MyColors.darkTextColor : MyColors.grey98Color,
|
|
fontSize: 14,
|
|
),
|
|
border: InputBorder.none,
|
|
focusedBorder: InputBorder.none,
|
|
enabledBorder: InputBorder.none,
|
|
errorBorder: InputBorder.none,
|
|
disabledBorder: InputBorder.none,
|
|
contentPadding: EdgeInsets.only(
|
|
left: m.sFileType.isNotEmpty ? 10 : 20,
|
|
right: m.sFileType.isNotEmpty ? 0 : 5,
|
|
top: 20,
|
|
bottom: 20,
|
|
),
|
|
prefixIcon: m.sFileType.isNotEmpty
|
|
? Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: <Widget>[
|
|
SvgPicture.asset(
|
|
m.getType(m.sFileType),
|
|
height: 30,
|
|
width: 25,
|
|
alignment: Alignment.center,
|
|
fit: BoxFit.cover,
|
|
).paddingOnly(left: 20),
|
|
],
|
|
)
|
|
: null,
|
|
suffixIcon: SizedBox(
|
|
width: 96,
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.end,
|
|
crossAxisAlignment: CrossAxisAlignment.center, // added line
|
|
children: <Widget>[
|
|
if (m.sFileType.isNotEmpty)
|
|
IconButton(
|
|
padding: EdgeInsets.zero,
|
|
alignment: Alignment.centerRight,
|
|
icon: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisAlignment: MainAxisAlignment.end,
|
|
mainAxisSize: MainAxisSize.max,
|
|
children: <Widget>[
|
|
Container(
|
|
decoration: const BoxDecoration(
|
|
color: MyColors.redA3Color,
|
|
borderRadius: BorderRadius.all(
|
|
Radius.circular(20),
|
|
),
|
|
),
|
|
child: const Icon(
|
|
Icons.close,
|
|
size: 15,
|
|
color: MyColors.white,
|
|
),
|
|
),
|
|
("Clear")
|
|
.toText11(
|
|
color: MyColors.redA3Color,
|
|
)
|
|
.paddingOnly(
|
|
left: 4,
|
|
),
|
|
],
|
|
),
|
|
onPressed: () async {
|
|
m.removeAttachment();
|
|
},
|
|
),
|
|
if (m.sFileType.isEmpty)
|
|
RotationTransition(
|
|
turns: const AlwaysStoppedAnimation(45 / 360),
|
|
child: IconButton(
|
|
padding: EdgeInsets.zero,
|
|
alignment: Alignment.topRight,
|
|
icon: const Icon(
|
|
Icons.attach_file_rounded,
|
|
size: 26,
|
|
color: MyColors.grey3AColor,
|
|
),
|
|
onPressed: () async {
|
|
m.selectImageToUpload(context);
|
|
},
|
|
),
|
|
),
|
|
IconButton(
|
|
alignment: Alignment.centerRight,
|
|
padding: EdgeInsets.zero,
|
|
icon: SvgPicture.asset(
|
|
"assets/icons/chat/chat_send_icon.svg",
|
|
height: 26,
|
|
width: 26,
|
|
),
|
|
onPressed: () {
|
|
m.sendChatMessage(
|
|
userDetails["targetUser"].id,
|
|
userDetails["targetUser"].userName,
|
|
context,
|
|
);
|
|
},
|
|
)
|
|
],
|
|
),
|
|
).paddingOnly(
|
|
right: 20,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
));
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
void makeCall(String callType) async {
|
|
// final server = await SelectionDialog(
|
|
// context,
|
|
// title: "Select Server",
|
|
// items: ["https://livecareturn.hmg.com:8086", "https://104.197.179.1:8086"]
|
|
// ).show();
|
|
|
|
Map<String, String> json = {
|
|
"callerID": "9920",
|
|
"PatientID": "1231755",
|
|
"msgID": "123",
|
|
"notfID": "123",
|
|
"notification_foreground": "true",
|
|
"count": "1",
|
|
"message": "Doctor is calling ",
|
|
"AppointmentNo": "123",
|
|
"title": "Rayyan Hospital",
|
|
"ProjectID": "123",
|
|
"NotificationType": "10",
|
|
"background": "1",
|
|
"doctorname": "Dr Sulaiman Al Habib",
|
|
"clinicname": "ENT Clinic",
|
|
"speciality": "Speciality",
|
|
"appointmentdate": "Sun, 15th Dec, 2019",
|
|
"appointmenttime": "09:00",
|
|
"type": "video",
|
|
"session_id":
|
|
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImN0eSI6InR3aWxpby1mcGE7dj0xIn0.eyJqdGkiOiJTS2I2NjYyOWMzN2ZhOTM3YjFjNDI2Zjg1MTgyNWFmN2M0LTE1OTg3NzQ1MDYiLCJpc3MiOiJTS2I2NjYyOWMzN2ZhOTM3YjFjNDI2Zjg1MTgyNWFmN2M0Iiwic3ViIjoiQUNhYWQ1YTNmOGM2NGZhNjczNTY3NTYxNTc0N2YyNmMyYiIsImV4cCI6MTU5ODc3ODEwNiwiZ3JhbnRzIjp7ImlkZW50aXR5IjoiSGFyb29uMSIsInZpZGVvIjp7InJvb20iOiJTbWFsbERhaWx5U3RhbmR1cCJ9fX0.7XUS5uMQQJfkrBZu9EjQ6STL6R7iXkso6BtO1HmrQKk",
|
|
"identity": "Haroon1",
|
|
"name": "SmallDailyStandup",
|
|
"videoUrl": "video",
|
|
"picture": "video",
|
|
"is_call": "true",
|
|
"is_webrtc": "true",
|
|
// "server": "https://192.168.8.163:8086",
|
|
"server": "https://livecareturn.hmg.com:8086",
|
|
};
|
|
|
|
IncomingCallData incomingCallData = IncomingCallData.fromJson(json);
|
|
await Navigator.push(
|
|
context,
|
|
MaterialPageRoute(
|
|
builder: (BuildContext context) => OutGoingCall(
|
|
isVideoCall: callType == "VIDEO" ? true : false,
|
|
OutGoingCallData: incomingCallData,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|