Skip to content

Instantly share code, notes, and snippets.

@andrewliebchen
Created January 12, 2017 16:01
Show Gist options
  • Save andrewliebchen/4633726af3cc3224d95826d5c90b35d9 to your computer and use it in GitHub Desktop.
Save andrewliebchen/4633726af3cc3224d95826d5c90b35d9 to your computer and use it in GitHub Desktop.
Chat in Framer
InputModule = require 'input'
# Data
p =
fontSize: 24
lineHeight: 36
bubbleColor:
left: '#4080FF'
right: '#ccc'
padding: 20
inputHeight: 80
avatarSize: 60
users = [
{
id: 1
name: 'Isaak'
avatar: 'isaak.jpg'
}
{
id: 2
name: 'Garron'
avatar: 'garron.jpg'
}
{
id: 3
name: 'Engly'
avatar: 'engly.jpg'
}
{
id: 4
name: 'Ningxia'
avatar: 'ningxia.jpg'
}
{
id: 5
name: 'Andrew'
avatar: 'andrew.jpg'
}
]
data = [
{
author: 1
message: 'Lorem ipsum dolor sit amet, ei has impetus vituperata adversarium, nihil populo semper eu ius, an eam vero sensibus.'
}
{
author: 2
message: 'In facilisis dignissim mea, no cum blandit accusata contentiones. Luptatum inimicus at usu, ceteros quaerendum eu sed, id eirmod audire epicuri eum. Ea eos idque voluptatum.'
}
{
author: 3
message: 'Nec dolorum mediocrem at.'
}
{
author: 4
message: 'Nec an sonet euismod equidem, velit postulant intellegebat mei eu, eos ea offendit noluisse. Convenire definiebas constituam usu ut.'
}
{
author: 1
message: 'Te mazim.'
}
{
author: 2
message: 'Mel quidam deserunt an.'
}
{
author: 3
message: 'Ea ius tale audiam definitiones. Inani suavitate reprehendunt mea no. Nam quod rebum ea. At erant eruditi antiopam eos. In has idque tempor doctus, sit legere detracto cu.'
}
{
author: 4
message: 'Vel iudico aperiam invenire ne, graecis offendit principes id vix. Est ad sonet tibique, discere volumus oporteat ea vis. At option incorrupte scriptorem ius, in verear meliore vivendo usu, ut cum rebum fugit.'
}
{
author: 1
message: 'Amet eirmod ius ut, cu eum recteque facilisis complectitur.'
}
{
author: 2
message: 'Ex nullam deseruisse duo, no vim novum omittam definitiones, vix mollis indoctum scripserit an. Id persius efficiendi mel, solet iracundia disputationi est ne.'
}
{
author: 3
message: 'Mundi obliqu.'
}
{
author: 4
message: 'Ex saepe explicari pri, iriure appareat constituam te vix. Dicant postulant ocurreret cum eu, nam ne sumo integre assentior. In sumo mundi verterem ius, mel prima placerat praesent te.'
}
]
# Functions
renderComment = (comment, align) ->
# Calcuate the message size
@_messageSize = Utils.textSize comment.message,
{'padding': "#{p.padding}px"},
{width: Screen.width * 0.6}
@_leftPadding = p.padding * 2 + p.avatarSize
# Find the author
@_author = _.find users, {id: comment.author}
# Construct the comment
@comment = new Layer
parent: commentsScroll.content
name: 'comment'
width: Screen.width
height: @_messageSize.height + p.lineHeight * 2
@author = new Layer
name: 'comment:author'
html: @_author.name
parent: @comment
x: if align is 'left' then Align.right(-p.padding) else @_leftPadding
width: @comment.width
color: '#999'
style:
'font-weight': 'bold'
'font-size': '90%'
'text-align': if align is 'left' then 'right' else 'left'
@message = new Layer
name: 'comment:message'
parent: @comment
html: comment.message
height: @_messageSize.height
y: p.lineHeight
x: if align is 'left' then Align.right(-p.padding) else @_leftPadding
backgroundColor: if align is 'left' then p.bubbleColor.right else p.bubbleColor.left
color: if align is 'left' then '#333' else 'white'
borderRadius: p.padding
style:
'padding': "#{p.padding}px"
'width': 'auto'
'max-width': "#{@_messageSize.width}px"
'text-align': if align is 'left' then 'right' else 'left'
unless align is 'left'
@avatar = new Layer
parent: @comment
name: 'comment:avatar'
size: p.avatarSize
borderRadius: p.avatarSize / 2
image: "images/#{@_author.avatar}"
x: p.padding
y: Align.bottom(-p.padding * 2)
reflow = () ->
@commentsHeight = 0
@comments = commentsScroll.content.children
# Loop through all the comments
for comment, i in @comments
commentsHeight = @commentsHeight + comment.height
@yOffset = 0
# Add up the height of the sibling layers to the left of the current layer
for layer in _.take(@comments, i)
@yOffset = @yOffset + layer.height
# Set the current comment position to the height of left siblings
comment.y = yOffset
# Scroll stuff
commentsScroll.updateContent()
commentsScroll.scrollToLayer @comments[@comments.length - 1]
# Draw main comments
Framer.Defaults.Layer =
color: 'black'
backgroundColor: null
background = new BackgroundLayer
backgroundColor: 'white'
commentsScroll = new ScrollComponent
width: Screen.width
height: Screen.height - p.inputHeight
mouseWheelEnabled: true
scrollHorizontal: false
commentsScroll.contentInset =
top: p.padding
# Iterate through comments, render then reflow
_.map data, (comment) ->
renderComment(comment)
reflow()
# Input
inputWrapper = new Layer
height: p.inputHeight
width: Screen.width
y: Align.bottom
style:
'border-top': '1px solid #ccc'
input = new InputModule.Input
# setup: true
parent: inputWrapper
width: Screen.width
placeholder: 'Start chatting'
virtualKeyboard: false
input.on 'keyup', (event) ->
# Add new comments
if event.which is 13
renderComment {author: 5, message: @value}, 'left'
reflow()
@value = ''
input.form.addEventListener "submit", (event) ->
event.preventDefault()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment