Skip to content

Commit 5358279

Browse files
committed
fix: picker position
1 parent ccb62b6 commit 5358279

File tree

11 files changed

+84
-95
lines changed

11 files changed

+84
-95
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ yarn-error.log
1111

1212
# Test files
1313
coverage
14+
15+
# vscode
16+
.vscode

.vscode/launch.json

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/components/Widget/components/Conversation/components/Messages/components/Message/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ type Props = {
1515
}
1616

1717
function Message({ message, showTimeStamp }: Props) {
18-
const sanitizedHTML = markdownIt()
18+
const sanitizedHTML = markdownIt({ break: true })
1919
.use(markdownItClass, {
2020
img: ['rcw-message-img']
2121
})
@@ -26,7 +26,7 @@ function Message({ message, showTimeStamp }: Props) {
2626

2727
return (
2828
<div className={`rcw-${message.sender}`}>
29-
<div className="rcw-message-text" dangerouslySetInnerHTML={{ __html: sanitizedHTML }} />
29+
<div className="rcw-message-text" dangerouslySetInnerHTML={{ __html: sanitizedHTML.replace(/\n$/,'') }} />
3030
{showTimeStamp && <span className="rcw-timestamp">{format(message.timestamp, 'hh:mm')}</span>}
3131
</div>
3232
);

src/components/Widget/components/Conversation/components/Messages/components/Message/styles.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
.rcw-message {
55
margin: 10px;
66
display: flex;
7+
white-space: pre-wrap;
78
word-wrap: break-word;
89
}
910

@@ -19,6 +20,9 @@
1920

2021
.rcw-message-text {
2122
@include message-bubble($turqois-2);
23+
24+
white-space: pre-wrap;
25+
word-wrap: break-word;
2226
}
2327

2428
.rcw-timestamp {

src/components/Widget/components/Conversation/components/Sender/components/EmojiPicker/index.tsx

Lines changed: 0 additions & 46 deletions
This file was deleted.

src/components/Widget/components/Conversation/components/Sender/components/EmojiPicker/style.scss

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/components/Widget/components/Conversation/components/Sender/index.tsx

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { useRef, useEffect, useState } from 'react';
1+
import { useRef, useEffect, useState, forwardRef, useImperativeHandle } from 'react';
22
import { useSelector } from 'react-redux';
3-
import EmojiPicker from './components/EmojiPicker'
43
import cn from 'classnames';
54

65
import { GlobalState } from 'src/store/types';
76

87
import { getCaretIndex, isFirefox, updateCaret, insertNodeAtCaret, getSelection } from '../../../../../../utils/contentEditable'
98
const send = require('../../../../../../../assets/send_button.svg') as string;
9+
const emoji = require('../../../../../../../assets/icon-smiley.svg') as string;
1010
const brRegex = /<br>/g;
1111

1212
import './style.scss';
@@ -17,18 +17,28 @@ type Props = {
1717
autofocus: boolean;
1818
sendMessage: (event: any) => void;
1919
buttonAlt: string;
20+
onPressEmoji: () => void;
21+
onChangeSize: (event: any) => void;
2022
onTextInputChange?: (event: any) => void;
2123
}
2224

23-
function Sender({ sendMessage, placeholder, disabledInput, autofocus, onTextInputChange, buttonAlt }: Props) {
25+
function Sender({ sendMessage, placeholder, disabledInput, autofocus, onTextInputChange, buttonAlt, onPressEmoji, onChangeSize }: Props, ref) {
2426
const showChat = useSelector((state: GlobalState) => state.behavior.showChat);
2527
const inputRef = useRef<HTMLDivElement>(null!);
28+
const refContainer = useRef<HTMLDivElement>(null);
2629
const [enter, setEnter]= useState(false)
2730
const [firefox, setFirefox] = useState(false);
31+
const [height, setHeight] = useState(0)
2832
// @ts-ignore
2933
useEffect(() => { if (showChat && autofocus) inputRef.current?.focus(); }, [showChat]);
3034
useEffect(() => { setFirefox(isFirefox())}, [])
3135

36+
useImperativeHandle(ref, () => {
37+
return {
38+
onSelectEmoji: handlerOnSelectEmoji,
39+
};
40+
});
41+
3242
const handlerOnChange = (event) => {
3343
onTextInputChange && onTextInputChange(event)
3444
}
@@ -68,6 +78,16 @@ function Sender({ sendMessage, placeholder, disabledInput, autofocus, onTextInpu
6878
}
6979
}
7080

81+
// TODO use a context for checkSize and toggle picker
82+
const checkSize = () => {
83+
const senderEl = refContainer.current
84+
if(senderEl && height !== senderEl.clientHeight) {
85+
const {clientHeight} = senderEl;
86+
setHeight(clientHeight)
87+
onChangeSize(clientHeight ? clientHeight -1 : 0)
88+
}
89+
}
90+
7191
const handlerOnKeyUp = (event) => {
7292
const el = inputRef.current;
7393
if(!el) return true;
@@ -81,14 +101,15 @@ function Sender({ sendMessage, placeholder, disabledInput, autofocus, onTextInpu
81101
el.innerHTML = el.innerHTML.replace(brRegex, '')
82102
}
83103
}
104+
checkSize()
84105
}
85106

86107
const handlerOnKeyDown= (event) => {
87108
const el = inputRef.current;
88109

89110
if( event.key === 'Backspace' && el){
90111
const caretPosition = getCaretIndex(inputRef.current)
91-
const character = el?.innerHTML.charAt(caretPosition - 1)
112+
const character = el.innerHTML.charAt(caretPosition - 1)
92113
if(character === "\n") {
93114
event.preventDefault();
94115
event.stopPropagation()
@@ -98,9 +119,16 @@ function Sender({ sendMessage, placeholder, disabledInput, autofocus, onTextInpu
98119
}
99120
}
100121

122+
const handlerPressEmoji = () => {
123+
onPressEmoji();
124+
checkSize();
125+
}
126+
101127
return (
102-
<div className="rcw-sender">
103-
<EmojiPicker onSelectEmoji={handlerOnSelectEmoji}/>
128+
<div ref={refContainer} className="rcw-sender">
129+
<button className='rcw-picker-btn' type="submit" onClick={handlerPressEmoji}>
130+
<img src={emoji} className="rcw-picker-icon" alt="" />
131+
</button>
104132
<div className={cn('rcw-new-message', {
105133
'rcw-message-disable': disabledInput,
106134
})
@@ -126,4 +154,4 @@ function Sender({ sendMessage, placeholder, disabledInput, autofocus, onTextInpu
126154
);
127155
}
128156

129-
export default Sender;
157+
export default forwardRef(Sender);

src/components/Widget/components/Conversation/components/Sender/style.scss

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
min-height: 45px;
1111
overflow: hidden;
1212
padding: 10px;
13+
position: relative;
1314

1415
&.expand {
1516
height: 55px;
@@ -37,7 +38,7 @@
3738
display: block;
3839
height: 100%;
3940
line-height: 20px;
40-
max-height: 75px;
41+
max-height: 78px;
4142
overflow-y: auto;
4243
user-select: text;
4344
white-space: pre-wrap;
@@ -53,9 +54,10 @@
5354
}
5455
}
5556

56-
.rcw-send {
57+
.rcw-send, .rcw-picker-btn {
5758
background: $grey-2;
5859
border: 0;
60+
cursor: pointer;
5961

6062
.rcw-send-icon {
6163
height: 25px;

src/components/Widget/components/Conversation/index.tsx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { useRef, useState } from 'react';
2+
import { Picker } from 'emoji-mart';
13
import cn from 'classnames';
24

35
import Header from './components/Header';
@@ -9,6 +11,10 @@ import { AnyFunction } from '../../../../utils/types';
911

1012
import './style.scss';
1113

14+
interface ISenderRef {
15+
onSelectEmoji: (event: any) => void;
16+
}
17+
1218
type Props = {
1319
title: string;
1420
subtitle: string;
@@ -44,6 +50,23 @@ function Conversation({
4450
sendButtonAlt,
4551
showTimeStamp
4652
}: Props) {
53+
const [pickerOffset, setOffset] = useState(0)
54+
const senderRef = useRef<ISenderRef>(null!);
55+
const [pickerStatus, setPicket] = useState(false)
56+
57+
const onSelectEmoji = (emoji) => {
58+
senderRef.current?.onSelectEmoji(emoji)
59+
}
60+
61+
const togglePicker = () => {
62+
setPicket(prevPickerStatus => !prevPickerStatus)
63+
}
64+
65+
const handlerSendMsn = (event) => {
66+
sendMessage(event)
67+
if(pickerStatus) setPicket(false)
68+
}
69+
4770
return (
4871
<div className={cn('rcw-conversation-container', className)} aria-live="polite">
4972
<Header
@@ -55,13 +78,20 @@ function Conversation({
5578
/>
5679
<Messages profileAvatar={profileAvatar} showTimeStamp={showTimeStamp} />
5780
<QuickButtons onQuickButtonClicked={onQuickButtonClicked} />
81+
{pickerStatus && (<Picker
82+
style={{ position: 'absolute', bottom: pickerOffset, left: '0', width: '100%' }}
83+
onSelect={onSelectEmoji}
84+
/>)}
5885
<Sender
59-
sendMessage={sendMessage}
86+
ref={senderRef}
87+
sendMessage={handlerSendMsn}
6088
placeholder={senderPlaceHolder}
6189
disabledInput={disabledInput}
6290
autofocus={autofocus}
6391
onTextInputChange={onTextInputChange}
6492
buttonAlt={sendButtonAlt}
93+
onPressEmoji={togglePicker}
94+
onChangeSize={setOffset}
6595
/>
6696
</div>
6797
);

src/components/Widget/components/Conversation/style.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
@import 'common';
22
@import 'variables/colors';
33
@import 'animation';
4+
@import "~emoji-mart/css/emoji-mart.css";
45

56
.rcw-conversation-container {
67
border-radius: 10px;
@@ -21,6 +22,10 @@
2122
}
2223
}
2324

25+
.emoji-mart-preview {
26+
display: none;
27+
}
28+
2429
.rcw-full-screen {
2530
.rcw-conversation-container {
2631
@include conversation-container-fs;

0 commit comments

Comments
 (0)