Skip to content

Commit 5d441aa

Browse files
(feature) Video Message Added
1 parent 5f674cd commit 5d441aa

File tree

8 files changed

+277
-25
lines changed

8 files changed

+277
-25
lines changed

example/App.js

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@ export class App extends Component {
3838
list: 'chat',
3939
messageList: [],
4040
};
41+
42+
this.addMessage = this.addMessage.bind(this);
4143
}
4244

4345
UNSAFE_componentWillMount() {
44-
// setInterval(this.addMessage.bind(this), 3000);
46+
this.addMessage(6)
4547
}
4648

4749
getRandomColor() {
@@ -54,7 +56,7 @@ export class App extends Component {
5456
}
5557

5658
token() {
57-
return (parseInt(Math.random() * 10 % 6));
59+
return (parseInt(Math.random() * 10 % 7));
5860
}
5961

6062
photo(size) {
@@ -64,35 +66,39 @@ export class App extends Component {
6466
}).toString()
6567
}
6668

67-
random(type) {
69+
random(type, mtype) {
6870
switch (type) {
6971
case 'message':
70-
var type = this.token();
72+
mtype = mtype || this.token();
7173
var status = 'waiting';
72-
switch (type) {
74+
switch (mtype) {
7375
case 0:
74-
type = 'photo';
76+
mtype = 'photo';
7577
status = 'sent';
7678
break;
7779
case 1:
78-
type = 'file';
80+
mtype = 'file';
7981
status = 'sent';
8082
break;
8183
case 2:
82-
type = 'system';
84+
mtype = 'system';
8385
status = 'received';
8486
break;
8587
case 3:
86-
type = 'location';
88+
mtype = 'location';
8789
break;
8890
case 4:
89-
type = 'spotify';
91+
mtype = 'spotify';
9092
break;
9193
case 5:
92-
type = 'meeting';
94+
mtype = 'meeting';
95+
break;
96+
case 6:
97+
mtype = 'video';
98+
status = 'sent';
9399
break;
94100
default:
95-
type = 'text';
101+
mtype = 'text';
96102
status = 'read';
97103
break;
98104
}
@@ -139,17 +145,19 @@ export class App extends Component {
139145
},
140146
})),
141147
}) : null,
142-
type: type,
148+
type: mtype,
143149
theme: 'white',
144150
view: 'list',
145151
title: loremIpsum({ count: 2, units: 'words' }),
146152
titleColor: this.getRandomColor(),
147-
text: type === 'spotify' ? 'spotify:track:7wGoVu4Dady5GV0Sv4UIsx' : loremIpsum({ count: 1, units: 'sentences' }),
153+
text: mtype === 'spotify' ? 'spotify:track:0QjjaCaXE45mvhCnV3C0TA' : loremIpsum({ count: 1, units: 'sentences' }),
148154
data: {
155+
videoURL: this.token() >= 1 ? 'https://www.w3schools.com/html/mov_bbb.mp4' : 'http://www.exit109.com/~dnn/clips/RW20seconds_1.mp4',
149156
uri: `data:image/png;base64,${this.photo(150)}`,
150157
status: {
151158
click: true,
152-
loading: .5,
159+
loading: 0.5,
160+
download: mtype === 'video',
153161
},
154162
size: "100MB",
155163
width: 300,
@@ -238,9 +246,9 @@ export class App extends Component {
238246
}
239247
}
240248

