* wip
This commit is contained in:
parent
8900af5196
commit
2e95682b10
|
|
@ -0,0 +1,23 @@
|
||||||
|
ActiveAdmin.register JamRuby::ChatMessage, :as => 'ChatMessage' do
|
||||||
|
# Note: a lame thing is it's not obvious how to make it search on email instead of user_id.
|
||||||
|
filter :music_session_id
|
||||||
|
filter :user_id
|
||||||
|
|
||||||
|
menu :parent => 'Misc'
|
||||||
|
|
||||||
|
config.per_page = 200
|
||||||
|
|
||||||
|
config.sort_order = 'created_at DESC'
|
||||||
|
|
||||||
|
index do
|
||||||
|
column 'User' do |oo| link_to(oo.user.email, oo.user.admin_url, {:title => oo.user.email}) end
|
||||||
|
column "Timestamp" do |post|
|
||||||
|
(post.created_at).strftime('%b %d %Y, %H:%M')
|
||||||
|
end
|
||||||
|
column "Message" do |post|
|
||||||
|
post.message
|
||||||
|
end
|
||||||
|
actions
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,2 +1,4 @@
|
||||||
ALTER TABLE chat_messages ADD COLUMN channel VARCHAR(128) NOT NULL DEFAULT 'session';
|
ALTER TABLE chat_messages ADD COLUMN channel VARCHAR(128) NOT NULL DEFAULT 'session';
|
||||||
ADD INDEX
|
CREATE INDEX chat_messages_idx_channels ON chat_messages(channel);
|
||||||
|
CREATE INDEX chat_messages_idx_created_at ON chat_messages(created_at);
|
||||||
|
CREATE INDEX chat_messages_idx_music_session_id ON chat_messages(music_session_id);
|
||||||
|
|
@ -29,10 +29,14 @@ module JamRuby
|
||||||
start = params[:start].presence
|
start = params[:start].presence
|
||||||
start = start.to_i || 0
|
start = start.to_i || 0
|
||||||
|
|
||||||
music_session_id = params[:music_session]
|
query = ChatMessage.where('channel = ?', params[:channel])
|
||||||
|
|
||||||
query = ChatMessage.where('music_session_id = ?', music_session_id)
|
if params.has_key? (:music_session)
|
||||||
.offset(start).limit(limit)
|
music_session_id = params[:music_session]
|
||||||
|
query = ChatMessage.where('music_session_id = ?', music_session_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
query = query.offset(start).limit(limit).order('created_at DESC')
|
||||||
|
|
||||||
if query.length == 0
|
if query.length == 0
|
||||||
[query, nil]
|
[query, nil]
|
||||||
|
|
|
||||||
|
|
@ -1230,7 +1230,11 @@ module JamRuby
|
||||||
user.errors.add(:email, "is not real")
|
user.errors.add(:email, "is not real")
|
||||||
end
|
end
|
||||||
elsif result == "risky" || result == "unknown"
|
elsif result == "risky" || result == "unknown"
|
||||||
user.email_needs_verification = true
|
if response.body["disposable"]
|
||||||
|
user.errors.add(:email, "is disposable address")
|
||||||
|
else
|
||||||
|
user.email_needs_verification = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
user.email_needs_verification = false
|
user.email_needs_verification = false
|
||||||
|
|
|
||||||
|
|
@ -295,11 +295,15 @@
|
||||||
function markAway() {
|
function markAway() {
|
||||||
logger.debug("sleep again!")
|
logger.debug("sleep again!")
|
||||||
active = false;
|
active = false;
|
||||||
|
context.UserActivityActions.setActive(active)
|
||||||
|
var userStatus = msg_factory.userStatus(false, null);
|
||||||
|
server.send(userStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
function activityCheck() {
|
function activityCheck() {
|
||||||
var timeoutTime = 300000; // 5 * 1000 * 60 , 5 minutes
|
var timeoutTime = 300000; // 5 * 1000 * 60 , 5 minutes
|
||||||
active = true;
|
active = true;
|
||||||
|
context.UserActivityActions.setActive(active)
|
||||||
activityTimeout = setTimeout(markAway, timeoutTime);
|
activityTimeout = setTimeout(markAway, timeoutTime);
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('body').bind('mousedown keydown touchstart focus', function(event) {
|
$('body').bind('mousedown keydown touchstart focus', function(event) {
|
||||||
|
|
@ -316,6 +320,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
active = true;
|
active = true;
|
||||||
|
context.UserActivityActions.setActive(active)
|
||||||
activityTimeout = setTimeout(markAway, timeoutTime);
|
activityTimeout = setTimeout(markAway, timeoutTime);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
(function(context,$) {
|
(function (context, $) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
context.JK = context.JK || {};
|
context.JK = context.JK || {};
|
||||||
context.JK.ChatPanel = function(app) {
|
context.JK.ChatPanel = function (app) {
|
||||||
var logger = context.JK.logger;
|
var logger = context.JK.logger;
|
||||||
var rest = context.JK.Rest();
|
var rest = context.JK.Rest();
|
||||||
var $panel = null;
|
var $panel = null;
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
var $errorMsg = null;
|
var $errorMsg = null;
|
||||||
var sendingMessage = false;
|
var sendingMessage = false;
|
||||||
var showing = false;
|
var showing = false;
|
||||||
var fullyInitialized = false;
|
var fullyInitialized = true;
|
||||||
var renderQueue = [];
|
var renderQueue = [];
|
||||||
var sidebar = null;
|
var sidebar = null;
|
||||||
var user = null;
|
var user = null;
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
var next = null;
|
var next = null;
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
fullyInitialized = false;
|
fullyInitialized = true;
|
||||||
renderQueue = [];
|
renderQueue = [];
|
||||||
sendingMessage = false;
|
sendingMessage = false;
|
||||||
//$chatMessages.empty();
|
//$chatMessages.empty();
|
||||||
|
|
@ -45,28 +45,28 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendMessage() {
|
function sendMessage() {
|
||||||
if(!context.JK.JamServer.connected) {
|
if (!context.JK.JamServer.connected) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var msg = $textBox.val();
|
var msg = $textBox.val();
|
||||||
if(!msg || msg == '') {
|
if (!msg || msg == '') {
|
||||||
// don't bother the server with empty messages
|
// don't bother the server with empty messages
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!sendingMessage) {
|
if (!sendingMessage) {
|
||||||
sendingMessage = true;
|
sendingMessage = true;
|
||||||
|
|
||||||
rest.createChatMessage(buildMessage())
|
rest.createChatMessage(buildMessage())
|
||||||
.done(function() {
|
.done(function () {
|
||||||
$textBox.val('');
|
$textBox.val('');
|
||||||
renderMessage(msg, user.id, user.name, new Date().toISOString(), true);
|
renderMessage(msg, user.id, user.name, new Date().toISOString(), true);
|
||||||
})
|
})
|
||||||
.fail(function(jqXHR) {
|
.fail(function (jqXHR) {
|
||||||
app.notifyServerError(jqXHR, 'Unable to Send Chat Message');
|
app.notifyServerError(jqXHR, 'Unable to Send Chat Message');
|
||||||
})
|
})
|
||||||
.always(function() {
|
.always(function () {
|
||||||
sendingMessage = false;
|
sendingMessage = false;
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -84,9 +84,9 @@
|
||||||
sender: senderId == user.id ? 'me' : senderName,
|
sender: senderId == user.id ? 'me' : senderName,
|
||||||
sent: sent
|
sent: sent
|
||||||
};
|
};
|
||||||
var txt = $(context._.template($('#template-chat-message').html(), options, { variable: 'data' }));
|
var txt = $(context._.template($('#template-chat-message').html(), options, {variable: 'data'}));
|
||||||
txt.find('.timeago').timeago();
|
txt.find('.timeago').timeago();
|
||||||
if(append) {
|
if (append) {
|
||||||
$chatMessages.append(txt);
|
$chatMessages.append(txt);
|
||||||
scrollToBottom();
|
scrollToBottom();
|
||||||
}
|
}
|
||||||
|
|
@ -96,7 +96,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function drainQueue() {
|
function drainQueue() {
|
||||||
context._.each(renderQueue, function(msg) {
|
context._.each(renderQueue, function (msg) {
|
||||||
renderMessage(msg.message, msg.user_id, msg.user_name, msg.sent, true);
|
renderMessage(msg.message, msg.user_id, msg.user_name, msg.sent, true);
|
||||||
});
|
});
|
||||||
renderQueue = [];
|
renderQueue = [];
|
||||||
|
|
@ -128,7 +128,7 @@
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
pasteIntoInput(this, "\n");
|
pasteIntoInput(this, "\n");
|
||||||
}
|
}
|
||||||
else if(evt.keyCode == 13 && !evt.shiftKey){
|
else if (evt.keyCode == 13 && !evt.shiftKey) {
|
||||||
sendMessage();
|
sendMessage();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +140,7 @@
|
||||||
$textBox.keydown(handleEnter);
|
$textBox.keydown(handleEnter);
|
||||||
$sendChatMessageBtn.click(sendMessage);
|
$sendChatMessageBtn.click(sendMessage);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$form.submit(null);
|
$form.submit(null);
|
||||||
$textBox.keydown(null);
|
$textBox.keydown(null);
|
||||||
$sendChatMessageBtn.click(null);
|
$sendChatMessageBtn.click(null);
|
||||||
|
|
@ -150,26 +150,21 @@
|
||||||
|
|
||||||
// called from sidebar when messages come in
|
// called from sidebar when messages come in
|
||||||
function chatMessageReceived(payload) {
|
function chatMessageReceived(payload) {
|
||||||
//if(fullyInitialized) {
|
if (fullyInitialized) {
|
||||||
//if (isChatPanelVisible()) {
|
if (isChatPanelVisible()) {
|
||||||
// renderMessage(payload.msg, payload.sender_id, payload.sender_name, payload.created_at, true);
|
|
||||||
//}
|
}
|
||||||
//else {
|
else {
|
||||||
highlightCount();
|
highlightCount();
|
||||||
incrementChatCount();
|
incrementChatCount();
|
||||||
// renderQueue.push({message: payload.msg, user_id: payload.sender_id, user_name: payload.sender_name, sent: payload.created_at});
|
|
||||||
|
|
||||||
context.jamClient.UserAttention(true);
|
context.jamClient.UserAttention(true);
|
||||||
//}
|
}
|
||||||
//}
|
}
|
||||||
//else {
|
|
||||||
// renderQueue.push({message: payload.msg, user_id: payload.sender_id, user_name: payload.sender_name, sent: payload.created_at});
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerChatMessage(bind) {
|
function registerChatMessage(bind) {
|
||||||
if (bind && bind == true) {
|
if (bind && bind == true) {
|
||||||
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.CHAT_MESSAGE, function(header, payload) {
|
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.CHAT_MESSAGE, function (header, payload) {
|
||||||
logger.debug("Handling CHAT_MESSAGE msg " + JSON.stringify(payload));
|
logger.debug("Handling CHAT_MESSAGE msg " + JSON.stringify(payload));
|
||||||
chatMessageReceived(payload);
|
chatMessageReceived(payload);
|
||||||
context.ChatActions.msgReceived(payload);
|
context.ChatActions.msgReceived(payload);
|
||||||
|
|
@ -185,10 +180,13 @@
|
||||||
function opened() {
|
function opened() {
|
||||||
lowlightCount();
|
lowlightCount();
|
||||||
setCount(0);
|
setCount(0);
|
||||||
|
|
||||||
drainQueue();
|
drainQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fullyOpened() {
|
||||||
|
context.ChatActions.fullyOpened()
|
||||||
|
}
|
||||||
|
|
||||||
function sessionStarted(e, data) {
|
function sessionStarted(e, data) {
|
||||||
$sessionId = data.session.id;
|
$sessionId = data.session.id;
|
||||||
|
|
||||||
|
|
@ -197,36 +195,23 @@
|
||||||
//$chatMessagesScroller.show();
|
//$chatMessagesScroller.show();
|
||||||
$errorMsg.hide();
|
$errorMsg.hide();
|
||||||
$panel.find('.panel-header').trigger('click');
|
$panel.find('.panel-header').trigger('click');
|
||||||
$panel.on('open', opened);
|
|
||||||
$panel.find('.btn-next-pager').attr('href', '/api/sessions/' + $sessionId + '/chats?page=1');
|
$panel.find('.btn-next-pager').attr('href', '/api/sessions/' + $sessionId + '/chats?page=1');
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
context.ChatActions.sessionStarted($sessionId);
|
context.ChatActions.sessionStarted($sessionId);
|
||||||
|
showing = true
|
||||||
// load previous chat messages
|
fullyInitialized = true;
|
||||||
rest.getChatMessages(buildQuery())
|
drainQueue();
|
||||||
.done(function (response) {
|
|
||||||
//handleChatResponse(response);
|
|
||||||
|
|
||||||
context.ChatActions.loadMessages('session', response)
|
|
||||||
//scrollToBottom(true);
|
|
||||||
showing = true;
|
|
||||||
fullyInitialized = true;
|
|
||||||
drainQueue();
|
|
||||||
})
|
|
||||||
.fail(function (jqXHR) {
|
|
||||||
app.notifyServerError(jqXHR, 'Unable to Load Session Conversations')
|
|
||||||
});
|
|
||||||
|
|
||||||
events(true);
|
events(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function sessionStopped(e, data) {
|
function sessionStopped(e, data) {
|
||||||
// open chat panel
|
// open chat panel
|
||||||
$chatSender.hide();
|
//$chatSender.hide();
|
||||||
$chatMessagesScroller.hide();
|
//$chatMessagesScroller.hide();
|
||||||
$errorMsg.show();
|
//$errorMsg.show();
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
events(false);
|
events(false);
|
||||||
|
|
@ -254,9 +239,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildQuery() {
|
function buildQuery() {
|
||||||
var query = {type: 'CHAT_MESSAGE', music_session: $sessionId, limit:LIMIT, page:currentPage};
|
var query = {type: 'CHAT_MESSAGE', music_session: $sessionId, limit: LIMIT, page: currentPage};
|
||||||
|
|
||||||
if(next) {
|
if (next) {
|
||||||
query.start = next;
|
query.start = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -274,11 +259,11 @@
|
||||||
|
|
||||||
renderChats(response.chats);
|
renderChats(response.chats);
|
||||||
|
|
||||||
if(response.next == null) {
|
if (response.next == null) {
|
||||||
// if we less results than asked for, end searching
|
// if we less results than asked for, end searching
|
||||||
$chatMessagesScroller.infinitescroll('pause');
|
$chatMessagesScroller.infinitescroll('pause');
|
||||||
|
|
||||||
if(currentPage > 0) {
|
if (currentPage > 0) {
|
||||||
// there are bugs with infinitescroll not removing the 'loading'.
|
// there are bugs with infinitescroll not removing the 'loading'.
|
||||||
// it's most noticeable at the end of the list, so whack all such entries
|
// it's most noticeable at the end of the list, so whack all such entries
|
||||||
$('.infinite-scroll-loader').remove();
|
$('.infinite-scroll-loader').remove();
|
||||||
|
|
@ -306,10 +291,10 @@
|
||||||
msg: $('<div class="infinite-scroll-loader">Loading ...</div>'),
|
msg: $('<div class="infinite-scroll-loader">Loading ...</div>'),
|
||||||
img: '/assets/shared/spinner-32.gif'
|
img: '/assets/shared/spinner-32.gif'
|
||||||
},
|
},
|
||||||
path: function(page) {
|
path: function (page) {
|
||||||
return '/api/sessions/' + $sessionId + '/chats?' + $.param(buildQuery());
|
return '/api/sessions/' + $sessionId + '/chats?' + $.param(buildQuery());
|
||||||
}
|
}
|
||||||
},function(json, opts) {
|
}, function (json, opts) {
|
||||||
handleChatResponse(json);
|
handleChatResponse(json);
|
||||||
});
|
});
|
||||||
$chatMessagesScroller.infinitescroll('resume');
|
$chatMessagesScroller.infinitescroll('resume');
|
||||||
|
|
@ -321,30 +306,26 @@
|
||||||
$contents = $panel.find('.chatcontents');
|
$contents = $panel.find('.chatcontents');
|
||||||
$chatMessagesScroller = $panel.find('.chat-list-scroller');
|
$chatMessagesScroller = $panel.find('.chat-list-scroller');
|
||||||
$count = $panel.find('#sidebar-chat-count');
|
$count = $panel.find('#sidebar-chat-count');
|
||||||
//$chatMessages = $panel.find('.previous-chat-list');
|
|
||||||
//$sendChatMessageBtn = $panel.find('.btn-send-chat-message');
|
|
||||||
//$chatSender = $panel.find('.chat-sender');
|
|
||||||
//$form = $panel.find('.chat-message-form');
|
|
||||||
//$textBox = $form.find('textarea');
|
|
||||||
$errorMsg = $panel.find('.chat-status');
|
$errorMsg = $panel.find('.chat-status');
|
||||||
|
|
||||||
$errorMsg.show();
|
$errorMsg.show();
|
||||||
//$chatSender.hide();
|
|
||||||
//$chatMessagesScroller.hide();
|
|
||||||
|
|
||||||
|
$panel.on('open', opened);
|
||||||
|
$panel.on('fullyOpen', fullyOpened);
|
||||||
app.user()
|
app.user()
|
||||||
.done(function (userDetail) {
|
.done(function (userDetail) {
|
||||||
user = userDetail;
|
user = userDetail;
|
||||||
|
|
||||||
registerChatMessage(true);
|
registerChatMessage(true);
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.initialize = initialize;
|
this.initialize = initialize;
|
||||||
this.sessionStarted = sessionStarted;
|
this.sessionStarted = sessionStarted;
|
||||||
this.sessionStopped = sessionStopped;
|
this.sessionStopped = sessionStopped;
|
||||||
this.registerChatMessage = registerChatMessage;
|
this.registerChatMessage = registerChatMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
})(window,jQuery);
|
})(window, jQuery);
|
||||||
|
|
@ -1711,11 +1711,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChatMessages(options) {
|
function getChatMessages(options) {
|
||||||
var musciSessionId = options["music_session"];
|
|
||||||
delete options["music_session"];
|
|
||||||
return $.ajax({
|
return $.ajax({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
url: '/api/sessions/' + musciSessionId + '/chats?' + $.param(options),
|
url: '/api/chat?' + $.param(options),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
contentType: 'application/json'
|
contentType: 'application/json'
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,9 @@
|
||||||
$('[layout-panel="contents"]').css({"height": "1px"});
|
$('[layout-panel="contents"]').css({"height": "1px"});
|
||||||
$expandedPanelContents.show();
|
$expandedPanelContents.show();
|
||||||
$expandedPanel.triggerHandler('open')
|
$expandedPanel.triggerHandler('open')
|
||||||
$expandedPanelContents.animate({"height": expandedPanelHeight + "px"}, opts.animationDuration);
|
$expandedPanelContents.animate({"height": expandedPanelHeight + "px"}, opts.animationDuration, function() {
|
||||||
|
$expandedPanel.triggerHandler('fullyOpen')
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function layoutHeader(screenWidth, screenHeight) {
|
function layoutHeader(screenWidth, screenHeight) {
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,20 @@
|
||||||
//= require_directory ./react-components/helpers
|
//= require_directory ./react-components/helpers
|
||||||
//= require_directory ./react-components/actions
|
//= require_directory ./react-components/actions
|
||||||
//= require ./react-components/stores/AppStore
|
//= require ./react-components/stores/AppStore
|
||||||
|
//= require ./react-components/stores/UserStore
|
||||||
|
//= require ./react-components/stores/UserActivityStore
|
||||||
//= require ./react-components/stores/InstrumentStore
|
//= require ./react-components/stores/InstrumentStore
|
||||||
//= require ./react-components/stores/LanguageStore
|
//= require ./react-components/stores/LanguageStore
|
||||||
//= require ./react-components/stores/GenreStore
|
//= require ./react-components/stores/GenreStore
|
||||||
//= require ./react-components/stores/SubjectStore
|
//= require ./react-components/stores/SubjectStore
|
||||||
//= require ./react-components/stores/ProfileStore
|
//= require ./react-components/stores/ProfileStore
|
||||||
//= require ./react-components/stores/PlatformStore
|
//= require ./react-components/stores/PlatformStore
|
||||||
//= require ./react-components/stores/ChatStore
|
|
||||||
//= require ./react-components/stores/BrowserMediaStore
|
//= require ./react-components/stores/BrowserMediaStore
|
||||||
//= require ./react-components/stores/RecordingStore
|
//= require ./react-components/stores/RecordingStore
|
||||||
//= require ./react-components/stores/VideoStore
|
//= require ./react-components/stores/VideoStore
|
||||||
//= require ./react-components/stores/SessionStore
|
//= require ./react-components/stores/SessionStore
|
||||||
//= require ./react-components/stores/SessionStatsStore
|
//= require ./react-components/stores/SessionStatsStore
|
||||||
|
//= require ./react-components/stores/ChatStore
|
||||||
//= require ./react-components/stores/MixerStore
|
//= require ./react-components/stores/MixerStore
|
||||||
//= require ./react-components/stores/ConfigureTracksStore
|
//= require ./react-components/stores/ConfigureTracksStore
|
||||||
//= require ./react-components/stores/JamTrackStore
|
//= require ./react-components/stores/JamTrackStore
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,6 @@ ChatActions = @ChatActions
|
||||||
return false
|
return false
|
||||||
|
|
||||||
msg = @textBox.val()
|
msg = @textBox.val()
|
||||||
logger.debug("text box: " + msg)
|
|
||||||
if !msg? || msg == ''
|
if !msg? || msg == ''
|
||||||
# don't bother the server with empty messages
|
# don't bother the server with empty messages
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -100,7 +99,10 @@ ChatActions = @ChatActions
|
||||||
@sendingMessage = false
|
@sendingMessage = false
|
||||||
|
|
||||||
sendMsgFail: (jqXHR) ->
|
sendMsgFail: (jqXHR) ->
|
||||||
@app.notifyServerError(jqXHR, 'Unable to Send Chat Message')
|
if jqXHR.status == 404
|
||||||
|
@app.notifyServerError(jqXHR, 'Session chat is only available while in session.')
|
||||||
|
else
|
||||||
|
@app.notifyServerError(jqXHR, 'Unable to Send Chat Message')
|
||||||
@sendingMessage = false
|
@sendingMessage = false
|
||||||
|
|
||||||
handleSendMessage: (e) ->
|
handleSendMessage: (e) ->
|
||||||
|
|
@ -118,9 +120,9 @@ ChatActions = @ChatActions
|
||||||
speed = 'slow'
|
speed = 'slow'
|
||||||
@lastChannel = @state.channel
|
@lastChannel = @state.channel
|
||||||
|
|
||||||
speed = 0 #slow
|
#speed = 0 #slow
|
||||||
$scroller = @root.find('.chat-list-scroller')
|
$scroller = @root.find('.chat-list-scroller')
|
||||||
@root.animate({scrollTop: $scroller[0].scrollHeight}, speed)
|
$scroller.animate({scrollTop: $scroller[0].scrollHeight}, speed)
|
||||||
|
|
||||||
pasteIntoInput: (el, text) ->
|
pasteIntoInput: (el, text) ->
|
||||||
el.focus();
|
el.focus();
|
||||||
|
|
@ -138,8 +140,7 @@ ChatActions = @ChatActions
|
||||||
handleEnter: (evt) ->
|
handleEnter: (evt) ->
|
||||||
if evt.keyCode == 13 && evt.shiftKey
|
if evt.keyCode == 13 && evt.shiftKey
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
@pasteIntoInput(this, "\n")
|
@pasteIntoInput($(evt.target).get(0), "\n")
|
||||||
else if evt.keyCode == 13 && !evt.shiftKey
|
else if evt.keyCode == 13 && !evt.shiftKey
|
||||||
@sendMessage()
|
@sendMessage()
|
||||||
return false
|
|
||||||
})
|
})
|
||||||
|
|
@ -37,7 +37,7 @@ rest = context.JK.Rest()
|
||||||
playJamTracks = []
|
playJamTracks = []
|
||||||
|
|
||||||
for jamTrack in @state.purchasedJamTracks
|
for jamTrack in @state.purchasedJamTracks
|
||||||
playJamTracks.push `<tr className="play-jamtrack"><td>
|
playJamTracks.push `<tr key={jamTrack.id} className="play-jamtrack"><td>
|
||||||
<a href={JamTrackPlayerStore.createPopupUrl(jamTrack)} target="_blank" onClick={this.onPlayJamTrack.bind(this, jamTrack)}>{jamTrack.name}</a> by {jamTrack.original_artist}</td></tr>`
|
<a href={JamTrackPlayerStore.createPopupUrl(jamTrack)} target="_blank" onClick={this.onPlayJamTrack.bind(this, jamTrack)}>{jamTrack.name}</a> by {jamTrack.original_artist}</td></tr>`
|
||||||
|
|
||||||
if @state.purchasedJamTracks.length < 5
|
if @state.purchasedJamTracks.length < 5
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ logger = context.JK.logger
|
||||||
errors = []
|
errors = []
|
||||||
if this.state.errors?
|
if this.state.errors?
|
||||||
for error in this.state.errors
|
for error in this.state.errors
|
||||||
errors.push(`<span>{error}</span>`)
|
errors.push(`<span key={error}>{error}</span>`)
|
||||||
|
|
||||||
`<div className="TeacherExperienceEditableList react-component">
|
`<div className="TeacherExperienceEditableList react-component">
|
||||||
<form className="teacher-experience-teaching-form">
|
<form className="teacher-experience-teaching-form">
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ logger = context.JK.logger
|
||||||
|
|
||||||
now = new Date().getFullYear()
|
now = new Date().getFullYear()
|
||||||
for yr in [now..1916]
|
for yr in [now..1916]
|
||||||
options.push `<option value={yr}>{yr}</option>`
|
options.push `<option key={yr} value={yr}>{yr}</option>`
|
||||||
|
|
||||||
`<select className="YearSelect react-component" name={this.props.name} required placeholder="Select" defaultValue={now}>
|
`<select className="YearSelect react-component" name={this.props.name} required placeholder="Select" defaultValue={now}>
|
||||||
{options}
|
{options}
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,5 @@ context = window
|
||||||
emptyChannel: {}
|
emptyChannel: {}
|
||||||
sessionStarted: {}
|
sessionStarted: {}
|
||||||
activateChannel: {}
|
activateChannel: {}
|
||||||
|
fullyOpened: {}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
context = window
|
||||||
|
|
||||||
|
@UserActivityActions = Reflux.createActions({
|
||||||
|
setActive: {}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
@ -1,33 +1,73 @@
|
||||||
$ = jQuery
|
$ = jQuery
|
||||||
context = window
|
context = window
|
||||||
logger = context.JK.logger
|
logger = context.JK.logger
|
||||||
|
SessionStore = context.SessionStore
|
||||||
|
|
||||||
@ChatStore = Reflux.createStore(
|
@ChatStore = Reflux.createStore(
|
||||||
{
|
{
|
||||||
listenables: @ChatActions
|
listenables: @ChatActions
|
||||||
|
|
||||||
|
limit: 20,
|
||||||
|
currentPage: 0,
|
||||||
|
next: null,
|
||||||
channel: 'global',
|
channel: 'global',
|
||||||
|
systemMsgId: 0
|
||||||
msgs: {global:[], session:[]}
|
msgs: {global:[], session:[]}
|
||||||
|
|
||||||
init: () ->
|
init: () ->
|
||||||
# Register with the app store to get @app
|
# Register with the app store to get @app
|
||||||
this.listenTo(context.AppStore, this.onAppInit)
|
this.listenTo(context.AppStore, this.onAppInit)
|
||||||
|
this.listenTo(context.UserActivityStore, this.onUserActivityChanged)
|
||||||
|
|
||||||
onAppInit: (@app) ->
|
onAppInit: (@app) ->
|
||||||
#$(document).on(EVENTS.SESSION_STARTED, ((e, data) =>
|
if context.JK.currentUserId?
|
||||||
#@sessionStarted(e, data);
|
@fetchHistory()
|
||||||
# return false
|
|
||||||
#))
|
|
||||||
|
|
||||||
# $(context.AppStore).on('SessionStarted', @onSessionStarted)
|
onUserActivityChanged: (state) ->
|
||||||
|
systemMsg = {}
|
||||||
|
@systemMsgId = @systemMsgId + 1
|
||||||
|
systemMsg.sender_name = 'System'
|
||||||
|
systemMsg.sender_id = 'system'
|
||||||
|
systemMsg.msg_id = @systemMsgId
|
||||||
|
systemMsg.created_at = new Date().toISOString()
|
||||||
|
systemMsg.channel = 'global'
|
||||||
|
if state.active
|
||||||
|
systemMsg.msg = "You've come back!"
|
||||||
|
else
|
||||||
|
systemMsg.msg = "You've become inactive. Any global chat messages while away will be missed."
|
||||||
|
|
||||||
|
@onMsgReceived(systemMsg)
|
||||||
|
|
||||||
|
# after the animation to open the chat panel is done, do it!
|
||||||
|
onFullyOpened: () ->
|
||||||
|
@changed()
|
||||||
|
|
||||||
# called from ChatPanel
|
# called from ChatPanel
|
||||||
onSessionStarted: () ->
|
onSessionStarted: () ->
|
||||||
logger.debug("ChatStore: onSessionStarted", this)
|
|
||||||
@msgs['session'] = []
|
@msgs['session'] = []
|
||||||
@channel = 'session'
|
@channel = 'session'
|
||||||
|
@fetchHistory()
|
||||||
@onEmptyChannel(@channel)
|
@onEmptyChannel(@channel)
|
||||||
|
|
||||||
|
buildQuery: () ->
|
||||||
|
query = {type: 'CHAT_MESSAGE', limit:@limit, page: @currentPage, channel: @channel};
|
||||||
|
|
||||||
|
if @channel == 'session' && SessionStore.currentSessionId?
|
||||||
|
query.music_session = SessionStore.currentSessionId
|
||||||
|
|
||||||
|
if @next
|
||||||
|
query.start = next
|
||||||
|
return query
|
||||||
|
|
||||||
|
fetchHistory: () ->
|
||||||
|
# load previous chat messages
|
||||||
|
rest.getChatMessages(@buildQuery())
|
||||||
|
.done((response) =>
|
||||||
|
@onLoadMessages(@channel, response)
|
||||||
|
).fail((jqXHR) =>
|
||||||
|
@app.notifyServerError(jqXHR, 'Unable to Load Session Conversations')
|
||||||
|
)
|
||||||
|
|
||||||
onEmptyChannel: (channel) ->
|
onEmptyChannel: (channel) ->
|
||||||
@msgs[channel] = []
|
@msgs[channel] = []
|
||||||
@changed()
|
@changed()
|
||||||
|
|
@ -42,6 +82,7 @@ logger = context.JK.logger
|
||||||
convert.msg_id = chat.id
|
convert.msg_id = chat.id
|
||||||
convert.created_at = chat.created_at
|
convert.created_at = chat.created_at
|
||||||
convert.channel = chat.channel
|
convert.channel = chat.channel
|
||||||
|
converted.push(convert)
|
||||||
converted
|
converted
|
||||||
|
|
||||||
# called from ChatPanel
|
# called from ChatPanel
|
||||||
|
|
@ -54,11 +95,27 @@ logger = context.JK.logger
|
||||||
|
|
||||||
history = @convertServerMessages(msgs.chats)
|
history = @convertServerMessages(msgs.chats)
|
||||||
|
|
||||||
@msgs[channel] = history.concat(channelMsgs)
|
for oldMsg in history
|
||||||
|
skip = false
|
||||||
|
for channelMsg in channelMsgs
|
||||||
|
if oldMsg.msg_id == channelMsg.msg_id
|
||||||
|
skip = true
|
||||||
|
break
|
||||||
|
|
||||||
|
if !skip
|
||||||
|
channelMsgs.unshift(oldMsg)
|
||||||
|
|
||||||
|
#totalMsgs = history.concat(channelMsgs)
|
||||||
|
channelMsgs.sort((a, b) =>
|
||||||
|
c = new Date(a.created_at)
|
||||||
|
d = new Date(b.created_at)
|
||||||
|
return (c > d) - (c < d)
|
||||||
|
)
|
||||||
|
@msgs[channel] = channelMsgs
|
||||||
|
|
||||||
@changed()
|
@changed()
|
||||||
|
|
||||||
onMsgReceived: (msg) ->
|
onMsgReceived: (msg) ->
|
||||||
logger.debug("ChatStore.msgReceived", msg)
|
|
||||||
|
|
||||||
channelMsgs = @msgs[msg.channel]
|
channelMsgs = @msgs[msg.channel]
|
||||||
|
|
||||||
|
|
@ -79,6 +136,7 @@ logger = context.JK.logger
|
||||||
|
|
||||||
onActivateChannel: (channel) ->
|
onActivateChannel: (channel) ->
|
||||||
@channel = channel
|
@channel = channel
|
||||||
|
@fetchHistory()
|
||||||
@changed()
|
@changed()
|
||||||
|
|
||||||
onSendMsg: (msg, done, fail) ->
|
onSendMsg: (msg, done, fail) ->
|
||||||
|
|
@ -87,16 +145,15 @@ logger = context.JK.logger
|
||||||
|
|
||||||
done(response)
|
done(response)
|
||||||
|
|
||||||
#console.log("ON SEND MESSAGE SIMULATE", response)
|
if response.channel == 'session'
|
||||||
|
@onMsgReceived({
|
||||||
@onMsgReceived({
|
sender_name: "me",
|
||||||
sender_name: "me",
|
sender_id: context.JK.currentUserId,
|
||||||
sender_id: context.JK.currentUserId,
|
msg: msg,
|
||||||
msg: msg,
|
msg_id: response.id,
|
||||||
msg_id: response.id,
|
created_at: response.created_at,
|
||||||
created_at: response.created_at,
|
channel: response.channel
|
||||||
channel: @channel
|
})
|
||||||
})
|
|
||||||
)
|
)
|
||||||
.fail((jqXHR) =>
|
.fail((jqXHR) =>
|
||||||
fail(jqXHR)
|
fail(jqXHR)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
$ = jQuery
|
||||||
|
context = window
|
||||||
|
logger = context.JK.logger
|
||||||
|
|
||||||
|
@UserActivityStore = Reflux.createStore(
|
||||||
|
{
|
||||||
|
active: true
|
||||||
|
|
||||||
|
listenables: @UserActivityActions
|
||||||
|
|
||||||
|
init: ->
|
||||||
|
this.listenTo(context.AppStore, this.onAppInit)
|
||||||
|
|
||||||
|
onAppInit: (@app) ->
|
||||||
|
|
||||||
|
onSetActive: (active) ->
|
||||||
|
if active != @active
|
||||||
|
@active = active
|
||||||
|
@changed()
|
||||||
|
|
||||||
|
changed:() ->
|
||||||
|
@trigger(@getState())
|
||||||
|
|
||||||
|
getState:() ->
|
||||||
|
{active: @active}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import "client/common";
|
||||||
|
|
||||||
div[data-react-class="ChatWindow"] {
|
div[data-react-class="ChatWindow"] {
|
||||||
height:100%;
|
height:100%;
|
||||||
|
|
||||||
|
|
@ -5,6 +7,14 @@ div[data-react-class="ChatWindow"] {
|
||||||
height:100%;
|
height:100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.active-tab {
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
top: -24px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-bottom: 54px;
|
||||||
|
margin-top:24px;
|
||||||
|
}
|
||||||
.chat-tabs {
|
.chat-tabs {
|
||||||
text-align:center;
|
text-align:center;
|
||||||
}
|
}
|
||||||
|
|
@ -15,19 +25,22 @@ div[data-react-class="ChatWindow"] {
|
||||||
|
|
||||||
padding:2px;
|
padding:2px;
|
||||||
color: #ED3618;
|
color: #ED3618;
|
||||||
background-color:#09525b;
|
|
||||||
border-style:solid;
|
border-style:solid;
|
||||||
border-color:#09525b;
|
border-color:#09525b;
|
||||||
border-width:1px;
|
|
||||||
|
|
||||||
a {
|
a {
|
||||||
//color:white;
|
//color:white;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
|
color: #aaa;
|
||||||
|
&:hover {
|
||||||
|
color: #fc0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
color:white;
|
||||||
}
|
}
|
||||||
background-color:transparent;
|
background-color:transparent;
|
||||||
border-color:#09525b;
|
border-color:#09525b;
|
||||||
|
|
@ -42,7 +55,7 @@ div[data-react-class="ChatWindow"] {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
margin: 0px 15px;
|
margin: 0px 15px;
|
||||||
/*height: 210px;*/
|
/*height: 210px;*/
|
||||||
height: 73%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
.chart-text-section {
|
.chart-text-section {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ class ApiChatsController < ApiController
|
||||||
@chat_msg.user_id = current_user.id
|
@chat_msg.user_id = current_user.id
|
||||||
@chat_msg.music_session_id = @music_session.id if @music_session
|
@chat_msg.music_session_id = @music_session.id if @music_session
|
||||||
@chat_msg.message = params[:message]
|
@chat_msg.message = params[:message]
|
||||||
|
@chat_msg.channel = params[:channel]
|
||||||
|
|
||||||
if @chat_msg.save
|
if @chat_msg.save
|
||||||
ChatMessage.send_chat_msg @music_session, @chat_msg, current_user, params[:client_id], params[:channel]
|
ChatMessage.send_chat_msg @music_session, @chat_msg, current_user, params[:client_id], params[:channel]
|
||||||
|
|
@ -25,7 +26,7 @@ class ApiChatsController < ApiController
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_session
|
def check_session
|
||||||
if params.has_key?(:music_session)
|
if params.has_key?(:music_session) || params[:channel] == 'session'
|
||||||
@music_session = ActiveMusicSession.find(params[:music_session])
|
@music_session = ActiveMusicSession.find(params[:music_session])
|
||||||
if @music_session.nil?
|
if @music_session.nil?
|
||||||
raise ArgumentError, 'specified session not found'
|
raise ArgumentError, 'specified session not found'
|
||||||
|
|
|
||||||
|
|
@ -448,7 +448,7 @@ SampleApp::Application.routes.draw do
|
||||||
|
|
||||||
# session chat
|
# session chat
|
||||||
match '/chat' => 'api_chats#create', :via => :post
|
match '/chat' => 'api_chats#create', :via => :post
|
||||||
match '/sessions/:music_session/chats' => 'api_chats#index', :via => :get
|
match '/chat' => 'api_chats#index', :via => :get
|
||||||
|
|
||||||
# user recordings
|
# user recordings
|
||||||
# match '/users/:id/recordings' => 'api_users#recording_index', :via => :get
|
# match '/users/:id/recordings' => 'api_users#recording_index', :via => :get
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue