Skip to content

Commit 5d2edb4

Browse files
committed
Merge pull request #67 from nus-mtp/admin-stream-comments
Admin - Stream Comments
2 parents 93ed8eb + a843e1f commit 5d2edb4

9 files changed

Lines changed: 100 additions & 20 deletions

File tree

app_server/Gruntfile.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,6 @@ module.exports = function(grunt) {
7373
{
7474
src: './node_modules/materialize-css/dist/js/materialize.min.js',
7575
dest: './public/js/materialize.js'
76-
},
77-
{
78-
src: './node_modules/shaka-player/shaka-player.compiled.js',
79-
dest: './public/js/shaka.js'
8076
}
8177
]
8278
}

app_server/app/adapters/socket/SocketAdapter.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,19 @@ Class.__handleIdentifyEvent = function(socket) {
4545
Iron.unsealAsync(cookieData, ServerConfig.cookiePassword, Iron.defaults)
4646
.then((credentials) => {
4747
if (!credentials || credentials instanceof Error) {
48-
logger.error('Error decryping cookie from <identify> message');
48+
logger.error('Error decrypting cookie from <identify> message');
4949
return socket.emit('identify', 'ERR');
5050
}
5151

5252
let Authenticator = this.server.app.authenticator;
53-
return Authenticator.validateAccount(this.server, credentials)
53+
54+
let request = socket.request;
55+
if (credentials.scope &&
56+
credentials.scope.indexOf(Authenticator.SCOPE.ADMIN.STREAMS) > -1) {
57+
request.headers['x-csrf-token'] = request.headers['cookie'];
58+
}
59+
60+
return Authenticator.validateAccount(this.server, credentials, request)
5461
.then((result) => {
5562
if (!result || result instanceof Error) {
5663
logger.error(result);

app_server/public/index.htm

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
<body>
1010
<script src="js/jquery.js"></script>
1111
<script src="js/materialize.js"></script>
12-
<script src="js/shaka.js"></script>
1312
<script src="js/app.js"></script>
1413
</body>
1514
</html>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
$comment-line-height: 1.2rem;
2+
3+
#comments {
4+
line-height: $comment-line-height;
5+
height: $comment-line-height * 15;
6+
overflow: auto;
7+
margin-top: $comment-line-height;
8+
9+
.comment-row {
10+
margin-bottom: $comment-line-height / 2;
11+
12+
a {
13+
color: #000000;
14+
font-weight: bold;
15+
}
16+
}
17+
}

app_server/public/src/css/style.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@
3333
@import "partials/pagination";
3434
@import "partials/tables";
3535
@import "partials/message";
36+
@import "partials/comments";
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const m = require('mithril');
2+
const App = require('../app');
3+
4+
const Comment = module.exports = function (data) {
5+
this.id = m.prop(data.commentId);
6+
this.msg = m.prop(data.content);
7+
this.time = m.prop(new Date(data.createdAt));
8+
this.user = m.prop(data.alias || data.userId);
9+
this.userId = m.prop(data.userId);
10+
};
11+
12+
Comment.list = (streamId) =>
13+
App.request({
14+
method: 'GET',
15+
url: '../api/comments/streams/' + streamId,
16+
type: Comment
17+
});

app_server/public/src/js/modules/models/stream.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ const Stream = module.exports = function (data) {
77
this.appInstance = m.prop(data.appInstance);
88
this.link = m.prop(data.viewLink);
99
this.thumbnail = m.prop(data.thumbnailLink);
10-
this.room = m.prop(data.roomId);
10+
this.room = m.prop(data.appInstance);
1111
this.title = m.prop(data.title);
1212
this.startDateTime = m.prop(new Date(data.createdAt));
13-
this.endDateTime = m.prop(new Date(data.endedAt));
13+
this.endDateTime = m.prop(data.endedAt ? new Date(data.endedAt) : null);
1414
this.viewers = m.prop(data.totalViewers);
1515
this.stickers = m.prop(data.totalStickers);
1616
this.live = m.prop(data.live);

app_server/public/src/js/modules/pages/stream.js

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
/*global shaka*/
2-
31
const m = require('mithril');
2+
const shaka = require('shaka-player');
3+
const io = require('socket.io-client');
44

5+
const CommentModel = require('../models/comment');
56
const StreamModel = require('../models/stream');
67

78
const datetime = require('../utils/dateFormat');
89

9-
const Stream = module.exports = {};
10+
const Stream = module.exports = {
11+
stream: m.prop(),
12+
comments: m.prop([]),
13+
socket: m.prop()
14+
};
1015

11-
Stream.stream = m.prop();
16+
const MAX_COMMENTS = 1000;
1217

1318
const initPlayer = function () {
1419
shaka.polyfill.installAll();
@@ -34,10 +39,41 @@ const stopStream = function () {
3439
);
3540
};
3641

42+
const initComments = function () {
43+
Stream.socket(io());
44+
45+
Stream.socket().emit('identify', document.cookie);
46+
Stream.socket().emit('join', Stream.stream().room());
47+
Stream.socket().on('comment', function (res) {
48+
m.startComputation();
49+
Stream.comments().unshift(new CommentModel({
50+
userId: res.userId,
51+
alias: res.alias,
52+
content: res.message,
53+
createdAt: res.time
54+
}));
55+
while (Stream.comments().length > MAX_COMMENTS) {
56+
Stream.comments().pop();
57+
}
58+
m.endComputation();
59+
});
60+
};
61+
62+
const destroyComments = function () {
63+
Stream.socket().emit('leave', Stream.stream().room());
64+
};
65+
3766
Stream.controller = function () {
3867
let id = m.route.param('id') || -1;
3968

40-
StreamModel.get(id).then(Stream.stream);
69+
m.sync([
70+
StreamModel.get(id).then(Stream.stream),
71+
CommentModel.list(id).then(Stream.comments)
72+
]).then(initComments);
73+
74+
return {
75+
onunload: destroyComments
76+
};
4177
};
4278

4379
Stream.view = function () {
@@ -63,13 +99,20 @@ Stream.view = function () {
6399
m('div.row col s9', [
64100
m('div.col s12', stream.user().alias()),
65101
m('div.col s12', 'Start: ' + datetime.toShortDateTime(stream.startDateTime())),
66-
m('div.col s12', 'End: ' + datetime.toShortDateTime(stream.endDateTime()))
102+
stream.endDateTime() ?
103+
m('div.col s12', 'End: ' + datetime.toShortDateTime(stream.endDateTime())) :
104+
null
67105
])
68106
]),
69107
m('div.row', [
70108
m('div.col s12', stream.description()),
71109
m('button.btn col s12', {onclick: stopStream}, 'Stop Stream'),
72-
m('div.col s12', 'comment stream here')
110+
m('div#comments.col s12',
111+
Stream.comments().map((c) => m('div.comment-row', [
112+
'[' + datetime.toShortTime(c.time()) + '] ',
113+
m('a[href="/users/view/' + c.userId() + '"]', {config: m.route}, c.user() + ':'),
114+
' ' + c.msg()
115+
])))
73116
])
74117
])
75118
])

app_server/public/src/js/modules/utils/dateFormat.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
* 'timeFormat' formats time into more readable formats.
33
*/
44
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
5+
const to2Digits = (i) => i < 10 ? '0' + i : i;
56
const timeFormat = module.exports = {
6-
toShortDateTime: function (d) {
7-
return d.getDay() + ' ' + months[d.getMonth()] + ' ' + d.getFullYear() + ', ' +
8-
d.getHours() + ':' + d.getMinutes();
9-
}
7+
toShortDate: (d) => to2Digits(d.getDay()) + ' ' + months[d.getMonth()] + ' ' + d.getFullYear(),
8+
toShortTime: (d) => to2Digits(d.getHours()) + ':' + to2Digits(d.getMinutes()),
9+
toShortDateTime: (d) => timeFormat.toShortDate(d) + ', ' + timeFormat.toShortTime(d)
1010
};

0 commit comments

Comments
 (0)