-
Notifications
You must be signed in to change notification settings - Fork 11
/
common.coffee
203 lines (158 loc) · 5.57 KB
/
common.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
urlExp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig
UI.registerHelper "replaceURLs", (text) ->
# Shim so old links aren't broken, can be removed later for speed
return text if text.indexOf("target='_blank'>") > -1
text.replace(urlExp, "<a href='$1' target='_blank'>$1</a>")
Template.userList.helpers
loaded: -> Session.equals("userSubReady", true)
users: -> Meteor.users.find()
Template.userPill.helpers
labelClass: ->
if @_id is Meteor.userId()
"inverse"
else if @status?.online
"success"
else "default"
Template.userPill.events =
"click .action-chat-invite": (e) ->
myId = Meteor.userId()
unless myId?
bootbox.alert("You must be logged in to invite others to chat.")
return
myRoom = Session.get("room")
unless myRoom?
bootbox.alert("Join a chat room first to invite someone to chat with you.")
return
user = Blaze.getData(e.target)
if ChatUsers.findOne(userId: user._id)?
bootbox.alert("You and #{user.username} are already in the same room.")
return
bootbox.confirm "Invite #{user.username} to join you in <b>" + ChatRooms.findOne(myRoom).name + "</b>?"
, (result) ->
Meteor.call "inviteChat", user._id, myRoom if result
# String conversion needed: https://github.com/meteor/meteor/issues/1447
Handlebars.registerHelper "findTweet", -> Datastream.findOne(""+@)
Handlebars.registerHelper "lookupUser", -> Meteor.users.findOne(""+@)
###
XXX tweet icon mouseover and dragging is handled at the global page level and the
event page level respectively
###
Template.tweetIcon.events =
"click .action-unlink-tweet": (e) ->
# This needs to work on both events and map
# both the table row and the popup are .event-record
tweet = Blaze.getData(e.target)
event = Blaze.getData $(e.target).closest(".event-record")[0]
# The unlink function will also hide this if it's not tagged somewhere
# TODO: the unlink-hide process causes an unwanted scroll adjustment
Meteor.call "dataUnlink", tweet._id, event._id
# Mapping helpers
epsg4326 = new OpenLayers.Projection("EPSG:4326")
epsg900913 = new OpenLayers.Projection("EPSG:900913")
transformLocation = (location) ->
point = new OpenLayers.Geometry.Point(location[0], location[1])
point.transform(epsg900913, epsg4326)
return [point.x, point.y]
formatLocation = (location) ->
return "" unless location
[x, y] = transformLocation(location)
return x.toFixed(2) + ", " + y.toFixed(2)
Handlebars.registerHelper "formatLocation", -> formatLocation(@location)
transformLongLat = (longlat) ->
point = new OpenLayers.Geometry.Point(longlat[0], longlat[1])
point.transform(epsg4326, epsg900913)
return [point.x, point.y]
minLongLat = transformLocation([Mapper.extent[0], Mapper.extent[1]])
maxLongLat = transformLocation([Mapper.extent[2], Mapper.extent[3]])
entryPrecision = 3
Template.longLatEntry.helpers
minLong: minLongLat[0].toFixed(entryPrecision)
maxLong: maxLongLat[0].toFixed(entryPrecision)
minLat: minLongLat[1].toFixed(entryPrecision)
maxLat: maxLongLat[1].toFixed(entryPrecision)
# LongLat editable
# see http://vitalets.github.io/x-editable/assets/x-editable/inputs-ext/address/address.js
LongLat = (options) ->
@init("longlat", options, LongLat.defaults)
return
# inherit from Abstract input
$.fn.editableutils.inherit(LongLat, $.fn.editabletypes.abstractinput)
$.extend LongLat.prototype, {
###
Renders input from tpl
@method render()
###
render: ->
@$input = @$tpl.find("input")
return
###
Default method to show value in element. Can be overwritten by display option.
@method value2html(value, element)
###
value2html: (value, element) ->
unless value
$(element).empty()
return
# Call above function to render
$(element).html formatLocation(value)
return
###
Gets value from element's html
We set value directly via javascript.
@method html2value(html)
###
html2value: (html) -> null
###
Converts value to string.
It is used in internal comparing (not for sending to server).
@method value2str(value)
###
value2str: formatLocation # This will ignore manual changes to the third decimal place.
###
Converts string to value. Used for reading value from 'data-value' attribute.
this is mainly for parsing value defined in data-value attribute.
If you will always set value by javascript, no need to overwrite it
@method str2value(str)
###
str2value: (str) -> str
###
Sets value of input.
@method value2input(value)
@param {mixed} value
###
value2input: (value) ->
return unless value
transformed = transformLocation(value)
@$input.filter('[name="long"]').val transformed[0].toFixed(entryPrecision)
@$input.filter('[name="lat"]').val transformed[1].toFixed(entryPrecision)
return
###
Returns value of input.
@method input2value()
###
input2value: ->
transformLongLat [
@$input.filter('[name="long"]').val(),
@$input.filter('[name="lat"]').val()
]
###
Activates input: sets focus on the first field.
@method activate()
###
activate: ->
@$input.filter('[name="long"]').focus()
return
###
Attaches handler to submit form in case of 'showbuttons=false' mode
@method autosubmit()
###
autosubmit: ->
@$input.keydown (e) ->
$(this).closest("form").submit() if e.which is 13
return
return
}
LongLat.defaults = $.extend {}, $.fn.editabletypes.abstractinput.defaults,
tpl: Blaze.toHTML Template.longLatEntry # No reactive contents
inputclass: ""
$.fn.editabletypes.longlat = LongLat