File size: 6,702 Bytes
a0fda44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import React, { useMemo, useState } from "react";
import { useSelector } from "react-redux";
import IconWrapper from "../../globals/IconWrapper";
import AttachFileModal from "./AttachFileModal";
import MessageInput from "./MessageInput";
import useRecorder from "../../../hooks/useRecorder";
import StopRecordModal from "./StopRecordModal";
import useMessageInput from "../../../hooks/useMessageInput";
import CTAButtons from "./CTAButtons";
import AttachFileOrRecordDuration from "./AttachFileOrRecordDuration";
import EmojiModal from "./EmojiModal";
import BubbleTail from "./BubbleTail";

function NewMessage({ currentChatRoom }) {
  // Get current message mode
  const messageMode = useSelector((state) => state.chatReducer.mode);

  // Message Input
  const {
    addEmojiToMessage,
    handleInput,
    messageEmpty,
    getCaretIndex,
    emitTypingEvent,
    setMessageEmpty,
  } = useMessageInput({ currentChatRoom });

  // Emoji modal visibility
  const [emojiVisible, setEmojiVisible] = useState(false);

  const isRecording = useMemo(() => messageMode === "recording", [messageMode]);

  const isTyping = useMemo(() => messageMode === "typing", [messageMode]);

  //   Recorder hook to record messages
  const {
    formattedTime,
    startRecording,
    endRecording,
    playRecording,
    clearRecording,
    pauseRecording,
  } = useRecorder({ currentChatRoom });

  return (
    <div className="flex flex-col shrink-0">
      <div className="flex items-end gap-[1.5rem] sm:gap-0">
        {/* Message form bubble */}
        <div
          className={` overflow-x-hidden flex-grow duration-75 flex items-end ${
            isRecording ? "mr-[6rem]" : "mr-0"
          }`}
        >
          {/* Message form */}
          <div
            className={`bg-primary px-[1.5rem] py-[1rem] rounded-2xl rounded-br-none flex-grow flex items-end  overflow-x-hidden`}
          >
            {/* Emoji picker */}
            <IconWrapper
              onClick={() => setEmojiVisible((prevState) => !prevState)}
              className="shrink-0"
            >
              {emojiVisible && (
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="1em"
                  height="1em"
                  preserveAspectRatio="xMidYMid meet"
                  viewBox="0 0 16 16"
                >
                  <g fill="currentColor" className="fill-secondary-text">
                    <path d="M14 5a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h12zM2 4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H2z" />
                    <path d="M13 10.25a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25v-.5zm0-2a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25v-.5zm-5 0A.25.25 0 0 1 8.25 8h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 8 8.75v-.5zm2 0a.25.25 0 0 1 .25-.25h1.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-1.5a.25.25 0 0 1-.25-.25v-.5zm1 2a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25v-.5zm-5-2A.25.25 0 0 1 6.25 8h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 6 8.75v-.5zm-2 0A.25.25 0 0 1 4.25 8h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 4 8.75v-.5zm-2 0A.25.25 0 0 1 2.25 8h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 2 8.75v-.5zm11-2a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25v-.5zm-2 0a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25v-.5zm-2 0A.25.25 0 0 1 9.25 6h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 9 6.75v-.5zm-2 0A.25.25 0 0 1 7.25 6h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 7 6.75v-.5zm-2 0A.25.25 0 0 1 5.25 6h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 5 6.75v-.5zm-3 0A.25.25 0 0 1 2.25 6h1.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-1.5A.25.25 0 0 1 2 6.75v-.5zm0 4a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25v-.5zm2 0a.25.25 0 0 1 .25-.25h5.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-5.5a.25.25 0 0 1-.25-.25v-.5z" />
                  </g>
                </svg>
              )}

              {!emojiVisible && (
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="1em"
                  height="1em"
                  preserveAspectRatio="xMidYMid meet"
                  viewBox="0 0 48 48"
                >
                  <path
                    fill="currentColor"
                    d="M17.5 22a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5ZM33 19.5a2.5 2.5 0 1 1-5 0a2.5 2.5 0 0 1 5 0ZM18.452 34.681A11.718 11.718 0 0 0 24 36a11.718 11.718 0 0 0 9.816-5.1a1.249 1.249 0 1 0-2.13-1.307A9.212 9.212 0 0 1 24 33.5a9.22 9.22 0 0 1-7.687-3.907a1.248 1.248 0 1 0-2.13 1.307a11.718 11.718 0 0 0 4.269 3.781ZM24 4C12.954 4 4 12.954 4 24s8.954 20 20 20s20-8.954 20-20S35.046 4 24 4ZM6.5 24c0-9.665 7.835-17.5 17.5-17.5S41.5 14.335 41.5 24S33.665 41.5 24 41.5S6.5 33.665 6.5 24Z"
                  />
                </svg>
              )}
            </IconWrapper>

            {/* Message Input */}
            <MessageInput
              isRecording={isRecording}
              handleInput={handleInput}
              messageEmpty={messageEmpty}
              getCaretIndex={getCaretIndex}
              emitTypingEvent={emitTypingEvent}
            />

            <AttachFileOrRecordDuration
              isRecording={isRecording}
              formattedTime={formattedTime}
            />
          </div>
          <BubbleTail fillColor="fill-primary stroke-primary" />
        </div>

        {/* Action buttons to record stop recording and send messages or voice notes */}
        <CTAButtons
          startRecording={startRecording}
          endRecording={endRecording}
          isTyping={isTyping}
          isRecording={isRecording}
          clearRecording={clearRecording}
          pauseRecording={pauseRecording}
          setMessageEmpty={setMessageEmpty}
        />
      </div>

      {/* Modals */}
      {/* To pick emoji */}
      <EmojiModal
        emojiVisible={emojiVisible}
        setEmojiVisible={setEmojiVisible}
        addEmojiToMessage={addEmojiToMessage}
      />

      {/* To attach either video or photo */}
      <AttachFileModal />
      {/* Ask confirmation to stop recording if user types into keyboard while recording */}
      <StopRecordModal
        playRecording={playRecording}
        clearRecording={clearRecording}
      />
    </div>
  );
}

export default NewMessage;