context = window rest = new context.JK.Rest() ChatActions = @ChatActions @ChatWindow = React.createClass({ mixins: [Reflux.listenTo(@AppStore, "onAppInit"), Reflux.listenTo(@UserStore, "onUserChanged"), Reflux.listenTo(@ChatStore, "onChatChanged")] lastChannel: null getInitialState: () -> state = context.ChatStore.getState() state getInitialProps: () -> {newFormat:true} onChatChanged: (chatState) -> @setState(chatState) onUserChanged: (userState) -> @setState(userState) onAppInit: (app) -> @app = app activateChannel: (channel, e) -> e.preventDefault() ChatActions.activateChannel(channel); convertPurpose: (purpose) -> if !purpose? return '' switch purpose when 'Lesson Requested' then 'requested lesson' when 'Lesson Canceled' then 'canceled lesson' when 'Lesson Approved' then 'approved lesson' when 'All Lesson Times Updated' then 'updated all lesson times' when 'Lesson Updated Time Approved' then 'updated lesson time' when 'New Time Proposed' then 'proposed new time' when 'Lesson Declined' then 'declined lesson' when 'Notation File' then 'attached a notation file' when 'Audio File' then 'attached an audio file' when 'JamKazam Recording' then 'attached a recording' when 'Lesson Timeout' then 'canceled by system' else purpose notationClicked: (music_notation, e) -> e.preventDefault() context.JK.popExternalLink("/api/music_notations/#{music_notation.id}?target=_blank") audioClicked: (music_notation, e) -> e.preventDefault() context.JK.popExternalLink("/api/music_notations/#{music_notation.id}?target=_blank") recordingClicked: (recording, e) -> e.preventDefault() context.JK.popExternalLink("/recordings/#{recording.id}") openMenu: (lesson, e) -> $this = $(e.target) if !$this.is('.lesson-session-actions-btn') $this = $this.closest('.lesson-session-actions-btn') $this.btOn() render: () -> if @state.channel == 'lesson' chatTabs = `
attach file
` else if !this.props.hideHeader tabs = [] for channel of @state.msgs classes = {} classes[channel] = true classes['chat-tab'] = true classes['active'] = channel == @state.channel if channel == 'global' display = 'Global' else if channel == 'session' display = 'Session' else if channel == 'lesson' display = 'Lesson' else if !channel? display = 'Global' else display = 'Unknown' if display == 'Unknown' continue tabs.push(`
{display}
`) chatTabs = `
{tabs}
` msgs = [] if @activeChannelType() == 'lesson' activeChannel = @state.lessonSessionId else activeChannel = @state.channel activeMsgs = @state.msgs[activeChannel] || [] for msg in activeMsgs timeago = $.timeago(msg.created_at) if msg.sender_id == context.JK.currentUserId sender = "me" else sender = msg.sender_name if msg.purpose purpose = `
{this.convertPurpose(msg.purpose)}
` else purpose = null additional = null if msg.purpose == 'Notation File' additional = `{msg.music_notation.file_name}` else if msg.purpose == 'Audio File' additional = `{msg.music_notation.file_name}` else if msg.purpose == 'JamKazam Recording' additional = `{msg.claimed_recording.name}` msgs.push(`
{sender}{purpose} {msg.msg} {additional}
`) if this.props?.showEmailNotice otherName = this.props?.other?.name emailSentNotice = `
an email will be sent if {otherName} is offline
` if this.props?.showClose closeBtn = `CLOSE` topClasses = {ChatWindow: true} if this.props?.rootClass? topClasses[this.props.rootClass] = true if this.props.rootClass == 'ChatDialog' attachFiles = `attach file
` `
{chatTabs}
{msgs}
SEND {closeBtn} {emailSentNotice} {attachFiles}
` activeChannelType: () -> @state.channelType sendMessage:()-> if !context.JK.JamServer.connected return false msg = @textBox.val() if !msg? || msg == '' # don't bother the server with empty messages return false; if !@sendingMessage @sendingMessage = true target_user_id = this.props?.other?.id ChatActions.sendMsg(msg, @sendMsgDone, @sendMsgFail, target_user_id, @activeChannelType()) sendMsgDone: () -> @textBox.val('') @sendingMessage = false sendMsgFail: (jqXHR) -> 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 handleSendMessage: (e) -> e.preventDefault() @sendMessage() handleCloseMessage: (e) -> e.preventDefault() this.props.onCloseClicked() componentDidMount: () -> @root = $(@getDOMNode()) @textBox = @root.find('textarea') componentDidUpdate: () -> if @lastChannel != @state.channel speed = 0 else speed = 'slow' @lastChannel = @state.channel #speed = 0 #slow $scroller = @root.find('.chat-list-scroller') $scroller.animate({scrollTop: $scroller[0].scrollHeight}, speed) items = @root.find('.chat-tabs .lesson-session-actions-btn') @hookupMenu(items) items = @root.find('#attach-files-chat-dialog') @hookupMenu(items) hookupMenu: (items) -> $.each(items, (i, node) => ( $node = $(node) chat_dialog = this.props.rootClass == 'ChatDialog' lesson = {id: $node.attr('data-lesson-id'), attachments_only: true, chat_dialog: chat_dialog} $node.lessonSessionActions(lesson).off(context.JK.EVENTS.LESSON_SESSION_ACTION).on(context.JK.EVENTS.LESSON_SESSION_ACTION, @lessonSessionActionSelected) )) lessonSessionActionSelected: (e, data) -> lessonId = data.options.id if data.lessonAction == 'attach-recording' window.AttachmentActions.startAttachRecording(lessonId) else if data.lessonAction == 'attach-notation' window.AttachmentActions.startAttachNotation(lessonId) else if data.lessonAction == 'attach-audio' window.AttachmentActions.startAttachAudio(lessonId) pasteIntoInput: (el, text) -> el.focus(); if typeof el.selectionStart == "number" && typeof el.selectionEnd == "number" val = el.value selStart = el.selectionStart el.value = val.slice(0, selStart) + text + val.slice(el.selectionEnd) el.selectionEnd = el.selectionStart = selStart + text.length else if typeof document.selection != "undefined" textRange = document.selection.createRange() textRange.text = text textRange.collapse(false) textRange.select() handleEnter: (evt) -> if evt.keyCode == 13 && evt.shiftKey evt.preventDefault() @pasteIntoInput($(evt.target).get(0), "\n") else if evt.keyCode == 13 && !evt.shiftKey @sendMessage() })