mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-23 23:58:02 -05:00
130 lines
3.9 KiB
CoffeeScript
130 lines
3.9 KiB
CoffeeScript
CocoView = require 'views/core/CocoView'
|
|
template = require 'templates/play/level/chat'
|
|
{me} = require 'core/auth'
|
|
LevelBus = require 'lib/LevelBus'
|
|
|
|
module.exports = class LevelChatView extends CocoView
|
|
id: 'level-chat-view'
|
|
template: template
|
|
open: false
|
|
|
|
events:
|
|
'keypress textarea': 'onChatKeydown'
|
|
'click i': 'onIconClick'
|
|
|
|
subscriptions:
|
|
'bus:new-message': 'onNewMessage'
|
|
|
|
constructor: (options) ->
|
|
@levelID = options.levelID
|
|
@session = options.session
|
|
# TODO: we took out session.multiplayer, so this will not fire. If we want to resurrect it, we'll of course need a new way of activating chat.
|
|
@listenTo(@session, 'change:multiplayer', @updateMultiplayerVisibility)
|
|
@sessionID = options.sessionID
|
|
@bus = LevelBus.get(@levelID, @sessionID)
|
|
super()
|
|
@regularlyClearOldMessages()
|
|
@playNoise = _.debounce(@playNoise, 100)
|
|
|
|
updateMultiplayerVisibility: ->
|
|
return unless @$el?
|
|
try
|
|
@$el.toggle Boolean @session.get('multiplayer')
|
|
catch e
|
|
console.error "Couldn't toggle the style on the LevelChatView to #{Boolean @session.get('multiplayer')} because of an error:", e
|
|
|
|
afterRender: ->
|
|
@chatTables = $('table', @$el)
|
|
@updateMultiplayerVisibility()
|
|
|
|
regularlyClearOldMessages: ->
|
|
@clearOldMessagesInterval = setInterval(@clearOldMessages, 5000)
|
|
|
|
clearOldMessages: =>
|
|
rows = $('.closed-chat-area tr')
|
|
for row in rows
|
|
row = $(row)
|
|
added = row.data('added')
|
|
if new Date().getTime() - added > 60 * 1000
|
|
row.fadeOut(1000, -> $(this).remove())
|
|
|
|
onNewMessage: (e) ->
|
|
@$el.show() unless e.message.system
|
|
@addOne(e.message)
|
|
@trimClosedPanel()
|
|
@playNoise() if e.message.authorID isnt me.id
|
|
|
|
playNoise: ->
|
|
@playSound 'chat_received'
|
|
|
|
messageObjectToJQuery: (message) ->
|
|
td = $('<td></td>')
|
|
content = message.content
|
|
content = _.string.escapeHTML(content)
|
|
content = content.replace(/\n/g, '<br/>')
|
|
content = content.replace(RegExp(' ', 'g'), ' ') # coffeescript can't compile '/ /g'
|
|
if _.string.startsWith(content, '/me')
|
|
content = message.authorName + content.slice(3)
|
|
|
|
if message.system
|
|
td.append($('<span class="system"></span>').html(content))
|
|
|
|
else if _.string.startsWith(content, '/me')
|
|
td.append($('<span class="action"></span>').html(content))
|
|
|
|
else
|
|
td.append($('<strong></strong>').text(message.authorName+': '))
|
|
td.append($('<span></span>').html(content))
|
|
|
|
tr = $('<tr></tr>')
|
|
tr.addClass('me') if message.authorID is me.id
|
|
tr.append(td)
|
|
|
|
addOne: (message) ->
|
|
return if message.system and message.authorID is me.id
|
|
if @open
|
|
openPanel = $('.open-chat-area', @$el)
|
|
height = openPanel.outerHeight()
|
|
distanceFromBottom = openPanel[0].scrollHeight - height - openPanel[0].scrollTop
|
|
doScroll = distanceFromBottom < 10
|
|
tr = @messageObjectToJQuery(message)
|
|
tr.data('added', new Date().getTime())
|
|
@chatTables.append(tr)
|
|
@scrollDown() if doScroll
|
|
|
|
trimClosedPanel: ->
|
|
closedPanel = $('.closed-chat-area', @$el)
|
|
limit = 5
|
|
rows = $('tr', closedPanel)
|
|
for row, i in rows
|
|
break if rows.length - i <= limit
|
|
row.remove()
|
|
|
|
onChatKeydown: (e) ->
|
|
if key.isPressed('enter')
|
|
message = _.string.strip($(e.target).val())
|
|
return false unless message
|
|
@bus.sendMessage(message)
|
|
$(e.target).val('')
|
|
return false
|
|
|
|
onIconClick: ->
|
|
@open = not @open
|
|
openPanel = $('.open-chat-area', @$el).toggle @open
|
|
closedPanel = $('.closed-chat-area', @$el).toggle not @open
|
|
@scrollDown() if @open
|
|
if window.getSelection?
|
|
sel = window.getSelection()
|
|
sel.empty?()
|
|
sel.removeAllRanges?()
|
|
else
|
|
document.selection.empty()
|
|
|
|
scrollDown: ->
|
|
openPanel = $('.open-chat-area', @$el)[0]
|
|
openPanel.scrollTop = openPanel.scrollHeight or 1000000
|
|
|
|
destroy: ->
|
|
key.deleteScope('level')
|
|
clearInterval @clearOldMessagesInterval if @clearOldMessagesInterval
|
|
super()
|