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.
		
		
		
		
		
			
		
			
				
	
	
		
			381 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			381 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Dart
		
	
import 'dart:async';
 | 
						|
import 'dart:convert';
 | 
						|
import 'package:audio_waveforms/audio_waveforms.dart';
 | 
						|
import 'package:easy_localization/easy_localization.dart';
 | 
						|
import 'package:flutter/material.dart';
 | 
						|
import 'package:flutter_svg/flutter_svg.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/main.dart';
 | 
						|
import 'package:mohem_flutter_app/models/chat/call.dart';
 | 
						|
import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
 | 
						|
import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart';
 | 
						|
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart';
 | 
						|
import 'package:mohem_flutter_app/provider/chat_call_provider.dart';
 | 
						|
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
 | 
						|
import 'package:mohem_flutter_app/ui/chat/custom_auto_direction.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/ui/chat/common.dart';
 | 
						|
import 'package:mohem_flutter_app/widgets/chat_app_bar_widge.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:signalr_netcore/signalr_client.dart';
 | 
						|
import 'package:swipe_to/swipe_to.dart';
 | 
						|
 | 
						|
class ChatDetailedScreenParams {
 | 
						|
  ChatUser? chatUser;
 | 
						|
  bool? isNewChat;
 | 
						|
 | 
						|
  ChatDetailedScreenParams(this.chatUser, this.isNewChat);
 | 
						|
}
 | 
						|
 | 
						|
class ChatDetailScreen extends StatefulWidget {
 | 
						|
  const ChatDetailScreen({Key? key}) : super(key: key);
 | 
						|
 | 
						|
  @override
 | 
						|
  State<ChatDetailScreen> createState() => _ChatDetailScreenState();
 | 
						|
}
 | 
						|
 | 
						|
