Improved broadcast and chat feature.

This commit is contained in:
Martin Edenhofer 2012-11-04 11:24:03 +01:00
parent 9cc2bfd71e
commit afc3062150
3 changed files with 102 additions and 24 deletions

View file

@ -2,7 +2,7 @@ $ = jQuery.sub()
class App.ChatWidget extends App.Controller
events:
'submit #chat_form': 'newMessage'
'submit #chat_form': 'submitMessage'
'focusin [name=chat_message]': 'focusIn'
'focusout [name=chat_message]': 'focusOut'
'click .close': 'toggle'
@ -24,15 +24,22 @@ class App.ChatWidget extends App.Controller
@start()
start: =>
@focus = false
@isShown = false
@focus = false
@isShown = false
@newMessage = false
@render()
@hide()
@interval @position, 200, 'chat-widget'
App.Event.bind(
'chat:message'
(e) =>
# show new message info
@newMessage = true
# remember messages
@messageLog.push e
# chump max message count
@ -46,43 +53,72 @@ class App.ChatWidget extends App.Controller
App.Event.bind(
'chat:window_toggle'
(e) =>
if e.user_id is Session['id']
if e.show
@show()
else
@hide()
if e.show
@show()
else
@hide()
)
App.Event.bind(
'chat:message_new'
(e) =>
@el.find('div.well').removeClass('alert-success')
)
toggle: (e) =>
e.preventDefault()
if @el.find('#chat_content').hasClass('hide')
if !@el.find('#chat_content').is(':visible')
@show()
App.Event.trigger(
'ws:send'
action: 'broadcast'
event: 'chat:window_toggle'
recipient:
user_id: [ Session['id'] ]
data:
user_id: Session['id']
show: true
)
else
@hide()
App.Event.trigger(
'ws:send'
action: 'broadcast'
event: 'chat:window_toggle'
action: 'broadcast'
event: 'chat:window_toggle'
recipient:
user_id: [ Session['id'] ]
data:
user_id: Session['id']
show: false
)
@newMessage = false
show: =>
@isShown = true
@el.find('#chat_content').removeClass('hide')
if @newMessage
@el.find('div.well').addClass('alert-success')
@delay( =>
@el.find('div.well').removeClass('alert-success')
@log 'DELAY rm'
App.Event.trigger(
'ws:send'
action: 'broadcast'
recipient:
user_id: [ Session['id'] ]
event: 'chat:message_new'
spool: true
data:
show: true
)
2000
'chat-message-new'
)
@el.find('#chat_content').show(100)
@newMessage = false
hide: =>
@isShown = false
@el.find('#chat_content').addClass('hide')
@el.find('#chat_content').hide(100)
focusIn: =>
@focus = true
@ -100,16 +136,26 @@ class App.ChatWidget extends App.Controller
message.nick = 'me'
# insert data
shown = false
if @isShown
shown = true
@html App.view('chat_widget')(
messages: @messageLog
isShown: shown
)
document.getElementById('chat_log_container').scrollTop = 10000
# focus in input box
if @focus
@el.find('[name=chat_message]').focus()
# show or not show window
if @isShown
@show()
else
@hide()
if @newMessage
@el.find('div.well').addClass('alert-success')
position: =>
chatHeigth = $(@el).find('div').height()
@ -127,7 +173,7 @@ class App.ChatWidget extends App.Controller
@el.offset( left: width, top: heigth )
@el.css( width: '200px' )
newMessage: (e) ->
submitMessage: (e) ->
e.preventDefault()
message = $(e.target).find('[name=chat_message]').val()
if message
@ -138,6 +184,7 @@ class App.ChatWidget extends App.Controller
@messageLog.push msg
$(e.target).find('[name=chat_message]').val('')
App.Event.trigger(
'ws:send'
action: 'broadcast'

View file

@ -1,6 +1,6 @@
<div class="well well-demand span3">
<h4><%- @T('Chat') %><a href="#" class="close">&times;</a></h4>
<div id="chat_content">
<div id="chat_content" <% if !@isShown: %>class="hide"<% end %>>
<div id="chat_log_container" class="max-size-scroll">
<% for message in @messages: %>
<div><%= message.nick %>: <%- @L( message.message ) %></div>

View file

@ -93,8 +93,9 @@ EventMachine.run {
# spool messages for new connects
if data['spool']
meta = {
:msg => msg,
:timestamp => Time.now.to_i,
:msg => msg,
:msg_object => data,
:timestamp => Time.now.to_i,
}
@spool.push meta
end
@ -102,9 +103,25 @@ EventMachine.run {
# get spool messages
if data['action'] == 'spool'
@spool.each { |message|
# only send not already now messages
if !data['timestamp'] || data['timestamp'] < message[:timestamp]
puts "send spool msg to #{client_id} #{ message[:msg] }"
@clients[client_id][:websocket].send( "[#{ message[:msg] }]" )
# spool to recipient list
if message[:msg_object]['recipient'] && message[:msg_object]['recipient']['user_id']
message[:msg_object]['recipient']['user_id'].each { |user_id|
if @clients[client_id][:session]['id'] == user_id
log 'notice', "send spool to (user_id=#{user_id})", client_id
@clients[client_id][:websocket].send( "[#{ message[:msg] }]" )
end
}
# spool every client
else
log 'notice', "send spool", client_id
@clients[client_id][:websocket].send( "[#{ message[:msg] }]" )
end
end
}
end
@ -121,10 +138,24 @@ EventMachine.run {
# broadcast
elsif data['action'] == 'broadcast'
# list all current clients
@clients.each { |local_client_id, local_client|
if local_client_id != client_id
puts "send broadcast to #{local_client_id} #{msg}"
local_client[:websocket].send( "[#{msg}]" )
# broadcast to recipient list
if data['recipient'] && data['recipient']['user_id']
data['recipient']['user_id'].each { |user_id|
if local_client[:session]['id'] == user_id
log 'notice', "send broadcast to (user_id=#{user_id})", local_client_id
local_client[:websocket].send( "[#{msg}]" )
end
}
# broadcast every client
else
log 'notice', "send broadcast", local_client_id
local_client[:websocket].send( "[#{msg}]" )
end
end
}
end
@ -168,7 +199,7 @@ EventMachine.run {
queue = Session.queue( client_id )
if queue && queue[0]
# log "send " + queue.inspect, client_id
log 'debug', "send data to client", client_id
log 'notice', "send data to client", client_id
client[:websocket].send( queue.to_json )
end
rescue => e