Skip to content

Commit eabdf86

Browse files
kubraturanabdurrahmanekr
authored andcommitted
Messages focus feature added.
1 parent 0122c69 commit eabdf86

4 files changed

Lines changed: 125 additions & 18 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ import { MessageBox } from 'react-chat-elements'
145145
| avatar | none | url | message box avatar url |
146146
| renderAddCmp | none | function (component) | adding custom components to message box |
147147
| copiableDate | false | boolean | message box date text copiable |
148+
| messageFocus | false | boolean | used in message focus feature in MessageList component, makes style of the component focused |
148149

149150

150151
## SystemMessage Component
@@ -204,6 +205,9 @@ import { MessageList } from 'react-chat-elements'
204205
| downButtonBadge | none | boolean | message list downButton badge content |
205206
| onDownButtonClick | none | function | message list onDownButtonClick |
206207
| onContextMenu | none | function | message list item onContextMenu event, gets 3 parameters: message item, index of item, event |
208+
| focusedMessage | none | string | id of a message to focus on, this prop makes the MessageList scroll into MessageBox item of given message id |
209+
| scrollBlock | 'center' | string | used in scroll into focusedMessage as value of block property in parameter of scrollIntoView function |
210+
207211

208212
## ChatList Component
209213

src/MessageBox/MessageBox.css

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,19 @@
6464
min-width: 140px;
6565
}
6666

