BattleSim/client/app/js/views/private_messages_view.coffee

260 lines
8.8 KiB
CoffeeScript

class @PrivateMessagesView extends Backbone.View
messageTemplate: JST['private_message']
events:
"keypress .chat_input" : "keyPressEvent"
"keyup .chat_input" : "keyUpEvent"
"click .challenge_button, .cancel_challenge" : "toggleChallengeEvent"
"click .popup_messages" : "focusChatEvent"
"click .title_minimize" : "minimizePopupEvent"
"click .title_close" : "closePopupEvent"
"challenge .popup" : "sendChallengeEvent"
"cancelChallenge .popup" : "challengeCanceledEvent"
"focus .popup" : "focusPopupEvent"
initialize: =>
@listenTo(@collection, 'open', @createPopup)
@listenTo(@collection, 'focus', @focusPopup)
@listenTo(@collection, 'receive', @receiveMessage)
@listenTo(@collection, 'close', @closePopup)
@listenTo(@collection, 'minimize', @minimizePopup)
@listenTo(@collection, 'show', @showPopup)
@listenTo(@collection, 'openChallenge', @openChallenge)
@listenTo(@collection, 'cancelChallenge', @cancelChallenge)
@listenTo(@collection, 'closeChallenge', @closeChallenge)
@listenTo(@collection, 'focus show', @resetNotifications)
# @listenTo(PokeBattle.userList, 'add', @notifyJoin)
# @listenTo(PokeBattle.userList, 'remove', @notifyLeave)
createPopup: (message) =>
title = id = message.id
$html = @$findPopup(id)
if @$findPopup(id).length == 0
$html = $(@messageTemplate({window, id, title}))
@$el.append($html)
@positionPopup($html, @$(".popup:visible").length - 1)
@addLogMessages($html, message.getLog())
$html
focusPopup: (message) =>
id = message.id
$popup = @$findPopup(id)
$popup.find('.chat_input').focus()
closePopup: (message) =>
username = message.id
@$findPopup(username).remove()
@repositionPopups()
minimizePopup: (message) =>
username = message.id
$popup = @$findPopup(username)
$popup.addClass('hidden')
@repositionPopups()
showPopup: (message) =>
username = message.id
$popup = @$findPopup(username)
@$el.append($popup)
$popup.removeClass('hidden')
@scrollToBottom($popup)
@repositionPopups()
addMessage: ($popup, message) =>
$messages = $popup.find('.popup_messages')
$messages.append(message)
# todo: make this and receiveMessage construct messages from a common source
addLogMessages: ($popup, log) =>
messageHtml = ""
for {username, message, opts} in log
message = _.escape(message)
username = "Me" if username == PokeBattle.username
if opts.type in [ 'error', 'alert' ]
messageHtml += "<p class='grey'>#{message}</p>"
else
messageHtml += "<p class='grey'><strong>#{username}:</strong> #{message}</p>"
@addMessage($popup, messageHtml)
@scrollToBottom($popup)
# todo: make this and addLogMessages construct messages from a common source
receiveMessage: (messageModel, messageId, username, message, options) =>
message = _.escape(message)
$popup = @$findOrCreatePopup(messageId)
wasAtBottom = @isAtBottom($popup)
username = "Me" if username == PokeBattle.username
if options.type == 'error'
@addMessage($popup, "<p class='red italic'>#{message}</p>")
else if options.type == 'alert'
@addMessage($popup, "<p class='yellow italic'>#{message}</p>")
else
if username != "Me" && !$popup.find('.chat_input').is(":focus")
$popup.addClass('new_message')
PokeBattle.notifyUser(PokeBattle.NotificationTypes.PRIVATE_MESSAGE, username)
else
@resetNotifications(messageModel)
@addMessage($popup, "<p><strong>#{username}:</strong> #{message}</p>")
if wasAtBottom then @scrollToBottom($popup)
openChallenge: (messageId, generation, conditions) =>
$popup = @$findOrCreatePopup(messageId)
$challenge = @createChallenge($popup, generation, conditions)
if generation
$challenge.find('.is_not_challenger').addClass('hidden')
$challenge.find('.is_challenger').removeClass('hidden')
cancelChallenge: (messageId) =>
$popup = @$findOrCreatePopup(messageId)
$challenge = $popup.find('.challenge')
$challenge.find('.icon-spinner').addClass('hidden')
$challenge.find('.send_challenge, .select').removeClass('disabled')
$challenge.find('.challenge_text').text("Challenge")
$challenge.find(".cancel_challenge").text('Close')
closeChallenge: (messageId) =>
$popup = @$findOrCreatePopup(messageId)
$challenge = $popup.find('.challenge')
$challenge.addClass('hidden')
$popup.find('.popup_messages').removeClass('small')
resetNotifications: (message) =>
message.set('notifications', 0)
notifyJoin: (user) =>
message = @collection.get(user.id)
return unless @isOpen(message)
message?.add(user.id, "#{user.id} is now online!", type: "alert")
notifyLeave: (user) =>
message = @collection.get(user.id)
return unless @isOpen(message)
message?.add(user.id, "#{user.id} is now offline.", type: "alert")
isOpen: (message) =>
message && @$findPopup(message.id).length > 0
# Returns true if the chat is scrolled to the bottom of the screen.
# This also returns true if the messages are hidden.
isAtBottom: ($popup) =>
$el = $popup.find('.popup_messages')
($el[0].scrollHeight - $el.scrollTop() <= $el.outerHeight())
scrollToBottom: ($popup) =>
messages = $popup.find('.popup_messages')[0]
return unless messages
messages.scrollTop = messages.scrollHeight
false
positionPopup: ($popup, index) =>
leftOffset = $('#content').position().left
$popup.css(left: leftOffset + index * $popup.outerWidth(true))
repositionPopups: =>
@$(".popup:visible").each (index, self) =>
@positionPopup($(self), index)
$findPopup: (id) =>
@$(".popup[data-user-id='#{id}']")
$findOrCreatePopup: (messageId) =>
$popup = @$findPopup(messageId)
$popup = @createPopup(@collection.get(messageId)) if $popup.length == 0
$popup
$closestPopup: (target) =>
$target = $(target)
return $target if $target.hasClass("popup")
return $target.closest(".popup")
messageFromPopup: (target) =>
$popup = @$closestPopup(target)
message = @collection.get($popup.data('user-id'))
return message
createChallenge: ($popup, generation, conditions) =>
$challenge = $popup.find('.challenge')
$challenge.html(JST['challenge']())
createChallengePane
eventName: "challenge"
button: $popup.find('.send_challenge')
acceptButton: $popup.find('.accept_challenge')
rejectButton: $popup.find('.reject_challenge')
populate: $popup.find(".challenge_data")
generation: generation
personId: $popup.data('user-id')
defaultClauses: conditions || [
Conditions.TEAM_PREVIEW
Conditions.PBV_1000
Conditions.SLEEP_CLAUSE
Conditions.EVASION_CLAUSE
Conditions.SPECIES_CLAUSE
Conditions.OHKO_CLAUSE
Conditions.PRANKSTER_SWAGGER_CLAUSE
Conditions.UNRELEASED_BAN
]
blockedClauses: conditions? || [Conditions.RATED_BATTLE]
$popup.find('.popup_messages').addClass('small')
$challenge.removeClass('hidden')
$challenge
##########
# EVENTS #
##########
keyPressEvent: (e) =>
switch e.which
when 13 # [ Enter ]
$input = $(e.currentTarget)
message = @messageFromPopup(e.currentTarget)
text = $input.val()
return if text.length == 0
PokeBattle.primus.send('privateMessage', message.id, text)
$input.val('')
keyUpEvent: (e) =>
switch e.which
when 27 # [ Esc ]
@closePopupEvent(e)
minimizePopupEvent: (e) =>
message = @messageFromPopup(e.currentTarget)
message.trigger('minimize', message)
closePopupEvent: (e) =>
message = @messageFromPopup(e.currentTarget)
message.trigger('close', message)
focusChatEvent: (e) =>
@$closestPopup(e.currentTarget).find('input').focus()
toggleChallengeEvent: (e) =>
$popup = @$closestPopup(e.currentTarget)
$challenge = $popup.find('.challenge')
wasAtBottom = @isAtBottom($popup)
if $challenge.hasClass("hidden")
@createChallenge($popup)
else if $challenge.find('.cancel_challenge').text() == 'Cancel'
$popup.find('.send_challenge').click()
else
@closeChallenge(@messageFromPopup($popup))
if wasAtBottom then @scrollToBottom($popup)
sendChallengeEvent: (e) =>
$popup = @$closestPopup(e.currentTarget)
$challenge = $popup.find('.challenge')
$challenge.find(".icon-spinner").removeClass('hidden')
$challenge.find(".challenge_text").text('Challenging...')
$challenge.find(".cancel_challenge").text('Cancel')
challengeCanceledEvent: (e) =>
message = @messageFromPopup(e.currentTarget)
message.trigger('cancelChallenge', message.id)
focusPopupEvent: (e) =>
$popup = @$closestPopup(e.currentTarget)
$popup.removeClass('new_message')
@resetNotifications(@collection.get($popup.data('user-id')))