mirror of
https://github.com/wbbaddons/Tims-Chat.git
synced 2024-10-31 14:10:08 +00:00
Merge branch 'master' into privateChannels
Conflicts: file/js/be.bastelstu.Chat.litcoffee
This commit is contained in:
commit
8279759294
@ -33,7 +33,9 @@ exposed by a function if necessary.
|
|||||||
newMessageCount = 0
|
newMessageCount = 0
|
||||||
scrollUpNotifications = off
|
scrollUpNotifications = off
|
||||||
chatSession = Date.now()
|
chatSession = Date.now()
|
||||||
|
|
||||||
errorVisible = false
|
errorVisible = false
|
||||||
|
inputErrorHidingTimer = null
|
||||||
|
|
||||||
lastMessage = null
|
lastMessage = null
|
||||||
openChannel = 0
|
openChannel = 0
|
||||||
@ -109,15 +111,15 @@ Make the user leave the chat when **Tims Chat** is about to be unloaded.
|
|||||||
Insert the appropriate smiley code into the input when a smiley is clicked.
|
Insert the appropriate smiley code into the input when a smiley is clicked.
|
||||||
|
|
||||||
$('#smilies').on 'click', 'img', ->
|
$('#smilies').on 'click', 'img', ->
|
||||||
insertText ' ' + $(@).attr('alt') + ' '
|
insertText " #{$(@).attr('alt')} "
|
||||||
|
|
||||||
Handle submitting the form. The message will be validated by some basic checks, passed to the `submit` eventlisteners
|
Handle submitting the form. The message will be validated by some basic checks, passed to the `submit` eventlisteners
|
||||||
and afterwards sent to the server by an AJAX request.
|
and afterwards sent to the server by an AJAX request.
|
||||||
|
|
||||||
$('#timsChatForm').submit (event) ->
|
$('#timsChatForm').submit (event) ->
|
||||||
event.preventDefault()
|
do event.preventDefault
|
||||||
|
|
||||||
text = $('#timsChatInput').val().trim()
|
text = do $('#timsChatInput').val().trim
|
||||||
$('#timsChatInput').val('').focus().keyup()
|
$('#timsChatInput').val('').focus().keyup()
|
||||||
|
|
||||||
return false if text.length is 0
|
return false if text.length is 0
|
||||||
@ -126,7 +128,7 @@ and afterwards sent to the server by an AJAX request.
|
|||||||
text = "/whisper #{$("#timsChatMessageContainer#{openChannel}").data 'username'}, #{text}"
|
text = "/whisper #{$("#timsChatMessageContainer#{openChannel}").data 'username'}, #{text}"
|
||||||
|
|
||||||
# Free the fish!
|
# Free the fish!
|
||||||
freeTheFish() if text.toLowerCase() is '/free the fish'
|
do freeTheFish if text.toLowerCase() is '/free the fish'
|
||||||
|
|
||||||
text = do (text) ->
|
text = do (text) ->
|
||||||
obj =
|
obj =
|
||||||
@ -145,16 +147,13 @@ and afterwards sent to the server by an AJAX request.
|
|||||||
enableSmilies: $('#timsChatSmilies').data 'status'
|
enableSmilies: $('#timsChatSmilies').data 'status'
|
||||||
showLoadingOverlay: false
|
showLoadingOverlay: false
|
||||||
success: ->
|
success: ->
|
||||||
$('#timsChatInputContainer').removeClass('formError').find('.innerError').hide()
|
do hideInputError
|
||||||
getMessages()
|
|
||||||
|
do getMessages
|
||||||
failure: (data) ->
|
failure: (data) ->
|
||||||
return true unless (data?.returnValues?.errorType?) or (data?.message?)
|
return true unless (data?.returnValues?.errorType?) or (data?.message?)
|
||||||
|
|
||||||
$('#timsChatInputContainer').addClass('formError').find('.innerError').show().html (data?.returnValues?.errorType) ? data.message
|
showInputError (data?.returnValues?.errorType) ? data.message
|
||||||
|
|
||||||
setTimeout ->
|
|
||||||
$('#timsChatInputContainer').removeClass('formError').find('.innerError').hide()
|
|
||||||
, 5e3
|
|
||||||
|
|
||||||
false
|
false
|
||||||
|
|
||||||
@ -163,11 +162,11 @@ The the word the caret is in will be passed to `autocomplete` and replaced if a
|
|||||||
|
|
||||||
$('#timsChatInput').keydown (event) ->
|
$('#timsChatInput').keydown (event) ->
|
||||||
if event.keyCode is $.ui.keyCode.TAB
|
if event.keyCode is $.ui.keyCode.TAB
|
||||||
input = $(event.currentTarget)
|
do event.preventDefault
|
||||||
event.preventDefault()
|
input = $ @
|
||||||
|
|
||||||
autocomplete.value ?= input.val()
|
autocomplete.value ?= do input.val
|
||||||
autocomplete.caret ?= input.getCaret()
|
autocomplete.caret ?= do input.getCaret
|
||||||
|
|
||||||
beforeCaret = autocomplete.value.substring 0, autocomplete.caret
|
beforeCaret = autocomplete.value.substring 0, autocomplete.caret
|
||||||
lastSpace = beforeCaret.lastIndexOf ' '
|
lastSpace = beforeCaret.lastIndexOf ' '
|
||||||
@ -183,7 +182,7 @@ The the word the caret is in will be passed to `autocomplete` and replaced if a
|
|||||||
return if toComplete.length is 0
|
return if toComplete.length is 0
|
||||||
console.log "Autocompleting '#{toComplete}'"
|
console.log "Autocompleting '#{toComplete}'"
|
||||||
|
|
||||||
if beforeComplete is '' and toComplete.substring(0, 1) is '/'
|
if beforeComplete is '' and (toComplete.substring 0, 1) is '/'
|
||||||
regex = new RegExp "^#{WCF.String.escapeRegExp toComplete.substring 1}", "i"
|
regex = new RegExp "^#{WCF.String.escapeRegExp toComplete.substring 1}", "i"
|
||||||
# TODO: Proper command list
|
# TODO: Proper command list
|
||||||
commands = (command for command in v.config.installedCommands when regex.test command)
|
commands = (command for command in v.config.installedCommands when regex.test command)
|
||||||
@ -201,7 +200,7 @@ The the word the caret is in will be passed to `autocomplete` and replaced if a
|
|||||||
Reset autocompleter to default status, when a key is pressed that is not TAB.
|
Reset autocompleter to default status, when a key is pressed that is not TAB.
|
||||||
|
|
||||||
else
|
else
|
||||||
$('#timsChatInput').click()
|
do $('#timsChatInput').click
|
||||||
|
|
||||||
Reset autocompleter to default status, when the input is `click`ed, as the position of the caret may have changed.
|
Reset autocompleter to default status, when the input is `click`ed, as the position of the caret may have changed.
|
||||||
|
|
||||||
@ -214,14 +213,14 @@ Reset autocompleter to default status, when the input is `click`ed, as the posit
|
|||||||
Refresh the room list when the associated button is `click`ed.
|
Refresh the room list when the associated button is `click`ed.
|
||||||
|
|
||||||
$('#timsChatRoomList button').click ->
|
$('#timsChatRoomList button').click ->
|
||||||
refreshRoomList()
|
do refreshRoomList
|
||||||
|
|
||||||
Clear the chat by removing every single message once the clear button is `clicked`.
|
Clear the chat by removing every single message once the clear button is `clicked`.
|
||||||
|
|
||||||
$('#timsChatClear').click (event) ->
|
$('#timsChatClear').click (event) ->
|
||||||
event.preventDefault()
|
do event.preventDefault
|
||||||
$('.timsChatMessageContainer.active .timsChatMessage').remove()
|
do $('.timsChatMessageContainer.active .timsChatMessage').remove
|
||||||
$('.timsChatMessageContainer.active').scrollTop $('.timsChatMessageContainer.active').prop('scrollHeight')
|
$('.timsChatMessageContainer.active').scrollTop $('.timsChatMessageContainer.active').prop 'scrollHeight'
|
||||||
|
|
||||||
Handle toggling of the toggleable buttons.
|
Handle toggling of the toggleable buttons.
|
||||||
|
|
||||||
@ -236,7 +235,7 @@ Handle toggling of the toggleable buttons.
|
|||||||
element.addClass 'active'
|
element.addClass 'active'
|
||||||
element.attr 'title', element.data 'disableMessage'
|
element.attr 'title', element.data 'disableMessage'
|
||||||
|
|
||||||
$('#timsChatInput').focus()
|
do $('#timsChatInput').focus
|
||||||
|
|
||||||
Mark smilies as disabled when they are disabled.
|
Mark smilies as disabled when they are disabled.
|
||||||
|
|
||||||
@ -282,7 +281,7 @@ Scroll down when autoscroll is being activated.
|
|||||||
|
|
||||||
$('#timsChatAutoscroll').click (event) ->
|
$('#timsChatAutoscroll').click (event) ->
|
||||||
if $('#timsChatAutoscroll').data 'status'
|
if $('#timsChatAutoscroll').data 'status'
|
||||||
$('.timsChatMessageContainer.active').scrollTop $('.timsChatMessageContainer.active').prop('scrollHeight')
|
$('.timsChatMessageContainer.active').scrollTop $('.timsChatMessageContainer.active').prop 'scrollHeight'
|
||||||
|
|
||||||
$('.timsChatMessageContainer.active').on 'scroll', (event) ->
|
$('.timsChatMessageContainer.active').on 'scroll', (event) ->
|
||||||
element = $ @
|
element = $ @
|
||||||
@ -293,13 +292,13 @@ Scroll down when autoscroll is being activated.
|
|||||||
if scrollTop < scrollHeight - height - 25
|
if scrollTop < scrollHeight - height - 25
|
||||||
if $('#timsChatAutoscroll').data('status') is 1
|
if $('#timsChatAutoscroll').data('status') is 1
|
||||||
scrollUpNotifications = on
|
scrollUpNotifications = on
|
||||||
$('#timsChatAutoscroll').click()
|
do $('#timsChatAutoscroll').click
|
||||||
|
|
||||||
if scrollTop > scrollHeight - height - 10
|
if scrollTop > scrollHeight - height - 10
|
||||||
if $('#timsChatAutoscroll').data('status') is 0
|
if $('#timsChatAutoscroll').data('status') is 0
|
||||||
scrollUpNotifications = off
|
scrollUpNotifications = off
|
||||||
$(@).removeClass 'notification'
|
$(@).removeClass 'notification'
|
||||||
$('#timsChatAutoscroll').click()
|
do $('#timsChatAutoscroll').click
|
||||||
|
|
||||||
Enable duplicate tab detection.
|
Enable duplicate tab detection.
|
||||||
|
|
||||||
@ -332,11 +331,11 @@ load messages if the appropriate event arrives.
|
|||||||
do ->
|
do ->
|
||||||
be.bastelstu.wcf.nodePush.onConnect ->
|
be.bastelstu.wcf.nodePush.onConnect ->
|
||||||
console.log 'Disabling periodic loading'
|
console.log 'Disabling periodic loading'
|
||||||
pe.getMessages.stop()
|
do pe.getMessages.stop
|
||||||
|
|
||||||
be.bastelstu.wcf.nodePush.onDisconnect ->
|
be.bastelstu.wcf.nodePush.onDisconnect ->
|
||||||
console.log 'Enabling periodic loading'
|
console.log 'Enabling periodic loading'
|
||||||
getMessages()
|
do getMessages
|
||||||
pe.getMessages = new WCF.PeriodicalExecuter getMessages, v.config.reloadTime * 1e3
|
pe.getMessages = new WCF.PeriodicalExecuter getMessages, v.config.reloadTime * 1e3
|
||||||
|
|
||||||
be.bastelstu.wcf.nodePush.onMessage 'be.bastelstu.chat.newMessage', getMessages
|
be.bastelstu.wcf.nodePush.onMessage 'be.bastelstu.chat.newMessage', getMessages
|
||||||
@ -345,18 +344,37 @@ load messages if the appropriate event arrives.
|
|||||||
Finished! Enable the input now and join the chat.
|
Finished! Enable the input now and join the chat.
|
||||||
|
|
||||||
join roomID
|
join roomID
|
||||||
$('#timsChatInput').enable().jCounter().focus();
|
do $('#timsChatInput').enable().jCounter().focus
|
||||||
|
|
||||||
console.log "Finished initializing"
|
console.log "Finished initializing"
|
||||||
|
|
||||||
true
|
true
|
||||||
|
|
||||||
|
Shows an error message below the input.
|
||||||
|
|
||||||
|
showInputError = (message) ->
|
||||||
|
$('#timsChatInputContainer').addClass('formError').find('.innerError').show().html message
|
||||||
|
|
||||||
|
clearTimeout inputErrorHidingTimer if inputErrorHidingTimer?
|
||||||
|
inputErrorHidingTimer = setTimeout ->
|
||||||
|
do hideInputError
|
||||||
|
, 5e3
|
||||||
|
|
||||||
|
Hides the error message below the input.
|
||||||
|
|
||||||
|
hideInputError = ->
|
||||||
|
clearTimeout inputErrorHidingTimer if inputErrorHidingTimer?
|
||||||
|
inputErrorHidingTimer = null
|
||||||
|
|
||||||
|
do $('#timsChatInputContainer').removeClass('formError').find('.innerError').hide
|
||||||
|
|
||||||
Free the fish.
|
Free the fish.
|
||||||
|
|
||||||
freeTheFish = ->
|
freeTheFish = ->
|
||||||
return if $.wcfIsset 'fish'
|
return if $.wcfIsset 'fish'
|
||||||
console.warn 'Freeing the fish'
|
console.warn 'Freeing the fish'
|
||||||
fish = $ """<div id="fish">#{WCF.String.escapeHTML('><((((\u00B0>')}</div>"""
|
fish = $ """<div id="fish">#{WCF.String.escapeHTML('><((((\u00B0>')}</div>"""
|
||||||
|
|
||||||
fish.css
|
fish.css
|
||||||
position: 'absolute'
|
position: 'absolute'
|
||||||
top: '150px'
|
top: '150px'
|
||||||
@ -400,7 +418,7 @@ Fetch new messages from the server and pass them to `handleMessages`. The userli
|
|||||||
error: ->
|
error: ->
|
||||||
console.error "Message loading failed, #{--remainingFailures} remaining"
|
console.error "Message loading failed, #{--remainingFailures} remaining"
|
||||||
if remainingFailures <= 0
|
if remainingFailures <= 0
|
||||||
freeTheFish()
|
do freeTheFish
|
||||||
console.error 'To many failures, aborting'
|
console.error 'To many failures, aborting'
|
||||||
|
|
||||||
showError WCF.Language.get 'chat.error.onMessageLoad'
|
showError WCF.Language.get 'chat.error.onMessageLoad'
|
||||||
@ -532,7 +550,7 @@ Remove all users that left the chat.
|
|||||||
$('.timsChatUser').each ->
|
$('.timsChatUser').each ->
|
||||||
unless foundUsers[$(@).attr('id')]?
|
unless foundUsers[$(@).attr('id')]?
|
||||||
console.log "Removing User: '#{$(@).data('username')}'"
|
console.log "Removing User: '#{$(@).data('username')}'"
|
||||||
$(@).remove();
|
do $(@).remove
|
||||||
|
|
||||||
|
|
||||||
$('#toggleUsers .badge').text $('.timsChatUser').length
|
$('#toggleUsers .badge').text $('.timsChatUser').length
|
||||||
@ -548,12 +566,12 @@ the existing text. If `options.submit` is true the message will be sent to the s
|
|||||||
|
|
||||||
text = $('#timsChatInput').val() + text if options.append
|
text = $('#timsChatInput').val() + text if options.append
|
||||||
$('#timsChatInput').val text
|
$('#timsChatInput').val text
|
||||||
$('#timsChatInput').keyup()
|
do $('#timsChatInput').keyup
|
||||||
|
|
||||||
if (options.submit)
|
if options.submit
|
||||||
$('#timsChatForm').submit()
|
do $('#timsChatForm').submit
|
||||||
else
|
else
|
||||||
$('#timsChatInput').focus()
|
do $('#timsChatInput').focus
|
||||||
|
|
||||||
Send out notifications for the given `message`. The number of unread messages will be prepended to `document.title` and if available desktop notifications will be sent.
|
Send out notifications for the given `message`. The number of unread messages will be prepended to `document.title` and if available desktop notifications will be sent.
|
||||||
|
|
||||||
@ -575,9 +593,9 @@ Send out notifications for the given `message`. The number of unread messages wi
|
|||||||
notification = new window.Notification title,
|
notification = new window.Notification title,
|
||||||
body: content
|
body: content
|
||||||
onclick: ->
|
onclick: ->
|
||||||
notification.close()
|
do notification.close
|
||||||
setTimeout ->
|
setTimeout ->
|
||||||
notification.close()
|
do notification.close
|
||||||
, 5e3
|
, 5e3
|
||||||
|
|
||||||
Fetch the roomlist from the server and update it in the GUI.
|
Fetch the roomlist from the server and update it in the GUI.
|
||||||
@ -593,7 +611,7 @@ Fetch the roomlist from the server and update it in the GUI.
|
|||||||
showLoadingOverlay: false
|
showLoadingOverlay: false
|
||||||
suppressErrors: true
|
suppressErrors: true
|
||||||
success: (data) ->
|
success: (data) ->
|
||||||
$('.timsChatRoom').remove()
|
do $('.timsChatRoom').remove
|
||||||
$('#toggleRooms .badge').text data.returnValues.length
|
$('#toggleRooms .badge').text data.returnValues.length
|
||||||
|
|
||||||
for room in data.returnValues
|
for room in data.returnValues
|
||||||
@ -604,8 +622,8 @@ Fetch the roomlist from the server and update it in the GUI.
|
|||||||
|
|
||||||
if window.history?.replaceState?
|
if window.history?.replaceState?
|
||||||
$('.timsChatRoom').click (event) ->
|
$('.timsChatRoom').click (event) ->
|
||||||
event.preventDefault()
|
do event.preventDefault
|
||||||
target = $(@)
|
target = $ @
|
||||||
|
|
||||||
window.history.replaceState {}, '', target.attr 'href'
|
window.history.replaceState {}, '', target.attr 'href'
|
||||||
|
|
||||||
@ -623,8 +641,8 @@ Shows an unrecoverable error with the given text.
|
|||||||
|
|
||||||
loading = true
|
loading = true
|
||||||
|
|
||||||
pe.refreshRoomList.stop()
|
do pe.refreshRoomList.stop
|
||||||
pe.getMessages.stop()
|
do pe.getMessages.stop
|
||||||
|
|
||||||
errorDialog = $("""
|
errorDialog = $("""
|
||||||
<div id="timsChatLoadingErrorDialog">
|
<div id="timsChatLoadingErrorDialog">
|
||||||
@ -635,7 +653,7 @@ Shows an unrecoverable error with the given text.
|
|||||||
formSubmit = $("""<div class="formSubmit"></div>""").appendTo errorDialog
|
formSubmit = $("""<div class="formSubmit"></div>""").appendTo errorDialog
|
||||||
reloadButton = $("""<button class="buttonPrimary">#{WCF.Language.get 'chat.error.reload'}</button>""").appendTo formSubmit
|
reloadButton = $("""<button class="buttonPrimary">#{WCF.Language.get 'chat.error.reload'}</button>""").appendTo formSubmit
|
||||||
reloadButton.on 'click', ->
|
reloadButton.on 'click', ->
|
||||||
window.location.reload()
|
do window.location.reload
|
||||||
|
|
||||||
$('#timsChatLoadingErrorDialog').wcfDialog
|
$('#timsChatLoadingErrorDialog').wcfDialog
|
||||||
closable: false
|
closable: false
|
||||||
@ -667,15 +685,15 @@ Joins a room.
|
|||||||
|
|
||||||
document.title = v.titleTemplate.fetch data.returnValues
|
document.title = v.titleTemplate.fetch data.returnValues
|
||||||
handleMessages data.returnValues.messages
|
handleMessages data.returnValues.messages
|
||||||
getMessages()
|
do getMessages
|
||||||
refreshRoomList()
|
do refreshRoomList
|
||||||
failure: ->
|
failure: ->
|
||||||
showError WCF.Language.get 'chat.error.join'
|
showError WCF.Language.get 'chat.error.join'
|
||||||
|
|
||||||
Open private channel
|
Open private channel
|
||||||
|
|
||||||
openPrivateChannel = (userID) ->
|
openPrivateChannel = (userID) ->
|
||||||
if !$.wcfIsset "timsChatMessageContainer#{userID}"
|
unless $.wcfIsset "timsChatMessageContainer#{userID}"
|
||||||
return unless $.wcfIsset "timsChatUser#{userID}"
|
return unless $.wcfIsset "timsChatUser#{userID}"
|
||||||
|
|
||||||
div = $('<div>')
|
div = $('<div>')
|
||||||
@ -694,23 +712,25 @@ Open private channel
|
|||||||
Close private channel
|
Close private channel
|
||||||
|
|
||||||
closePrivateChannel = (userID) ->
|
closePrivateChannel = (userID) ->
|
||||||
$("#timsChatMessageContainer#{userID}").remove() unless userID is 0
|
do $("#timsChatMessageContainer#{userID}").remove unless userID is 0
|
||||||
openPrivateChannel 0
|
openPrivateChannel 0
|
||||||
|
|
||||||
Bind the given callback to the given event.
|
Bind the given callback to the given event.
|
||||||
|
|
||||||
addListener = (event, callback) ->
|
addListener = (event, callback) ->
|
||||||
return false unless events[event]?
|
return false unless events[event]?
|
||||||
|
|
||||||
events[event].add callback
|
events[event].add callback
|
||||||
|
|
||||||
|
true
|
||||||
|
|
||||||
Remove the given callback from the given event.
|
Remove the given callback from the given event.
|
||||||
|
|
||||||
removeListener = (event, callback) ->
|
removeListener = (event, callback) ->
|
||||||
return false unless events[event]?
|
return false unless events[event]?
|
||||||
|
|
||||||
events[event].remove callback
|
events[event].remove callback
|
||||||
|
|
||||||
|
true
|
||||||
|
|
||||||
And finally export the public methods and variables.
|
And finally export the public methods and variables.
|
||||||
|
|
||||||
Chat =
|
Chat =
|
||||||
|
Loading…
Reference in New Issue
Block a user