241-
addMessage() {
249+
addMessage(mtype) {
242250
var list = this.state.messageList;
243-
list.push(this.random('message'));
251+
list.push(this.random('message', mtype));
244252
this.setState({
245253
messageList: list,
246254
});
@@ -355,7 +363,7 @@ export class App extends Component {
355363
rightButtons={
356364
<Button
357365
text='Gönder'
358-
onClick={this.addMessage.bind(this)} />
366+
onClick={() => this.addMessage()} />
359367
} />
360368
</div>
361369
</div>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-chat-elements",
3-
"version": "10.11.3",
3+
"version": "10.12.0",
44
"description": "Reactjs chat components",
55
"author": "Avare Kodcu <[email protected]>",
66
"main": "dist/main.js",

src/MeetingMessage/__tests__/__snapshots__/MeetingMessage.js.snap

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,6 @@ exports[`MeetingMessage component should render without issues 1`] = `
3333
</span>
3434
</div>
3535
</div>
36-
<div
37-
className="rce-mtmg-right-icon"
38-
>
39-
<MdMoreHoriz />
40-
</div>
4136
</div>
4237
<div
4338
className="rce-mtmg-body-bottom"

src/MessageBox/MessageBox.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import LocationMessage from '../LocationMessage/LocationMessage';
88
import SpotifyMessage from '../SpotifyMessage/SpotifyMessage';
99
import ReplyMessage from '../ReplyMessage/ReplyMessage';
1010
import MeetingMessage from '../MeetingMessage/MeetingMessage';
11+
import VideoMessage from '../VideoMessage/VideoMessage';
1112

1213
import Avatar from '../Avatar/Avatar';
1314

@@ -40,7 +41,7 @@ export class MessageBox extends Component {
4041

4142
render() {
4243
var positionCls = classNames('rce-mbox', { 'rce-mbox-right': this.props.position === 'right' });
43-
var thatAbsoluteTime = !/(text|file|meeting)/g.test(this.props.type) && !(this.props.type === 'location' && this.props.text);
44+
var thatAbsoluteTime = !/(text|video|file|meeting)/g.test(this.props.type) && !(this.props.type === 'location' && this.props.text);
4445

4546
const dateText = this.props.date && !isNaN(this.props.date) && (
4647
this.props.dateString ||
@@ -166,6 +167,19 @@ export class MessageBox extends Component {
166167
text={this.props.text} />
167168
}
168169

170+
{
171+
this.props.type === 'video' &&
172+
<VideoMessage
173+
onOpen={this.props.onOpen}
174+
onDownload={this.props.onDownload}
175+
onLoad={this.props.onLoad}
176+
onPhotoError={this.props.onPhotoError}
177+
data={this.props.data}
178+
width={this.props.width}
179+
height={this.props.height}
180+
text={this.props.text} />
181+
}
182+
169183
{
170184
this.props.type === 'file' &&
171185
<FileMessage

src/VideoMessage/VideoMessage.css

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
.rce-mbox-video {
2+
margin-top: -3px;
3+
margin-right: -6px;
4+
margin-left: -6px;
5+
}
6+
7+
.rce-mbox-video.padding-time {
8+
padding-bottom: 12px;
9+
}
10+
11+
.rce-mbox-video .rce-mbox-text {
12+
padding: 5px 0px;
13+
max-width: 300px;
14+
margin: auto;
15+
}
16+
17+
.rce-mbox-video--video {
18+
position: relative;
19+
display: flex;
20+
overflow: hidden;
21+
justify-content: center;
22+
border-radius: 5px;
23+
max-height: 500px;
24+
}
25+
26+
.rce-mbox-video--video__block {
27+
position: absolute;
28+
top: 0;
29+
right: 0;
30+
left: 0;
31+
bottom: 0;
32+
background-color: rgba(0,0,0,0.5);
33+
border-radius: 5px;
34+
display: flex;
35+
}
36+
37+
.rce-mbox-video--video img {
38+
height: 100%;
39+
min-height: 100px;
40+
user-select: none;
41+
}
42+
43+
.rce-mbox-video--video video {
44+
width: 100%;
45+
/*min-height: 100px;*/
46+
user-select: none;
47+
}
48+
49+
.rce-mbox-video--video__block-item {
50+
margin: auto;
51+
cursor: pointer;
52+
width: 100px;
53+
height: 100px;
54+
}
55+
56+
.rce-mbox-video--download {
57+
color: #efe;
58+
display: flex;
59+
justify-content: center;
60+
background: none;
61+
border: none;
62+
font-size: 3.2em;
63+
outline: none;
64+
border: 1px solid #eee;
65+
border-radius: 100%;
66+
height: 100px;
67+
width: 100px;
68+
}
69+
70+
.rce-mbox-video--download:hover {
71+
opacity: .7;
72+
}
73+
74+
.rce-mbox-video--download:active {
75+
opacity: .3;
76+
}
77+
78+
.rce-mbox-video--error {
79+
display: flex;
80+
justify-content: center;
81+
align-items: center;
82+
background: none;
83+
font-size: 70px;
84+
color: #eaeaea;
85+
}

src/VideoMessage/VideoMessage.js

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import React, { Component } from 'react';
2+
3+
import './VideoMessage.css';
4+
5+
import FaCloudDownload from 'react-icons/lib/fa/cloud-download';
6+
import FaError from 'react-icons/lib/fa/exclamation-triangle';
7+
8+
import classNames from 'classnames';
9+
10+
const ProgressBar = require('react-progress-bar.js');
11+
const Circle = ProgressBar.Circle;
12+
13+
export class VideoMessage extends Component {
14+
render() {
15+
var progressOptions = {
16+
strokeWidth: 2.3,
17+
color: '#efe',
18+
trailColor: '#aaa',
19+
trailWidth: 1,
20+
step: (state, circle) => {
21+
circle.path.setAttribute('trail', state.color);
22+
circle.path.setAttribute('trailwidth-width', state.width);
23+
24+
var value = Math.round(circle.value() * 100);
25+
if (value === 0)
26+
circle.setText('');
27+
else
28+
circle.setText(value);
29+
}
30+
};
31+
32+
const error = this.props.data.status && this.props.data.status.error === true;
33+
const downloaded = this.props.data.status && this.props.data.status.download;
34+
35+
return (
36+
<div
37+
className={classNames('rce-mbox-video', {
38+
'padding-time': !this.props.text,
39+
})}>
40+
<div
41+
className='rce-mbox-video--video'
42+
style={this.props.data.width && this.props.data.height && {
43+
width: this.props.data.width,
44+
height: this.props.data.height,
45+
}}>
46+
47+
{
48+
!downloaded &&
49+
<img
50+
src={this.props.data.uri}
51+
alt={this.props.data.alt}
52+
onClick={this.props.onOpen}
53+
onLoad={this.props.onLoad}
54+
onError={this.props.onPhotoError}/>
55+
}
56+
57+
{
58+
downloaded &&
59+
<video controls>
60+
<source src={this.props.data.videoURL} type='video/mp4'/>
61+
Your browser does not support HTML video.
62+
</video>
63+
}
64+
65+
{
66+
error &&
67+
<div className='rce-mbox-video--video__block'>
68+
<span
69+
className='rce-mbox-video--video__block-item rce-mbox-video--error'>
70+
<FaError/>
71+
</span>
72+
</div>
73+
}
74+
{
75+
!error &&
76+
this.props.data.status &&
77+
!downloaded &&
78+
<div className='rce-mbox-video--video__block'>
79+
{
80+
!this.props.data.status.click &&
81+
<button
82+
onClick={this.props.onDownload}
83+
className='rce-mbox-video--video__block-item rce-mbox-video--download'>
84+
<FaCloudDownload/>
85+
</button>
86+
}
87+
{
88+
typeof this.props.data.status.loading === 'number' &&
89+
this.props.data.status.loading !== 0 &&
90+
<Circle
91+
progress={this.props.data.status.loading}
92+
options={progressOptions}
93+
initialAnimate={true}
94+
containerClassName={'rce-mbox-video--video__block-item'} />
95+
}
96+
</div>
97+
}
98+
</div>
99+
{
100+
this.props.text &&
101+
<div className='rce-mbox-text'>
102+
{this.props.text}
103+
</div>
104+
}
105+
</div>
106+
);
107+
}
108+
}
109+
110+
VideoMessage.defaultProps = {
111+
text: '',
112+
data: {},
113+
onDownload: null,
114+
onOpen: null,
115+
onLoad: null,
116+
onPhotoError: null,
117+
};
118+
119+
120+
export default VideoMessage;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import React, { Component } from 'react';
2+
import { shallow } from 'enzyme';
3+
import toJson from 'enzyme-to-json';
4+
import VideoMessage from '../VideoMessage';
5+
6+
describe('VideoMessage component', () => {
7+
it('should render without issues', () => {
8+
const component = shallow(<VideoMessage />);
9+
10+
expect(component.length).toBe(1);
11+
expect(toJson(component)).toMatchSnapshot();
12+
});
13+
});

0 commit comments

Comments
 (0)