This commit is contained in:
Seth Call 2016-02-01 14:14:06 -06:00
parent 8900af5196
commit 2e95682b10
20 changed files with 233 additions and 106 deletions

View File

@ -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

View File

@ -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);

View File

@ -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]

View File

@ -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

View File

@ -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);
}); });
}); });

View File

@ -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);

View File

@ -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'
}) })

View File

@ -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) {

View File

@ -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

View File

@ -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
}) })

View File

@ -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

View File

@ -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">

View File

@ -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}

View File

@ -7,4 +7,5 @@ context = window
emptyChannel: {} emptyChannel: {}
sessionStarted: {} sessionStarted: {}
activateChannel: {} activateChannel: {}
fullyOpened: {}
}) })

View File

@ -0,0 +1,6 @@
context = window
@UserActivityActions = Reflux.createActions({
setActive: {}
})

View File

@ -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)

View File

@ -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}
}
)

View File

@ -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 {

View File

@ -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'

View File

@ -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