-
Notifications
You must be signed in to change notification settings - Fork 4
/
script.js
259 lines (209 loc) · 6.34 KB
/
script.js
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
/************************/
/* ANYWHERE */
/************************/
People = new Mongo.Collection("people");
// Enable to pull in data from q42.nl instead of local
/*
q42nl = DDP.connect("http://q42.nl");
People = new Meteor.Collection("Employees", q42nl);
q42nl.subscribe("employees");
*/
/************************/
/* CLIENT */
/************************/
if (Meteor.isClient) {
// Set some default session values when starting up
Meteor.startup(function() {
Session.setDefault("sortby", "name");
Session.setDefault("sortdir", 1);
});
Template.people.helpers({
// The list of people, which can be sorted depending
// on session values
people: function() {
var sortby = Session.get("sortby");
var sortdir = Session.get("sortdir");
var sort = {};
sort[sortby] = sortdir;
return People.find({}, {sort: sort});
},
// How many people there are
numberPeople: function() {
return People.find().count();
},
// Show the current plusones or zero if the property
// doesn't exist
plusones: function() {
return this.plusones || 0;
},
// Hacky check to determine whether this item is the same
// as the currently logged in user
isMe: function() {
if (!this.name) return false;
return this.name.toLowerCase().indexOf(
Meteor.user().profile.name.toLowerCase()) == 0;
},
// Whether to disable the +1 button if the current user
// already voted for that person
disabled: function() {
return _.contains(this.voters, Meteor.user()._id)
? " disabled" : "";
},
// The currently sorted column
sort: function() {
return Session.get("sortby");
},
// Whether the current item is selected or not
selected: function() {
return Session.equals("selected", this._id)
? "selected" : "";
},
// Format a date to display when the last vote was added
// for this person
lastvote: function() {
if (this.lastvote)
return moment(this.lastvote).fromNow();
return "never";
},
// Draw an arrow up or down depending on whether and how
// we're sorting this column
sortby: function(col) {
if (Session.equals("sortby", col) &&
Session.equals("sortdir", 1))
return "↑"
else if (Session.equals("sortby", col) &&
Session.equals("sortdir", -1))
return "↓";
else return "";
},
// Generate a shade of green depending on how many votes
// the maximum upvoted user has
bgc: function(plusones) {
var max = People.findOne({}, {sort: {plusones: -1}})
.plusones;
max = max || 1;
plusones = plusones || 0;
var n = ~~(plusones / max * 100 + 155);
var c = [Math.max(0, n - 80), n, Math.max(0, n - 80)]
.join(",")
return "background: rgb(" + c + ")";
}
});
// Define some events for the people template
Template.people.events({
'click .button': function() {
// Call the server method "plusone" with the current
// person's id when we click the +1 button
Meteor.call("plusone", this._id);
},
'click tbody tr': function() {
// Select the current item when we click it
Session.set('selected', this._id);
},
'click thead th': function(evt) {
// Sort by the column we just clicked, or reverse the
// sort order if already sorting by it
Session.set("sortby",
evt.target.getAttribute("data-sortby"));
Session.set("sortdir", Session.get("sortdir") * -1);
}
});
}
/************************/
/* SERVER */
/************************/
if (Meteor.isServer) {
// Define some access rights for the People collection
People.allow({
// Allow all inserts
insert: function() { return true; },
// only allow updates that increment plusones by 1 and
// disallow upvoting yourself
update: function(userId, docs, fields, modifier) {
var isMe = docs[0].name.toLowerCase() ===
Meteor.user().profile.name.toLowerCase();
var isPlusOne = _.keys(modifier).length == 1
&& modifier["$inc"] && modifier["$inc"].plusones == 1;
return isPlusOne && !isMe;
}
});
// Watch the People collection and act if a change matches
// our observer
People.find({}).observe({
changed: function(newDoc, atIndex, oldDoc) {
// If a person is upvoted beyond 42 upvotes, send Rahul
// an email :)
if (newDoc.plusones >= 42 && oldDoc.plusones < 42) {
Email.send({
to: "[email protected]",
from: "[email protected]",
subject: "Someone reached +42!",
text: newDoc.name +
" reached +42 votes in the Meteor Demo! W000000t"
});
}
}
});
// Define some API methods that the client can use
Meteor.methods({
// Plusone a person by ID. Doesn't do anything if the
// current user already voted for this person.
plusone: function(id) {
var record = People.findOne(id);
if (_.contains(record.voters, Meteor.user()._id))
return;
People.update(id, {
$inc: {plusones: 1},
$addToSet: {voters: Meteor.user()._id},
$set: {lastvote: new Date()}
});
}
});
/************************/
/* DEMO UTILITY METHODS */
/************************/
Meteor.methods({
empty: function() {
People.remove({});
},
reset: function() {
People.remove({});
// Prefill the database with people who signed up for this talk :)
var people = [
"Albert Netymk",
"Albin Larsson",
"Anton Malmberg",
"Asma Rafiq",
"Bas Kloppenborg",
"CalleR",
"Carl Byström",
"Christian Nygaard",
"Hesham",
"Håkan Rosenhorn",
"Johan Althoff",
"Johan Andersson",
"Johan Olsson",
"Jonathon Walker",
"Karl Pokus",
"kenny duong",
"Kim Carlbäcker",
"Kvadratrot",
"Linus Österberg",
"Marcus Ekwall",
"Mathias Anderssén",
"Oskar Flordal",
"paer Henrikxon",
"Peramanathan Sathyamoorthy",
"Rahul Choudhury",
"Richard Norqvist"
];
_.each(people, function(person) {
People.insert({
name: person,
plusones: 0,
voters: []
});
});
}
});
}