322:7dfdf32e8577
Anton Shestakov <av6@dwimlabs.net>, Sat, 14 Jul 2018 20:23:13 +0800
index: authorizing contact also adds it to the roster Maybe there are cases when this doesn't make sense, but so far this looks like the right thing to do.

next change 324:da4b66c14a44
previous change 279:01439ae590ed

coffee/contacts.coffee

Permissions: -rw-r--r--

Other formats: Feeds:
class Tram.Contact extends Backbone.Model
idAttribute: 'jid'
defaults:
presence: 'unavailable'
show: 'offline'
initialize: ->
@on 'add change:type change:presence change:callstate change:features', ->
if @get('type') is 'self' then return @unset('d/actions')
if @get('presence') is 'subscribe' then return @set('d/actions', ['authorize', 'unauthorize'])
actions = ['remove']
if @get('presence') isnt 'unavailable' and Tram.NS.WEBRTC in (@get('features') ? [])
switch @get 'callstate'
when 'established'
actions.push('hang-up')
when 'outgoing'
actions.push('wait', 'hang-up')
when 'incoming'
actions.push('accept', 'decline')
else
actions.push('call')
@set('d/actions', actions)
class Tram.Profile extends Backbone.Model
idAttribute: 'bjid'
optimizeSide: 96
optimizeThreshold: 10000
initialize: ->
@on('add change:avatar', @optimizeAvatar)
@on 'add change:fullname change:nickname', ->
@set('d/handle', @get('fullname') or @get('nickname') or @get('bjid'))
optimizeAvatar: ->
avatar = @get('avatar')
if not (avatar?.mime and avatar?.data)
return @unset('avatar/url')
data = "data:#{ avatar.mime };base64,#{ avatar.data }"
if data.length < @optimizeThreshold
return @set('avatar/url', data)
img = new Image()
img.addEventListener 'load', =>
if img.width < @optimizeSide and img.height < @optimizeSide
return @set('avatar/url', data)
ratio = Math.min(@optimizeSide / img.width, @optimizeSide / img.height)
canvas = document.createElement('canvas')
canvas.height = Math.round(img.height * ratio)
canvas.width = Math.round(img.width * ratio)
ctx = canvas.getContext('2d')
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
mime = 'image/png'
if avatar.mime is 'image/jpeg'
mime = avatar.mime
optimized = canvas.toDataURL(mime)
if img.src.length < optimized.length
@set('avatar/url', data)
else
@set('avatar/url', optimized)
img.src = data
class Tram.Profiles extends Backbone.Collection
model: Tram.Profile
class Tram.Entity extends Backbone.Model
defaults:
identities: []
features: []
class Tram.Entities extends Backbone.Collection
model: Tram.Entity
class Tram.Contacts extends Backbone.Collection
model: Tram.Contact
comparator: (model) ->
if model.get('presence') is 'unavailable'
return 2
else if model.get('presence') is 'subscribe'
return 1
else if model.get('type') is 'self'
return -1
else
return 0
initialize: ->
@on('change:presence change:type', @sort)
class Tram.AvatarView extends Backbone.View
templateEl: $($('#avatar-template').html())
colors: Tram.colors.avatar
initialize: ->
@setElement(@templateEl.clone())
getColors: (hash) =>
ci = hash % @colors.length
"color: white; background: #{ @colors[ci] };"
render: ->
@rivet = rivets.bind(@el, contact: @model, view: @)
@
remove: ->
@rivet.unbind()
super
class Tram.ContactView extends Backbone.View
templateEl: $($('#contact-template').html())
colors: Tram.colors.show
events:
'click [data-chat]': -> @model.trigger('action/chat')
'click [data-authorize]': -> @model.trigger('action/authorize')
'click [data-unauthorize]': -> @model.trigger('action/unauthorize')
'click [data-call]': (event) -> @model.trigger('action/call', event.currentTarget.getAttribute('data-call'))
'click [data-accept]': (event) -> @model.trigger('action/accept', event.currentTarget.getAttribute('data-accept'))
'click [data-decline]': -> @model.trigger('action/decline')
'click [data-hang-up]': -> @model.trigger('action/hangup')
'click [data-remove]': -> @model.trigger('action/remove')
initialize: ->
@setElement(@templateEl.clone())
@$avatarColumn = @$('.avatar-column')
@bind()
bind: ->
@listenTo(@model, 'remove', @remove)
getBorderColor: (show) =>
"border-left-color: #{ @colors[show] || @colors['default'] };"
getPipColor: (show) =>
"background: #{ @colors[show] || @colors['default'] };"
render: ->
@rivet = rivets.bind(@el, contact: @model, view: @)
@av = new Tram.AvatarView(model: @model)
@$avatarColumn.prepend(@av.render().el)
@
remove: ->
@av.remove()
@rivet.unbind()
super
class Tram.ContactsApp extends Backbone.View
initialize: ->
@listenTo(@collection, 'add', @onAdd)
@listenTo(@collection, 'sort', @onSort)
onAdd: (model, collection) ->
mi = collection.indexOf(model)
model.view = new Tram.ContactView(model: model)
el = model.view.render().el
if mi is 0
@$el.prepend(el)
else
@$el.children().eq(mi - 1).after(el)
onSort: (collection, options) ->
if not options.add
collection.each (model) =>
model.view.$el.detach()
@$el.append(model.view.el)