class _ChatDetailScreenState extends State<ChatDetailScreen> {
 | 
						|
  final RefreshController _rc = RefreshController(initialRefresh: false);
 | 
						|
  late ChatProviderModel data;
 | 
						|
  late ChatCallProvider callPro;
 | 
						|
  ChatDetailedScreenParams? params;
 | 
						|
 | 
						|
  // var textDirection = TextDirection.RTL;
 | 
						|
 | 
						|
  void getMoreChat() async {
 | 
						|
    if (params != null) {
 | 
						|
      data.paginationVal = data.paginationVal + 10;
 | 
						|
      if (params != null) {
 | 
						|
        data.getSingleUserChatHistory(
 | 
						|
          senderUID: AppState().chatDetails!.response!.id!.toInt(),
 | 
						|
          receiverUID: params!.chatUser!.id!,
 | 
						|
          loadMore: true,
 | 
						|
          isNewChat: false,
 | 
						|
        );
 | 
						|
      }
 | 
						|
    }
 | 
						|
    await Future.delayed(
 | 
						|
      const Duration(milliseconds: 1000),
 | 
						|
    );
 | 
						|
    _rc.loadComplete();
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  void dispose() {
 | 
						|
    data.disposeAudio();
 | 
						|
    super.dispose();
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    params = ModalRoute.of(context)!.settings.arguments as ChatDetailedScreenParams;
 | 
						|
    data = Provider.of<ChatProviderModel>(context, listen: false);
 | 
						|
    // callPro = Provider.of<ChatCallProvider>(context, listen: false);
 | 
						|
    if (params != null) {
 | 
						|
      data.getSingleUserChatHistory(
 | 
						|
        senderUID: AppState().chatDetails!.response!.id!.toInt(),
 | 
						|
        receiverUID: params!.chatUser!.id!,
 | 
						|
        loadMore: false,
 | 
						|
        isNewChat: params!.isNewChat!,
 | 
						|
      );
 | 
						|
      data.initAudio(receiverId: params!.chatUser!.id!);
 | 
						|
    }
 | 
						|
 | 
						|
    return Scaffold(
 | 
						|
      backgroundColor: MyColors.backgroundColor,
 | 
						|
      appBar: ChatAppBarWidget(
 | 
						|
        context,
 | 
						|
        title: params!.chatUser!.userName.toString().replaceAll(".", " ").capitalizeFirstofEach,
 | 
						|
        showHomeButton: false,
 | 
						|
        showTyping: true,
 | 
						|
        chatUser: params!.chatUser,
 | 
						|
        actions: [
 | 
						|
          // SvgPicture.asset("assets/icons/chat/call.svg", width: 21, height: 23).onPress(() {
 | 
						|
          //   makeCall(callType: "AUDIO");
 | 
						|
          // }),
 | 
						|
          // 24.width,
 | 
						|
          // SvgPicture.asset("assets/icons/chat/video_call.svg", width: 21, height: 18).onPress(() {
 | 
						|
          //   makeCall(callType: "VIDEO");
 | 
						|
          // }),
 | 
						|
          // 21.width,
 | 
						|
        ],
 | 
						|
      ),
 | 
						|
      body: SafeArea(
 | 
						|
        child: Consumer<ChatProviderModel>(
 | 
						|
          builder: (BuildContext context, ChatProviderModel m, Widget? child) {
 | 
						|
            return (m.isLoading
 | 
						|
                ? ChatHomeShimmer(
 | 
						|
                    isDetailedScreen: true,
 | 
						|
                  )
 | 
						|
                : Column(
 | 
						|
                    children: <Widget>[
 | 
						|
                      SmartRefresher(
 | 
						|
                        enablePullDown: false,
 | 
						|
                        enablePullUp: true,
 | 
						|
                        onLoading: () {
 | 
						|
                          getMoreChat();
 | 
						|
                        },
 | 
						|
                        header: const MaterialClassicHeader(
 | 
						|
                          color: MyColors.gradiantEndColor,
 | 
						|
                        ),
 | 
						|
                        controller: _rc,
 | 
						|
                        reverse: true,
 | 
						|
                        child: ListView.separated(
 | 
						|
                          controller: m.scrollController,
 | 
						|
                          shrinkWrap: true,
 | 
						|
                          physics: const BouncingScrollPhysics(),
 | 
						|
                          reverse: true,
 | 
						|
                          itemCount: m.userChatHistory.length,
 | 
						|
                          padding: const EdgeInsets.all(21),
 | 
						|
                          separatorBuilder: (BuildContext cxt, int index) => 8.height,
 | 
						|
                          itemBuilder: (BuildContext context, int i) {
 | 
						|
                            return SwipeTo(
 | 
						|
                              iconColor: MyColors.lightGreenColor,
 | 
						|
                              child: ChatBubble(
 | 
						|
                                dateTime: m.dateFormte(m.userChatHistory[i].createdDate!),
 | 
						|
                                cItem: m.userChatHistory[i],
 | 
						|
                              ),
 | 
						|
                              onRightSwipe: (val) {
 | 
						|
                                m.chatReply(
 | 
						|
                                  m.userChatHistory[i],
 | 
						|
                                );
 | 
						|
                              },
 | 
						|
                            ).onPress(() async {
 | 
						|
                              logger.w(m.userChatHistory[i].toJson());
 | 
						|
                              if (m.userChatHistory[i].fileTypeResponse != null && m.userChatHistory[i].fileTypeId != null) {
 | 
						|
                                if (m.userChatHistory[i].fileTypeId! == 1 ||
 | 
						|
                                        m.userChatHistory[i].fileTypeId! == 5 ||
 | 
						|
                                        m.userChatHistory[i].fileTypeId! == 7 ||
 | 
						|
                                        m.userChatHistory[i].fileTypeId! == 6 ||
 | 
						|
                                        m.userChatHistory[i].fileTypeId! == 8
 | 
						|
                                    // || m.userChatHistory[i].fileTypeId! == 2
 | 
						|
                                    ) {
 | 
						|
                                  m.getChatMedia(context,
 | 
						|
                                      fileTypeName: m.userChatHistory[i].fileTypeResponse!.fileTypeName ?? "", fileTypeID: m.userChatHistory[i].fileTypeId!, fileName: m.userChatHistory[i].contant!);
 | 
						|
                                }
 | 
						|
                              }
 | 
						|
                            });
 | 
						|
                          },
 | 
						|
                        ),
 | 
						|
                      ).expanded,
 | 
						|
                      if (m.isReplyMsg)
 | 
						|
                        SizedBox(
 | 
						|
                          height: 82,
 | 
						|
                          child: Row(
 | 
						|
                            children: <Widget>[
 | 
						|
                              Container(height: 82, color: MyColors.textMixColor, width: 6),
 | 
						|
                              Container(
 | 
						|
                                color: MyColors.darkTextColor.withOpacity(0.10),
 | 
						|
                                padding: const EdgeInsets.only(top: 11, left: 14, bottom: 14, right: 21),
 | 
						|
                                child: Row(
 | 
						|
                                  children: [
 | 
						|
                                    Column(
 | 
						|
                                      crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
                                      children: [
 | 
						|
                                        (AppState().chatDetails!.response!.userName == m.repliedMsg.first.currentUserName.toString()
 | 
						|
                                                ? "You"
 | 
						|
                                                : m.repliedMsg.first.currentUserName.toString().replaceAll(".", " "))
 | 
						|
                                            .toText14(color: MyColors.lightGreenColor),
 | 
						|
                                        (m.repliedMsg.isNotEmpty ? m.repliedMsg.first.contant! : "").toText12(color: MyColors.grey71Color, maxLine: 2)
 | 
						|
                                      ],
 | 
						|
                                    ).expanded,
 | 
						|
                                    12.width,
 | 
						|
                                    if (m.isReplyMsg && m.repliedMsg.isNotEmpty) showReplyImage(m.repliedMsg, m),
 | 
						|
                                    12.width,
 | 
						|
                                    const Icon(Icons.cancel, size: 23, color: MyColors.grey7BColor).onPress(m.closeMe),
 | 
						|
                                  ],
 | 
						|
                                ),
 | 
						|
                              ).expanded,
 | 
						|
                            ],
 | 
						|
                          ),
 | 
						|
                        ),
 | 
						|
                      if (m.isAttachmentMsg && m.sFileType == ".png" || m.sFileType == ".jpeg" || m.sFileType == ".jpg")
 | 
						|
                        SizedBox(height: 200, width: double.infinity, child: Image.file(m.selectedFile, fit: BoxFit.cover)).paddingOnly(left: 21, right: 21, top: 21),
 | 
						|
                      const Divider(height: 1, color: MyColors.lightGreyEFColor),
 | 
						|
                      if (m.isRecoding)
 | 
						|
                        Column(
 | 
						|
                          children: <Widget>[
 | 
						|
                            Row(
 | 
						|
                              children: [
 | 
						|
                                Text(m.buildTimer()).paddingAll(10),
 | 
						|
                                if (m.isRecoding && m.isPlaying)
 | 
						|
                                  WaveBubble(
 | 
						|
                                    playerController: m.playerController,
 | 
						|
                                    isPlaying: m.playerController.playerState == PlayerState.playing,
 | 
						|
                                    onTap: () {},
 | 
						|
                                  ).expanded
 | 
						|
                                else
 | 
						|
                                  AudioWaveforms(
 | 
						|
                                    waveStyle: const WaveStyle(
 | 
						|
                                      waveColor: MyColors.lightGreenColor,
 | 
						|
                                      middleLineColor: Colors.transparent,
 | 
						|
                                      extendWaveform: true,
 | 
						|
                                      showBottom: true,
 | 
						|
                                      showTop: true,
 | 
						|
                                      waveThickness: 2,
 | 
						|
                                      showMiddleLine: false,
 | 
						|
                                      middleLineThickness: 0,
 | 
						|
                                    ),
 | 
						|
                                    padding: const EdgeInsets.all(5),
 | 
						|
                                    shouldCalculateScrolledPosition: false,
 | 
						|
                                    margin: EdgeInsets.zero,
 | 
						|
                                    size: const Size(double.infinity, 30.0),
 | 
						|
                                    recorderController: m.recorderController,
 | 
						|
                                    backgroundColor: Colors.white,
 | 
						|
                                  ).expanded,
 | 
						|
                              ],
 | 
						|
                            ),
 | 
						|
                            Row(
 | 
						|
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
						|
                              children: [
 | 
						|
                                const Icon(
 | 
						|
                                  Icons.delete_outlined,
 | 
						|
                                  size: 26,
 | 
						|
                                  color: MyColors.lightGreenColor,
 | 
						|
                                ).paddingAll(10).onPress(() {
 | 
						|
                                  m.deleteRecoding();
 | 
						|
                                }),
 | 
						|
                                SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26)
 | 
						|
                                    .onPress(
 | 
						|
                                      () => m.sendChatMessage(context,
 | 
						|
                                          targetUserId: params!.chatUser!.id!,
 | 
						|
                                          userStatus: params!.chatUser!.userStatus ?? 0,
 | 
						|
                                          userEmail: params!.chatUser!.email!,
 | 
						|
                                          targetUserName: params!.chatUser!.userName!),
 | 
						|
                                    )
 | 
						|
                                    .paddingOnly(right: 21),
 | 
						|
                              ],
 | 
						|
                            ),
 | 
						|
                          ],
 | 
						|
                        ).objectContainerView(disablePadding: true, radius: 0),
 | 
						|
                      if (!m.isRecoding)
 | 
						|
                        Row(
 | 
						|
                          children: [
 | 
						|
                            CustomAutoDirection(
 | 
						|
                              onDirectionChange: (bool isRTL) => m.onDirectionChange(isRTL),
 | 
						|
                              text: m.msgText,
 | 
						|
                              child: TextField(
 | 
						|
                                //    textDirection: m.textDirection,
 | 
						|
                                controller: m.message,
 | 
						|
                                decoration: InputDecoration(
 | 
						|
                                  hintTextDirection: m.textDirection,
 | 
						|
                                  hintText: m.isAttachmentMsg ? m.selectedFile.path.split("/").last : LocaleKeys.typeheretoreply.tr(),
 | 
						|
                                  hintStyle: TextStyle(color: m.isAttachmentMsg ? MyColors.darkTextColor : MyColors.grey98Color, fontSize: 14),
 | 
						|
                                  border: InputBorder.none,
 | 
						|
                                  focusedBorder: InputBorder.none,
 | 
						|
                                  enabledBorder: InputBorder.none,
 | 
						|
                                  errorBorder: InputBorder.none,
 | 
						|
                                  disabledBorder: InputBorder.none,
 | 
						|
                                  filled: true,
 | 
						|
                                  fillColor: MyColors.white,
 | 
						|
                                  contentPadding: const EdgeInsets.only(
 | 
						|
                                    left: 21,
 | 
						|
                                    top: 20,
 | 
						|
                                    bottom: 20,
 | 
						|
                                  ),
 | 
						|
                                  prefixIconConstraints: const BoxConstraints(),
 | 
						|
                                  prefixIcon: m.sFileType.isNotEmpty
 | 
						|
                                      ? SvgPicture.asset(m.getType(m.sFileType), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 21, right: 15)
 | 
						|
                                      : null,
 | 
						|
                                ),
 | 
						|
                                onChanged: (String val) {
 | 
						|
                                  m.inputBoxDirection(val);
 | 
						|
                                  m.userTypingInvoke(currentUser: AppState().chatDetails!.response!.id!, reciptUser: params!.chatUser!.id!);
 | 
						|
                                },
 | 
						|
                              ).expanded,
 | 
						|
                            ),
 | 
						|
                            if (m.sFileType.isNotEmpty)
 | 
						|
                              Row(
 | 
						|
                                children: <Widget>[
 | 
						|
                                  const Icon(Icons.cancel, size: 15, color: MyColors.redA3Color).paddingOnly(right: 5),
 | 
						|
                                  ("Clear").toText11(color: MyColors.redA3Color, isUnderLine: true).paddingOnly(left: 0),
 | 
						|
                                ],
 | 
						|
                              ).onPress(() => m.removeAttachment()).paddingOnly(right: 15),
 | 
						|
                            if (m.sFileType.isEmpty)
 | 
						|
                              RotationTransition(
 | 
						|
                                turns: const AlwaysStoppedAnimation(45 / 360),
 | 
						|
                                child: const Icon(Icons.attach_file_rounded, size: 26, color: MyColors.grey3AColor).onPress(
 | 
						|
                                  () => m.selectImageToUpload(context),
 | 
						|
                                ),
 | 
						|
                              ).paddingOnly(right: 15),
 | 
						|
                            const Icon(
 | 
						|
                              Icons.mic,
 | 
						|
                              color: MyColors.lightGreenColor,
 | 
						|
                            ).paddingOnly(right: 15).onPress(() {
 | 
						|
                              m.startRecoding(context);
 | 
						|
                            }),
 | 
						|
                            SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26)
 | 
						|
                                .onPress(
 | 
						|
                                  () => m.sendChatMessage(context,
 | 
						|
                                      targetUserId: params!.chatUser!.id!,
 | 
						|
                                      userStatus: params!.chatUser!.userStatus ?? 0,
 | 
						|
                                      userEmail: params!.chatUser!.email!,
 | 
						|
                                      targetUserName: params!.chatUser!.userName!),
 | 
						|
                                )
 | 
						|
                                .paddingOnly(right: 21),
 | 
						|
                          ],
 | 
						|
                        ).objectContainerView(disablePadding: true, radius: 0),
 | 
						|
                    ],
 | 
						|
                  ));
 | 
						|
          },
 | 
						|
        ),
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  Widget showReplyImage(List<SingleUserChatModel> data, ChatProviderModel m) {
 | 
						|
    if (data.first.isImageLoaded! && data.first.image != null) {
 | 
						|
      return Container(
 | 
						|
        width: 43,
 | 
						|
        height: 43,
 | 
						|
        decoration: BoxDecoration(
 | 
						|
            border: Border.all(color: MyColors.darkGrey3BColor, width: 1), borderRadius: BorderRadius.circular(10.0), image: DecorationImage(image: MemoryImage(data.first.image!), fit: BoxFit.cover)),
 | 
						|
      );
 | 
						|
    } else {
 | 
						|
      return data.first.fileTypeResponse != null && data.first.fileTypeResponse!.fileTypeName != null
 | 
						|
          ? Container(
 | 
						|
              width: 43,
 | 
						|
              height: 43,
 | 
						|
              constraints: const BoxConstraints(),
 | 
						|
              decoration: BoxDecoration(border: Border.all(color: MyColors.darkGrey3BColor, width: 1), borderRadius: BorderRadius.circular(10.0), color: Colors.white),
 | 
						|
              child: SvgPicture.asset(m.getType(data.first.fileTypeResponse!.fileTypeName ?? ""), alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 5, right: 5, top: 5, bottom: 5))
 | 
						|
          : const SizedBox();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  void makeCall({required String callType}) async {
 | 
						|
    callPro.initCallListeners();
 | 
						|
    print("================== Make call Triggered ============================");
 | 
						|
    Map<String, dynamic> json = {
 | 
						|
      "callerID": AppState().chatDetails!.response!.id!.toString(),
 | 
						|
      "callerDetails": AppState().chatDetails!.toJson(),
 | 
						|
      "receiverID": params!.chatUser!.id.toString(),
 | 
						|
      "receiverDetails": params!.chatUser!.toJson(),
 | 
						|
      "title": params!.chatUser!.userName!.replaceAll(".", " "),
 | 
						|
      "calltype": callType == "VIDEO" ? "Video" : "Audio",
 | 
						|
    };
 | 
						|
    logger.w(json);
 | 
						|
    CallDataModel callData = CallDataModel.fromJson(json);
 | 
						|
    await Navigator.push(
 | 
						|
      context,
 | 
						|
      MaterialPageRoute(
 | 
						|
        builder: (BuildContext context) => OutGoingCall(
 | 
						|
          isVideoCall: callType == "VIDEO" ? true : false,
 | 
						|
          outGoingCallData: callData,
 | 
						|
        ),
 | 
						|
      ),
 | 
						|
    ).then((value) {
 | 
						|
      print("then");
 | 
						|
      callPro.stopListeners();
 | 
						|
    });
 | 
						|
  }
 | 
						|
}
 |