denshobato_chat_panel 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +93 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/denshobato_chat_panel.gemspec +29 -0
- data/lib/api/conversation_api.rb +32 -0
- data/lib/api/denshobato_api.rb +6 -0
- data/lib/api/message_api.rb +96 -0
- data/lib/denshobato_chat_panel/engine.rb +5 -0
- data/lib/denshobato_chat_panel/react_helper.rb +7 -0
- data/lib/denshobato_chat_panel/version.rb +3 -0
- data/lib/denshobato_chat_panel.rb +9 -0
- data/lib/generators/denshobato_chat_panel/assets/javascripts/denshobato.js +26077 -0
- data/lib/generators/denshobato_chat_panel/assets/stylesheets/denshobato.scss +441 -0
- data/lib/generators/denshobato_chat_panel/install_generator.rb +50 -0
- data/lib/react/actions/Conversation.jsx +9 -0
- data/lib/react/actions/Index.jsx +7 -0
- data/lib/react/actions/Messages.jsx +30 -0
- data/lib/react/api/Api.jsx +19 -0
- data/lib/react/components/Message.jsx +47 -0
- data/lib/react/components/MessageForm.jsx +37 -0
- data/lib/react/components/Messages.jsx +110 -0
- data/lib/react/containers/MessagesContainer.jsx +47 -0
- data/lib/react/denshobato.js +18 -0
- data/lib/react/reducers/Conversation.jsx +20 -0
- data/lib/react/reducers/Index.jsx +8 -0
- data/lib/react/reducers/Messages.jsx +21 -0
- data/lib/react/store/Store.jsx +8 -0
- data/lib/react/utils/ChatUtils.js +12 -0
- data/package.json +35 -0
- data/webpack.config.js +21 -0
- metadata +163 -0
@@ -0,0 +1,441 @@
|
|
1
|
+
$spacing: 20px;
|
2
|
+
|
3
|
+
$radius: 4px;
|
4
|
+
|
5
|
+
$font-size-default: 20px;
|
6
|
+
$font-size-small: 0.65em;
|
7
|
+
|
8
|
+
$color-green: #91d98a;
|
9
|
+
$color-blue: #8ac0d9;
|
10
|
+
|
11
|
+
@import url(http://fonts.googleapis.com/css?family=Source+Sans+Pro:300);
|
12
|
+
|
13
|
+
@mixin clearfix {
|
14
|
+
display: block;
|
15
|
+
overflow: hidden;
|
16
|
+
&:before {
|
17
|
+
@include before;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
@mixin prefix($property, $value) {
|
22
|
+
-webkit-#{$property}: #{$value};
|
23
|
+
-ms-#{$property}: #{$value};
|
24
|
+
-moz-#{$property}: #{$value};
|
25
|
+
-o-#{$property}: #{$value};
|
26
|
+
#{$property}: #{$value};
|
27
|
+
}
|
28
|
+
|
29
|
+
@mixin radius($rad: $radius) {
|
30
|
+
@include prefix(border-radius, #{$rad});
|
31
|
+
}
|
32
|
+
|
33
|
+
@mixin before {
|
34
|
+
content: " ";
|
35
|
+
display: block;
|
36
|
+
}
|
37
|
+
|
38
|
+
.padding {
|
39
|
+
padding: $spacing;
|
40
|
+
}
|
41
|
+
|
42
|
+
.clearfix {
|
43
|
+
@include clearfix;
|
44
|
+
}
|
45
|
+
|
46
|
+
.font-size-small {
|
47
|
+
font-size: $font-size-small;
|
48
|
+
}
|
49
|
+
|
50
|
+
#denshobato-message-panel {
|
51
|
+
width: 75%;
|
52
|
+
display: block;
|
53
|
+
margin: 0 auto;
|
54
|
+
}
|
55
|
+
|
56
|
+
.top_menu {
|
57
|
+
background-color: white;
|
58
|
+
border: 1px solid rgba(0, 0, 0, 0.08);
|
59
|
+
padding: 18px 40px 5px 40px;
|
60
|
+
border-radius: 10px 10px 0px 0px;
|
61
|
+
z-index: 999;
|
62
|
+
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);
|
63
|
+
.chat-header {
|
64
|
+
display: block;
|
65
|
+
span {
|
66
|
+
display: block;
|
67
|
+
text-align: center;
|
68
|
+
font-size: 14px;
|
69
|
+
font-style: italic;
|
70
|
+
}
|
71
|
+
p {
|
72
|
+
color: cadetblue;
|
73
|
+
display: inline-grid;
|
74
|
+
text-align: center;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
.refresh-button {
|
78
|
+
float: right;
|
79
|
+
margin: -38px 0px 0px 0px;
|
80
|
+
background: none;
|
81
|
+
border: #a3d063 1px solid;
|
82
|
+
border-radius: 15px;
|
83
|
+
outline: none;
|
84
|
+
&:hover {
|
85
|
+
color: white;
|
86
|
+
background: #a3d063;
|
87
|
+
outline: none;
|
88
|
+
border: none;
|
89
|
+
}
|
90
|
+
}
|
91
|
+
.buttons {
|
92
|
+
margin: 0px 0 0 10px;
|
93
|
+
position: absolute;
|
94
|
+
.button {
|
95
|
+
width: 16px;
|
96
|
+
height: 16px;
|
97
|
+
border-radius: 50%;
|
98
|
+
display: inline-block;
|
99
|
+
margin-right: 10px;
|
100
|
+
position: relative;
|
101
|
+
&.close-button {
|
102
|
+
background-color: #f5886e;
|
103
|
+
&:hover {
|
104
|
+
cursor: pointer;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
&.minimize {
|
108
|
+
background-color: #fdbf68;
|
109
|
+
}
|
110
|
+
&.maximize {
|
111
|
+
background-color: #a3d063;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
// - - - Chat
|
118
|
+
|
119
|
+
.chat-wrapper {
|
120
|
+
min-width: 400px;
|
121
|
+
width: 100%;
|
122
|
+
height: 500px;
|
123
|
+
border: 1px solid rgba(0, 0, 0, 0.08);
|
124
|
+
padding: 20px;
|
125
|
+
position: relative;
|
126
|
+
border-radius: 0px 0px 10px 10px;
|
127
|
+
display: block;
|
128
|
+
overflow-y: scroll;
|
129
|
+
font-family: "Source Sans Pro", sans-serif;
|
130
|
+
font-size: $font-size-default;
|
131
|
+
font-weight: 300;
|
132
|
+
.chat-content {
|
133
|
+
background-color: white;
|
134
|
+
}
|
135
|
+
.chat-image {
|
136
|
+
float: left;
|
137
|
+
@include radius(50%);
|
138
|
+
&.chat-image-default {
|
139
|
+
width: $spacing * 3;
|
140
|
+
height: $spacing * 3;
|
141
|
+
}
|
142
|
+
}
|
143
|
+
.chat-message {
|
144
|
+
margin-bottom: $spacing;
|
145
|
+
width: 100%;
|
146
|
+
padding: 15px;
|
147
|
+
@include clearfix;
|
148
|
+
&:last-of-type {
|
149
|
+
margin-bottom: 0;
|
150
|
+
position: relative;
|
151
|
+
}
|
152
|
+
.full-name-recipient {
|
153
|
+
display: block;
|
154
|
+
font-size: 12px;
|
155
|
+
font-style: italic;
|
156
|
+
color: grey;
|
157
|
+
margin-top: 0px;
|
158
|
+
}
|
159
|
+
.full-name-sender {
|
160
|
+
@extend .full-name-recipient;
|
161
|
+
text-align: right;
|
162
|
+
color: sienna;
|
163
|
+
}
|
164
|
+
.chat-message-wrapper {
|
165
|
+
max-width: 70%;
|
166
|
+
display: table;
|
167
|
+
margin: 0 $spacing;
|
168
|
+
padding-top: $spacing / 2;
|
169
|
+
position: relative;
|
170
|
+
&:before {
|
171
|
+
@include before;
|
172
|
+
width: 0;
|
173
|
+
height: 0;
|
174
|
+
border: 12px solid transparent;
|
175
|
+
top: $spacing;
|
176
|
+
position: absolute;
|
177
|
+
z-index: 2;
|
178
|
+
}
|
179
|
+
p {
|
180
|
+
padding: $spacing / 2 $spacing;
|
181
|
+
color: white;
|
182
|
+
padding: 10px 15px;
|
183
|
+
font-size: 15px;
|
184
|
+
border-top: 1px solid;
|
185
|
+
&:first-of-type {
|
186
|
+
border-top: 0 !important;
|
187
|
+
}
|
188
|
+
}
|
189
|
+
}
|
190
|
+
&.chat-message-recipient {
|
191
|
+
.message-time {
|
192
|
+
font-size: xx-small;
|
193
|
+
display: block;
|
194
|
+
margin: 0 auto;
|
195
|
+
position: absolute;
|
196
|
+
margin-top: -3px;
|
197
|
+
left: 96px;
|
198
|
+
}
|
199
|
+
.message-author {
|
200
|
+
font-size: small;
|
201
|
+
position: absolute;
|
202
|
+
top: 76px;
|
203
|
+
left: 17px;
|
204
|
+
}
|
205
|
+
.chat-message-wrapper,
|
206
|
+
.chat-message-content {
|
207
|
+
float: left;
|
208
|
+
}
|
209
|
+
.chat-message-wrapper {
|
210
|
+
&:before {
|
211
|
+
left: -$spacing;
|
212
|
+
border-right-color: $color-green;
|
213
|
+
}
|
214
|
+
}
|
215
|
+
p {
|
216
|
+
background-color: $color-green;
|
217
|
+
border-top-color: $color-green - 20;
|
218
|
+
}
|
219
|
+
}
|
220
|
+
&.chat-message-sender {
|
221
|
+
.message-time {
|
222
|
+
font-size: xx-small;
|
223
|
+
display: block;
|
224
|
+
margin: 0 auto;
|
225
|
+
position: absolute;
|
226
|
+
margin-top: -3px;
|
227
|
+
right: 96px;
|
228
|
+
}
|
229
|
+
.message-author {
|
230
|
+
font-size: small;
|
231
|
+
position: absolute;
|
232
|
+
top: 77px;
|
233
|
+
right: 10px;
|
234
|
+
}
|
235
|
+
.chat-message-wrapper,
|
236
|
+
.chat-message-content {
|
237
|
+
float: right;
|
238
|
+
}
|
239
|
+
.chat-message-wrapper {
|
240
|
+
&:before {
|
241
|
+
right: -$spacing;
|
242
|
+
border-left-color: $color-blue;
|
243
|
+
}
|
244
|
+
}
|
245
|
+
p {
|
246
|
+
background: $color-blue;
|
247
|
+
border-top-color: $color-blue - 20;
|
248
|
+
}
|
249
|
+
img {
|
250
|
+
float: right;
|
251
|
+
}
|
252
|
+
}
|
253
|
+
.chat-message-content {
|
254
|
+
@include clearfix;
|
255
|
+
@include radius;
|
256
|
+
}
|
257
|
+
.chat-details {
|
258
|
+
clear: both;
|
259
|
+
width: 100%;
|
260
|
+
@include clearfix;
|
261
|
+
.chat-message-localization {
|
262
|
+
color: #8a8a8a;
|
263
|
+
margin: 0px 0px 0px 0px;
|
264
|
+
display: block;
|
265
|
+
font-size: 10px;
|
266
|
+
border: 1px solid rgba(0, 0, 0, 0.23);
|
267
|
+
padding: 2px 0px 2px 7px;
|
268
|
+
border-radius: 37px;
|
269
|
+
width: 51px;
|
270
|
+
&:hover {
|
271
|
+
background: #f1f1f1;
|
272
|
+
color: black;
|
273
|
+
border: 1px solid white;
|
274
|
+
}
|
275
|
+
}
|
276
|
+
}
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
280
|
+
.chat-wrapper::-webkit-scrollbar {
|
281
|
+
width: 6px;
|
282
|
+
}
|
283
|
+
|
284
|
+
.chat-wrapper::-webkit-scrollbar-track, ::-webkit-scrollbar-thumb {
|
285
|
+
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.58);
|
286
|
+
}
|
287
|
+
|
288
|
+
.bottom_wrapper {
|
289
|
+
position: fixed;
|
290
|
+
width: 60%;
|
291
|
+
background-color: white;
|
292
|
+
padding: 10px 10px 0px 10px;
|
293
|
+
z-index: 9;
|
294
|
+
bottom: 23px;
|
295
|
+
.message_input_wrapper {
|
296
|
+
display: inline-block;
|
297
|
+
height: 38px;
|
298
|
+
border-radius: 20px;
|
299
|
+
border: 1px solid #bcbdc0;
|
300
|
+
width: calc(100% - 160px);
|
301
|
+
position: relative;
|
302
|
+
padding: 0 20px;
|
303
|
+
.message_input {
|
304
|
+
border: none;
|
305
|
+
height: 100%;
|
306
|
+
box-sizing: border-box;
|
307
|
+
width: calc(100% - 40px);
|
308
|
+
position: absolute;
|
309
|
+
outline-width: 0;
|
310
|
+
color: gray;
|
311
|
+
}
|
312
|
+
}
|
313
|
+
.send_message {
|
314
|
+
width: 135px;
|
315
|
+
height: 39px;
|
316
|
+
display: inline-block;
|
317
|
+
border-radius: 50px;
|
318
|
+
background-color: #a3d063;
|
319
|
+
border: 2px solid #a3d063;
|
320
|
+
color: white;
|
321
|
+
cursor: pointer;
|
322
|
+
transition: all 0.2s linear;
|
323
|
+
text-align: center;
|
324
|
+
float: right;
|
325
|
+
&:hover {
|
326
|
+
color: #a3d063;
|
327
|
+
background-color: white;
|
328
|
+
}
|
329
|
+
.text {
|
330
|
+
font-size: 18px;
|
331
|
+
font-weight: 300;
|
332
|
+
display: inline-block;
|
333
|
+
line-height: 34px;
|
334
|
+
border: none;
|
335
|
+
background: none;
|
336
|
+
outline: none;
|
337
|
+
}
|
338
|
+
}
|
339
|
+
}
|
340
|
+
|
341
|
+
.chat-message-localization {
|
342
|
+
&:hover {
|
343
|
+
cursor: pointer;
|
344
|
+
}
|
345
|
+
}
|
346
|
+
|
347
|
+
|
348
|
+
.loading {
|
349
|
+
font-size: 16px;
|
350
|
+
font-weight: bold;
|
351
|
+
margin: 100px auto;
|
352
|
+
position: relative;
|
353
|
+
text-align: center;
|
354
|
+
width: 100%;
|
355
|
+
max-width: 200px;
|
356
|
+
p {
|
357
|
+
border-top: solid 1px #c5c5c5;
|
358
|
+
color: #f93841;
|
359
|
+
padding-top: 15px;
|
360
|
+
width: 100%;
|
361
|
+
animation-name: loading;
|
362
|
+
-webkit-animation: loading 2s ease-out infinite;
|
363
|
+
-moz-animation: loading 2s ease-out infinite;
|
364
|
+
animation: loading 2s ease-out infinite;
|
365
|
+
&:before {
|
366
|
+
content: "";
|
367
|
+
-webkit-border-radius: 30px;
|
368
|
+
-moz-border-radius: 30px;
|
369
|
+
-ms-border-radius: 30px;
|
370
|
+
-o-border-radius: 30px;
|
371
|
+
border-radius: 30px;
|
372
|
+
display: inline-block;
|
373
|
+
border-style: solid;
|
374
|
+
border-width: 20px 20px 20px 20px;
|
375
|
+
border-color: #b2060e transparent transparent transparent;
|
376
|
+
position: absolute;
|
377
|
+
top: -20px;
|
378
|
+
left: -10px;
|
379
|
+
animation-name: loading;
|
380
|
+
-webkit-animation: loading 2s ease-out infinite;
|
381
|
+
-moz-animation: loading 2s ease-out infinite;
|
382
|
+
animation: loading 2s ease-out infinite;
|
383
|
+
}
|
384
|
+
}
|
385
|
+
}
|
386
|
+
|
387
|
+
@-moz-keyframes loading {
|
388
|
+
0% {
|
389
|
+
left: -15px;
|
390
|
+
}
|
391
|
+
50% {
|
392
|
+
left: 185px;
|
393
|
+
color: #c5c5c5;
|
394
|
+
}
|
395
|
+
100% {
|
396
|
+
left: -15px;
|
397
|
+
}
|
398
|
+
}
|
399
|
+
|
400
|
+
|
401
|
+
@-webkit-keyframes loading {
|
402
|
+
0% {
|
403
|
+
left: -15px;
|
404
|
+
}
|
405
|
+
50% {
|
406
|
+
left: 185px;
|
407
|
+
color: #c5c5c5;
|
408
|
+
}
|
409
|
+
100% {
|
410
|
+
left: -15px;
|
411
|
+
}
|
412
|
+
}
|
413
|
+
|
414
|
+
|
415
|
+
@keyframes loading {
|
416
|
+
0% {
|
417
|
+
left: -15px;
|
418
|
+
}
|
419
|
+
50% {
|
420
|
+
left: 185px;
|
421
|
+
color: #c5c5c5;
|
422
|
+
}
|
423
|
+
100% {
|
424
|
+
left: -15px;
|
425
|
+
}
|
426
|
+
}
|
427
|
+
|
428
|
+
|
429
|
+
.load-messages {
|
430
|
+
border: 2px #a3d063 solid;
|
431
|
+
padding: 5px 20px 5px 20px;
|
432
|
+
font-size: 16px;
|
433
|
+
margin-bottom: 15px;
|
434
|
+
border-radius: 35px;
|
435
|
+
outline: none;
|
436
|
+
background-color: transparent;
|
437
|
+
&:hover {
|
438
|
+
background-color: #a3d063;
|
439
|
+
color: white;
|
440
|
+
}
|
441
|
+
}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module DenshobatoChatPanel
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
source_root File.dirname(__FILE__)
|
5
|
+
desc 'Install Chat Panel'
|
6
|
+
|
7
|
+
def copy_conversations
|
8
|
+
puts 'Copying assets'
|
9
|
+
|
10
|
+
copy_file './assets/javascripts/denshobato.js', 'vendor/assets/javascripts/denshobato.js'
|
11
|
+
copy_file './assets/stylesheets/denshobato.scss', 'vendor/assets/stylesheets/denshobato.scss'
|
12
|
+
end
|
13
|
+
|
14
|
+
def done
|
15
|
+
puts " =====================================================
|
16
|
+
1. Copy this line to your config/initializers/assets.rb
|
17
|
+
Rails.application.config.assets.precompile += %w( denshobato.js )
|
18
|
+
|
19
|
+
2. Add '@import 'denshobato'; to your application.scss'
|
20
|
+
|
21
|
+
3. In layouts/application.erb include javascript file to the bottom
|
22
|
+
Like this:
|
23
|
+
|
24
|
+
<body>
|
25
|
+
<div class='container'>
|
26
|
+
<%= render 'layouts/header' %>
|
27
|
+
<%= yield %>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<%= javascript_include_tag 'denshobato' %>
|
31
|
+
</body>
|
32
|
+
|
33
|
+
4. Mount API route in your routes.rb
|
34
|
+
mount Denshobato::DenshobatoApi => '/'
|
35
|
+
|
36
|
+
5. Add this helper with arguments to the page with your conversation
|
37
|
+
e.g # => conversation/32
|
38
|
+
|
39
|
+
= render_denshobato_messages(@conversation, current_user)
|
40
|
+
|
41
|
+
When @conversation = Denshobato::Conversation.find(params[:id])
|
42
|
+
and current_user is your signed_in user, e.g Devise current_user etc.
|
43
|
+
|
44
|
+
That's all!
|
45
|
+
=====================================================
|
46
|
+
"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import * as api from '../api/Api';
|
2
|
+
export const CONVERSATION = 'CONVERSATION';
|
3
|
+
|
4
|
+
export function conversation(id, user, klass) {
|
5
|
+
return ((dispatch) => {
|
6
|
+
api.conversation(id, user, klass)
|
7
|
+
.then((response) => dispatch({ type: CONVERSATION, response: response.data }));
|
8
|
+
});
|
9
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import * as api from '../api/Api';
|
2
|
+
export const FETCH = 'FETCH';
|
3
|
+
export const CREATE = 'CREATE';
|
4
|
+
export const DELETE = 'DELETE';
|
5
|
+
export const SHOW_ALL = 'SHOW_ALL';
|
6
|
+
|
7
|
+
export function fetch(id) {
|
8
|
+
return ((dispatch) => {
|
9
|
+
api.fetch(id)
|
10
|
+
.then((messages) => dispatch({ type: FETCH, data: messages.data }));
|
11
|
+
});
|
12
|
+
}
|
13
|
+
|
14
|
+
export function create(body, sender, conversation, senderClass) {
|
15
|
+
return ((dispatch) => {
|
16
|
+
api.createMessage(body, sender, conversation, senderClass)
|
17
|
+
.then((message) => dispatch({ type: CREATE, message: message.data }));
|
18
|
+
});
|
19
|
+
}
|
20
|
+
|
21
|
+
export function deleteMessage(id, conversation) {
|
22
|
+
return ((dispatch) => {
|
23
|
+
api.deleteMessage(id, conversation)
|
24
|
+
.then((response) => dispatch({ type: DELETE, data: response.data, id: id }));
|
25
|
+
});
|
26
|
+
}
|
27
|
+
|
28
|
+
export function showAll() {
|
29
|
+
return { type: SHOW_ALL, data: true };
|
30
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import axios from 'axios';
|
2
|
+
const API = `${window.location.origin}/api`;
|
3
|
+
|
4
|
+
export function fetch(id) {
|
5
|
+
return axios.get(`${API}/messages/get_conversation_messages?id=${id}`);
|
6
|
+
|
7
|
+
}
|
8
|
+
|
9
|
+
export function conversation(id, user, klass) {
|
10
|
+
return axios.get(`${API}/conversations/conversation_info?id=${id}&user=${user}&class=${klass}`);
|
11
|
+
}
|
12
|
+
|
13
|
+
export function createMessage(body, sender, conversation, senderClass) {
|
14
|
+
return axios.post(`${API}/messages/create_message`, { message: { body: body, conversation_id: conversation, sender: sender, sender_class: senderClass } });
|
15
|
+
}
|
16
|
+
|
17
|
+
export function deleteMessage(id, conversation) {
|
18
|
+
return axios.delete(`${API}/messages/delete_message?id=${id}&conversation=${conversation}`);
|
19
|
+
}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
import React, { Component } from 'react';
|
2
|
+
import store from '../store/Store';
|
3
|
+
import { actions } from '../actions/Index';
|
4
|
+
|
5
|
+
const room = document.getElementById('denshobato-message-panel');
|
6
|
+
|
7
|
+
export default class Message extends Component {
|
8
|
+
static propTypes = {
|
9
|
+
message: React.PropTypes.shape({
|
10
|
+
id: React.PropTypes.number.isRequired,
|
11
|
+
body: React.PropTypes.string.isRequired,
|
12
|
+
author: React.PropTypes.string.isRequired,
|
13
|
+
}),
|
14
|
+
sender: React.PropTypes.shape({
|
15
|
+
author: React.PropTypes.string,
|
16
|
+
conversationId: React.PropTypes.number,
|
17
|
+
}),
|
18
|
+
};
|
19
|
+
|
20
|
+
deleteMessage = () => {
|
21
|
+
let result = confirm('Delete Message from your conversation?');
|
22
|
+
if (result) {
|
23
|
+
store.dispatch(actions.messages.deleteMessage(this.props.message.id, this.props.sender.conversationId));
|
24
|
+
};
|
25
|
+
};
|
26
|
+
|
27
|
+
render() {
|
28
|
+
const { message, sender } = this.props;
|
29
|
+
const cssClass = (message.author == sender.author) ? 'recipient' : 'sender';
|
30
|
+
|
31
|
+
return (
|
32
|
+
<div className={`chat-message chat-message-${cssClass}`}>
|
33
|
+
<span className='message-author'>{message.full_name}</span>
|
34
|
+
<img className='chat-image chat-image-default' src={message.avatar} />
|
35
|
+
<span className='message-time'>{message.time}</span>
|
36
|
+
<div className='chat-message-wrapper'>
|
37
|
+
<div className='chat-message-content'>
|
38
|
+
<p>{message.body}</p>
|
39
|
+
</div>
|
40
|
+
<div className='chat-details'>
|
41
|
+
<span className='chat-message-localization font-size-small' onClick={this.deleteMessage}>Remove</span>
|
42
|
+
</div>
|
43
|
+
</div>
|
44
|
+
</div>
|
45
|
+
);
|
46
|
+
}
|
47
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import React, { Component } from 'react';
|
2
|
+
import { reduxForm } from 'redux-form';
|
3
|
+
import store from '../store/Store';
|
4
|
+
|
5
|
+
export default class MessageForm extends Component {
|
6
|
+
static propTypes = {
|
7
|
+
handleSubmit: React.PropTypes.func.isRequired,
|
8
|
+
fields: React.PropTypes.shape({
|
9
|
+
body: React.PropTypes.object.isRequired,
|
10
|
+
senderClass: React.PropTypes.object.isRequired,
|
11
|
+
}),
|
12
|
+
};
|
13
|
+
|
14
|
+
render() {
|
15
|
+
const { fields: { body, senderClass }, handleSubmit } = this.props;
|
16
|
+
return (
|
17
|
+
<div>
|
18
|
+
<form onSubmit={handleSubmit}>
|
19
|
+
<div className="bottom_wrapper clearfix">
|
20
|
+
<div className="message_input_wrapper">
|
21
|
+
<input className="message_input" placeholder="Type your message here..." {...body}/>
|
22
|
+
</div>
|
23
|
+
<div className="send_message">
|
24
|
+
<div className="icon"></div>
|
25
|
+
<button onclick={handleSubmit} className="text">Send</button>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
</form>
|
29
|
+
</div>
|
30
|
+
);
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
MessageForm = reduxForm({
|
35
|
+
form: 'message-form',
|
36
|
+
fields: ['body', 'senderClass'],
|
37
|
+
})(MessageForm);
|