Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .meteor/packages
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ mizzao:autocomplete
mizzao:timesync
momentjs:moment
monbro:mongodb-mapreduce-aggregation
mquandalle:jquery-textcomplete
mrt:mask
mrt:publish-with-relations
mrt:reactive-store
Expand Down
1 change: 0 additions & 1 deletion .meteor/versions
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ momentjs:moment@2.10.3
monbro:mongodb-mapreduce-aggregation@1.0.1
mongo@1.1.0
mongo-livedata@1.0.8
mquandalle:jquery-textcomplete@0.3.9_1
mrt:mask@0.0.1
mrt:publish-with-relations@0.1.5
mrt:reactive-store@0.0.1
Expand Down
24 changes: 0 additions & 24 deletions client/lib/chatMessages.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,6 @@
resize()
toBottom() if self.scrollable

$(".input-message").textcomplete [ {
match: /\B:([\-+\w]*)$/
search: (term, callback) ->
results = []
$.each emojione.emojioneList, (shortname, data) ->
if shortname.indexOf(term) > -1
results.push shortname
return
if term.length >= 3
results.sort (a, b) ->
a.length > b.length
callback results
return
template: (shortname) ->
length = emojione.emojioneList[shortname].length
'<img class="emojione" src="//cdn.jsdelivr.net/emojione/assets/png/' + emojione.emojioneList[shortname][length - 1].toUpperCase() + '.png"> ' + shortname
replace: (shortname) ->
event.stopPropagation()
event.preventDefault()
shortname
index: 1
maxCount: 10
} ], footer: '', placement: 'top'

return