67+
.rce-mbox.message-focus {
68+
animation-iteration-count: 4;
69+
-webkit-animation-iteration-count: 5;
70+
-webkit-animation-duration: 1s;
71+
animation-name: message-box-default-focus;
72+
animation-duration: 1s;
73+
}
74+
75+
@-webkit-keyframes message-box-default-focus {
76+
from {background-color: #fff;}
77+
to {background-color: #dfdfdf;}
78+
}
79+
6780
.rce-mbox-body {
6881
margin: 0;
6982
padding: 0;
@@ -78,6 +91,19 @@
7891
border-top-left-radius: 5px;
7992
}
8093

94+
.rce-mbox.rce-mbox-right.message-focus {
95+
animation-iteration-count: 4;
96+
-webkit-animation-iteration-count: 5;
97+
-webkit-animation-duration: 1s;
98+
animation-name: message-box-right-focus;
99+
animation-duration: 1s;
100+
}
101+
102+
@-webkit-keyframes message-box-right-focus {
103+
from {background-color: #d4f1fb;}
104+
to {background-color: #b8dae6;}
105+
}
106+
81107
.rce-mbox-text {
82108
font-size: 13.6px;
83109
word-break: break-word;
@@ -134,6 +160,19 @@
134160
filter: drop-shadow( 2px 0px 1px rgba(0, 0, 0, .2));
135161
}
136162

163+
.rce-mbox-right-notch.message-focus {
164+
animation-iteration-count: 4;
165+
-webkit-animation-iteration-count: 5;
166+
-webkit-animation-duration: 1s;
167+
animation-name: message-right-notch-focus;
168+
animation-duration: 1s;
169+
}
170+
171+
@-webkit-keyframes message-right-notch-focus {
172+
from {fill: #d4f1fb;}
173+
to {fill: #b8dae6;}
174+
}
175+
137176
.rce-mbox-left-notch {
138177
position: absolute;
139178
left: -14px;
@@ -143,6 +182,19 @@
143182
fill: white;
144183
}
145184

185+
.rce-mbox-left-notch.message-focus {
186+
animation-iteration-count: 4;
187+
-webkit-animation-iteration-count: 5;
188+
-webkit-animation-duration: 1s;
189+
animation-name: message-left-notch-focus;
190+
animation-duration: 1s;
191+
}
192+
193+
@-webkit-keyframes message-left-notch-focus {
194+
from {fill: #fff;}
195+
to {fill: #dfdfdf;}
196+
}
197+
146198
.rce-mbox-title {
147199
margin: 0;
148200
margin-bottom: 8px;
@@ -170,4 +222,4 @@
170222

171223
.rce-mbox-title > .rce-avatar-container {
172224
margin-right: 5px;
173-
}
225+
}

src/MessageBox/MessageBox.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ export class MessageBox extends Component {
5050
className={classNames(
5151
positionCls,
5252
{'rce-mbox--clear-padding': thatAbsoluteTime},
53-
{'rce-mbox--clear-notch': !this.props.notch}
53+
{'rce-mbox--clear-notch': !this.props.notch},
54+
{ 'message-focus': this.props.messageFocus},
5455
)}>
5556
<div
5657
className='rce-mbox-body'
@@ -187,12 +188,18 @@ export class MessageBox extends Component {
187188
{
188189
this.props.notch &&
189190
(this.props.position === 'right' ?
190-
<svg className="rce-mbox-right-notch" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
191+
<svg className={classNames(
192+
"rce-mbox-right-notch",
193+
{ 'message-focus': this.props.messageFocus},
194+
)} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
191195
<path d="M0 0v20L20 0" />
192196
</svg>
193197
:
194198
<div>
195-
<svg className="rce-mbox-left-notch" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
199+
<svg className={classNames(
200+
"rce-mbox-left-notch",
201+
{ 'message-focus': this.props.messageFocus},
202+
)} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
196203
<defs>
197204
<filter id="filter1" x="0" y="0">
198205
<feOffset result="offOut" in="SourceAlpha" dx="-2" dy="-5" />
@@ -234,6 +241,7 @@ MessageBox.defaultProps = {
234241
renderAddCmp: null,
235242
copiableDate: false,
236243
onContextMenu: null,
244+
messageFocus: false,
237245
};
238246

239247

src/MessageList/MessageList.js

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import React, { Component } from 'react';
1+
import React, { Component, } from 'react';
22
import './MessageList.css';
33

4-
import MessageBox from '../MessageBox/MessageBox';
4+
import {
5+
MessageBox,
6+
} from '../MessageBox/MessageBox';
57

68
import FaChevronDown from 'react-icons/lib/fa/chevron-down';
79

@@ -14,10 +16,24 @@ export class MessageList extends Component {
1416
this.state = {
1517
scrollBottom: 0,
1618
downButton: false,
19+
messageFocus: false,
1720
};
1821

1922
this.loadRef = this.loadRef.bind(this);
23+
this.createReferenceOfMessage = this.createReferenceOfMessage.bind(this);
2024
this.onScroll = this.onScroll.bind(this);
25+
this.messageRefs = [];
26+
}
27+
28+
scrollIntoMessage(focusedMessage) {
29+
var message = this.messageRefs.find(x => x.messageId === focusedMessage);
30+
if (message !== undefined) {
31+
this.setState({
32+
messageFocus: true,
33+
}, () => {
34+
message.ref.scrollIntoView({block: this.props.scrollBlock, behavior: 'smooth',});
35+
});
36+
}
2137
}
2238

2339
checkScroll() {
@@ -35,12 +51,15 @@ export class MessageList extends Component {
3551
}
3652
}
3753

38-
componentWillReceiveProps() {
54+
componentWillReceiveProps(nextProps) {
3955
if (!this.mlistRef)
4056
return;
4157
this.setState({
4258
scrollBottom: this.getBottom(this.mlistRef),
4359
}, this.checkScroll.bind(this));
60+
61+
if (nextProps.focusedMessage)
62+
this.scrollIntoMessage(nextProps.focusedMessage);
4463
}
4564

4665
getBottom(e) {
@@ -83,6 +102,22 @@ export class MessageList extends Component {
83102
this.props.cmpRef(ref);
84103
}
85104

105+
createReferenceOfMessage(ref, messageId) {
106+
var check = this.messageRefs.find(res => res.messageId === messageId);
107+
108+
if (check !== undefined) {
109+
var index = this.messageRefs.indexOf(check);
110+
if (index !== -1) {
111+
this.messageRefs.splice(index, 1);
112+
}
113+
}
114+
115+
this.messageRefs.push({
116+
ref: ref,
117+
messageId: messageId,
118+
});
119+
}
120+
86121
onScroll(e) {
87122
var bottom = this.getBottom(e.target);
88123
this.state.scrollBottom = bottom;
@@ -92,15 +127,15 @@ export class MessageList extends Component {
92127
this.setState({
93128
downButton: true,
94129
scrollBottom: bottom,
95-
})
130+
});
96131
}
97132
} else {
98133
if (this.state.downButton !== false) {
99134
this.state.downButton = false;
100135
this.setState({
101136
downButton: false,
102137
scrollBottom: bottom,
103-
})
138+
});
104139
}
105140
}
106141

@@ -128,16 +163,22 @@ export class MessageList extends Component {
128163
className='rce-mlist'>
129164
{
130165
this.props.dataSource.map((x, i) => (
131-
<MessageBox
132-
key={i}
133-
{...x}
134-
onOpen={this.props.onOpen && ((e) => this.onOpen(x, i, e))}
135-
onDownload={this.props.onDownload && ((e) => this.onDownload(x, i, e))}
136-
onTitleClick={this.props.onTitleClick && ((e) => this.onTitleClick(x, i, e))}
137-
onForwardClick={this.props.onForwardClick && ((e) => this.onForwardClick(x, i, e))}
138-
onClick={this.props.onClick && ((e) => this.onClick(x, i, e))}
139-
onContextMenu={this.props.onContextMenu && ((e) => this.onContextMenu(x, i, e))}
166+
<div
167+
ref={ref => this.createReferenceOfMessage(ref, x.id)}>
168+
<MessageBox
169+
key={i}
170+
{...x}
171+
focusedMessage={this.props.focusedMessage}
172+
messageFocus={x.id === this.props.focusedMessage && this.state.messageFocus}
173+
onOpen={this.props.onOpen && ((e) => this.onOpen(x, i, e))}
174+
onFocus={this.props.onFocus && ((e) => this.onFocus(x, i, e)) }
175+
onDownload={this.props.onDownload && ((e) => this.onDownload(x, i, e))}
176+
onTitleClick={this.props.onTitleClick && ((e) => this.onTitleClick(x, i, e))}
177+
onForwardClick={this.props.onForwardClick && ((e) => this.onForwardClick(x, i, e))}
178+
onClick={this.props.onClick && ((e) => this.onClick(x, i, e))}
179+
onContextMenu={this.props.onContextMenu && ((e) => this.onContextMenu(x, i, e))}
140180
/>
181+
</div>
141182
))
142183
}
143184
</div>
@@ -175,6 +216,8 @@ MessageList.defaultProps = {
175216
toBottomHeight: 300,
176217
downButton: true,
177218
downButtonBadge: null,
219+
focusedMessage: null,
220+
scrollBlock: 'center',
178221
};
179222

180223
export default MessageList;

0 commit comments

Comments
 (0)