isScrollable = ->
Expand Down
26 changes: 26 additions & 0 deletions client/stylesheets/base.less
Original file line number Diff line number Diff line change
Expand Up @@ -1411,6 +1411,32 @@ a.github-fork {
left: 0;
width: 100%;
}
.message-popup {
position: absolute;
background: #FFF;
border: 1px solid #DDD;
z-index: 101;
bottom: 61px;
left: 20px;
right: 20px;
box-shadow: 0px 0px 10px #DDD;
border-radius: 5px 5px 0 0;
overflow: hidden;
.message-popup-title {
background-color: #FAFAFA;
border-bottom: 1px solid #EEE;
padding: 6px;
}
.popup-item {
padding: 6px;
border-bottom: 1px solid #fff;
&.selected {
background-color: #439ee1;
border-color: #2b80ba;
color: white;
}
}
}
.message-form {
> div {
position: relative;
Expand Down
45 changes: 44 additions & 1 deletion client/views/app/chatWindowDashboard.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,49 @@ Template.chatWindowDashboard.helpers
else
return t('chatWindowDashboard.See_all')

popupConfig: ->
template = Template.instance()
config =
title: 'People'
collection: Meteor.users
template: 'messagePopupUser'
getInput: ->
return template.find('.input-message')
getFilter: (collection, filter) ->
return collection.find name: new RegExp(filter, 'i')

return config

popupEmojiConfig: ->
template = Template.instance()
config =
title: 'Emoji'
collection: emojione.emojioneList
template: 'messagePopupEmoji'
trigger: ':'
prefix: ''
getInput: ->
return template.find('.input-message')
getFilter: (collection, filter) ->
results = []
for shortname, data of collection
if shortname.indexOf(filter) > -1
results.push
_id: shortname
data: data

if results.length > 10
break

if filter.length >= 3
results.sort (a, b) ->
a.length > b.length

return results

return config


Template.chatWindowDashboard.events
"click .flex-tab .more": (event) ->
Session.set('flexOpened', !Session.get('flexOpened'))
Expand Down Expand Up @@ -279,7 +322,7 @@ Template.chatWindowDashboard.events

'keydown .input-message': (event) ->
console.log 'chatWindowDashboard.keydown.input-message',this._id if window.rocketDebug
ChatMessages.keydown(this._id, event)
ChatMessages.keydown(this._id, event, Template.instance())

'keydown .input-message-editing': (event) ->
console.log 'chatWindowDashboard.keydown.input-message-editing',this._id if window.rocketDebug
Expand Down
2 changes: 2 additions & 0 deletions client/views/app/chatWindowDashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ <h2>
<span>{{_ "chatWindowDashboard.New_messages"}}</span>
</div>
</div>
{{> messagePopup popupEmojiConfig}}
{{> messagePopup popupConfig}}
<footer class="footer">
<form class="message-form" method="post" action="/">
<div>
Expand Down
4 changes: 4 additions & 0 deletions client/views/app/message-popup-emoji.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Template.messagePopupEmoji.helpers
value: ->
length = this.data.length
return this.data[length - 1].toUpperCase()
3 changes: 3 additions & 0 deletions client/views/app/message-popup-emoji.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template name="messagePopupEmoji">
<img class="emojione" src="//cdn.jsdelivr.net/emojione/assets/png/{{value}}.png"> {{_id}}
</template>
3 changes: 3 additions & 0 deletions client/views/app/message-popup-user.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template name="messagePopupUser">
{{name}}
</template>
162 changes: 162 additions & 0 deletions client/views/app/message-popup.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
getCursorPosition = (input) ->
if not input? then return
if input.selectionStart?
return input.selectionStart
else if document.selection?
input.focus()
sel = document.selection.createRange()
selLen = document.selection.createRange().text.length
sel.moveStart('character', - input.value.length)
return sel.text.length - selLen

setCursorPosition = (input, caretPos) ->
if not input? then return
if input.selectionStart?
input.focus()
return input.setSelectionRange(caretPos, caretPos)
else if document.selection?
range = input.createTextRange()
range.move('character', caretPos)
range.select()

val = (v, d) ->
return if v? then v else d

Template.messagePopup.onCreated ->
template = this

template.textFilter = new ReactiveVar ''

template.open = new ReactiveVar false

template.value = new ReactiveVar

template.trigger = val(template.data.trigger, '@')

template.prefix = val(template.data.prefix, template.trigger)

template.suffix = val(template.data.suffix, ' ')

template.matchSelectorRegex = val(template.data.matchSelectorRegex, new RegExp "#{template.trigger}[A-Za-z0-9-_]*$")

template.selectorRegex = val(template.data.selectorRegex, new RegExp "#{template.trigger}([A-Za-z0-9-_]*)$")

template.replaceRegex = val(template.data.replaceRegex, new RegExp "#{template.trigger}[A-Za-z0-9-_]*$")

template.up = =>
current = template.find('.popup-item.selected')
previous = current.previousElementSibling or template.find('.popup-item:last-child')
if previous?
current.className = current.className.replace /\sselected/, ''
previous.className += ' selected'
template.value.set previous.getAttribute('data-id')

template.down = =>
current = template.find('.popup-item.selected')
next = current.nextElementSibling or template.find('.popup-item')
if next?
current.className = current.className.replace /\sselected/, ''
next.className += ' selected'
template.value.set next.getAttribute('data-id')

template.verifySelection = =>
current = template.find('.popup-item.selected')
if not current?
first = template.find('.popup-item')
if first?
first.className += ' selected'
template.value.set first.getAttribute('data-id')

template.onInputKeydown = (event) =>
if template.open.curValue isnt true
return

if event.which is 13
template.open.set false

value = template.input.value
caret = getCursorPosition(template.input)
firstPartValue = value.substr 0, caret
lastPartValue = value.substr caret

firstPartValue = firstPartValue.replace(template.selectorRegex, template.prefix + template.value.curValue + template.suffix)

template.input.value = firstPartValue + lastPartValue

setCursorPosition template.input, firstPartValue.length

event.preventDefault()
event.stopPropagation()

template.onInputKeyup = (event) =>
if template.open.curValue is true and event.which is 27
template.open.set false
event.preventDefault()
event.stopPropagation()
return

value = template.input.value
value = value.substr 0, getCursorPosition(template.input)

if template.matchSelectorRegex.test value
template.textFilter.set(value.match(template.selectorRegex)[1])
template.open.set true
else
template.open.set false

if template.open.curValue isnt true
return

if event.which is 38
template.up()
else if event.which is 40
template.down()
else
Meteor.defer =>
template.verifySelection()


Template.messagePopup.onRendered ->
this.input = this.data.getInput?()
$(this.input).on 'keyup', this.onInputKeyup.bind this
$(this.input).on 'keydown', this.onInputKeydown.bind this


Template.messagePopup.onDestroyed ->
$(this.input).off 'keyup', this.onInputKeyup
$(this.input).off 'keydown', this.onInputKeydown


Template.messagePopup.events
'mouseenter .popup-item': (e) ->
if e.currentTarget.className.indexOf('selected') > -1
return

template = Template.instance()

current = template.find('.popup-item.selected')
if current?
current.className = current.className.replace /\sselected/, ''
e.currentTarget.className += ' selected'
template.value.set this._id

'click .popup-item': (e) ->
template = Template.instance()

template.value.set this._id

template.open.set false


Template.messagePopup.helpers
isOpen: ->
Template.instance().open.get()

data: ->
template = Template.instance()
filter = template.textFilter.get()
result = template.data.getFilter template.data.collection, filter
if (template.data.collection instanceof Meteor.Collection and result.count() is 0) or result?.length is 0
template.open.set false

return result
16 changes: 16 additions & 0 deletions client/views/app/message-popup.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<template name="messagePopup">
{{#if isOpen}}
<div class="message-popup">
<div class="message-popup-title">
{{title}}
</div>
<div>
{{#each data}}
<div class="popup-item" data-id="{{_id}}">
{{> Template.dynamic template=../template}}
</div>
{{/each}}
</div>
</div>
{{/if}}
</template>