vines-services 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,342 @@
1
+ var SystemsPage;
2
+ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
3
+ SystemsPage = (function() {
4
+ function SystemsPage(session) {
5
+ this.session = session;
6
+ this.session.onRoster(__bind(function() {
7
+ return this.roster();
8
+ }, this));
9
+ this.session.onMessage(__bind(function(m) {
10
+ return this.message(m);
11
+ }, this));
12
+ this.session.onPresence(__bind(function(p) {
13
+ return this.presence(p);
14
+ }, this));
15
+ this.commands = new Commands;
16
+ this.chats = {};
17
+ this.currentContact = null;
18
+ this.layout = null;
19
+ }
20
+ SystemsPage.prototype.datef = function(millis) {
21
+ var d, hour, meridian, minutes;
22
+ d = new Date(millis);
23
+ meridian = d.getHours() >= 12 ? ' pm' : ' am';
24
+ hour = d.getHours() > 12 ? d.getHours() - 12 : d.getHours();
25
+ if (hour === 0) {
26
+ hour = 12;
27
+ }
28
+ minutes = d.getMinutes() + '';
29
+ if (minutes.length === 1) {
30
+ minutes = '0' + minutes;
31
+ }
32
+ return hour + ':' + minutes + meridian;
33
+ };
34
+ SystemsPage.prototype.groupContacts = function() {
35
+ var contact, group, groups, jid, _i, _len, _ref, _ref2;
36
+ groups = {};
37
+ _ref = this.session.roster;
38
+ for (jid in _ref) {
39
+ contact = _ref[jid];
40
+ _ref2 = contact.groups;
41
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
42
+ group = _ref2[_i];
43
+ (groups[group] || (groups[group] = [])).push(contact);
44
+ }
45
+ }
46
+ return groups;
47
+ };
48
+ SystemsPage.prototype.roster = function() {
49
+ var contact, contacts, group, groups, items, name, optgroup, option, sorted, _i, _len, _results;
50
+ groups = this.groupContacts();
51
+ sorted = (function() {
52
+ var _results;
53
+ _results = [];
54
+ for (group in groups) {
55
+ contacts = groups[group];
56
+ _results.push(group);
57
+ }
58
+ return _results;
59
+ })();
60
+ sorted = sorted.sort(function(a, b) {
61
+ a = a.toLowerCase();
62
+ b = b.toLowerCase();
63
+ if (a > b) {
64
+ return 1;
65
+ } else if (a < b) {
66
+ return -1;
67
+ } else {
68
+ return 0;
69
+ }
70
+ });
71
+ items = $('#roster-items').empty();
72
+ _results = [];
73
+ for (_i = 0, _len = sorted.length; _i < _len; _i++) {
74
+ group = sorted[_i];
75
+ contacts = groups[group];
76
+ optgroup = $('<li class="group"></li>').appendTo(items);
77
+ optgroup.text(group);
78
+ optgroup.attr('data-group', group);
79
+ _results.push((function() {
80
+ var _j, _len2, _results2;
81
+ _results2 = [];
82
+ for (_j = 0, _len2 = contacts.length; _j < _len2; _j++) {
83
+ contact = contacts[_j];
84
+ option = $("<li data-jid=\"" + contact.jid + "\">\n <span class=\"text\"></span>\n <span class=\"unread\" style=\"display:none;\"></span>\n</li>").appendTo(items);
85
+ if (contact.offline()) {
86
+ option.addClass('offline');
87
+ }
88
+ option.click(__bind(function(event) {
89
+ return this.selectContact(event);
90
+ }, this));
91
+ name = contact.name || contact.jid.split('@')[0];
92
+ option.attr('data-name', name);
93
+ option.attr('data-group', group);
94
+ _results2.push($('.text', option).text(name));
95
+ }
96
+ return _results2;
97
+ }).call(this));
98
+ }
99
+ return _results;
100
+ };
101
+ SystemsPage.prototype.message = function(message) {
102
+ var bottom, chat, from, me;
103
+ this.queueMessage(message);
104
+ me = message.from === this.session.jid();
105
+ from = message.from.split('/')[0];
106
+ if (me || from === this.currentContact) {
107
+ bottom = this.atBottom();
108
+ this.appendMessage(message);
109
+ if (bottom) {
110
+ return this.scroll({
111
+ animate: true
112
+ });
113
+ }
114
+ } else {
115
+ chat = this.chat(message.from);
116
+ chat.unread++;
117
+ return this.eachContact(from, function(node) {
118
+ return $('.unread', node).text(chat.unread).show();
119
+ });
120
+ }
121
+ };
122
+ SystemsPage.prototype.eachContact = function(jid, callback) {
123
+ var node, _i, _len, _ref, _results;
124
+ _ref = $("#roster-items li[data-jid='" + jid + "']").get();
125
+ _results = [];
126
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
127
+ node = _ref[_i];
128
+ _results.push(callback($(node)));
129
+ }
130
+ return _results;
131
+ };
132
+ SystemsPage.prototype.appendMessage = function(message) {
133
+ var contact, from, me, name, node, prefix, proxied;
134
+ me = message.from === this.session.jid();
135
+ proxied = $('jid', message.node).text();
136
+ from = (proxied || message.from).split('/')[0];
137
+ contact = this.session.roster[from];
138
+ name = contact ? contact.name || from : from;
139
+ node = $("<li data-jid=\"" + from + "\"><pre></pre></li>").appendTo('#messages');
140
+ prefix = me ? '$ ' : '';
141
+ $('pre', node).text(prefix + message.text);
142
+ if (!me) {
143
+ node.append("<footer>\n <span class=\"author\"></span> @\n <span class=\"time\">" + (this.datef(message.received)) + "</span>\n</footer>");
144
+ return $('.author', node).text(name);
145
+ }
146
+ };
147
+ SystemsPage.prototype.queueMessage = function(message) {
148
+ var chat, full, me;
149
+ me = message.from === this.session.jid();
150
+ full = message[me ? 'to' : 'from'];
151
+ chat = this.chat(full);
152
+ chat.jid = full;
153
+ return chat.messages.push(message);
154
+ };
155
+ SystemsPage.prototype.chat = function(jid) {
156
+ var bare, chat;
157
+ bare = jid.split('/')[0];
158
+ chat = this.chats[bare];
159
+ if (!chat) {
160
+ chat = {
161
+ jid: jid,
162
+ messages: [],
163
+ unread: 0
164
+ };
165
+ this.chats[bare] = chat;
166
+ }
167
+ return chat;
168
+ };
169
+ SystemsPage.prototype.presence = function(presence) {
170
+ var contact, from;
171
+ from = presence.from.split('/')[0];
172
+ if (from === this.session.bareJid()) {
173
+ return;
174
+ }
175
+ if (!presence.type || presence.offline) {
176
+ contact = this.session.roster[from];
177
+ this.eachContact(from, function(node) {
178
+ if (contact.offline()) {
179
+ return node.addClass('offline');
180
+ } else {
181
+ return node.removeClass('offline');
182
+ }
183
+ });
184
+ }
185
+ if (presence.offline) {
186
+ return this.chat(from).jid = from;
187
+ }
188
+ };
189
+ SystemsPage.prototype.selectContact = function(event) {
190
+ var contact, jid, selected;
191
+ $('#blank-slate').fadeOut(200, function() {
192
+ return $(this).remove();
193
+ });
194
+ $('#roster').hide();
195
+ selected = $(event.currentTarget);
196
+ jid = selected.attr('data-jid');
197
+ contact = this.session.roster[jid];
198
+ if (this.currentContact === jid) {
199
+ return;
200
+ }
201
+ this.currentContact = jid;
202
+ $('#message-label').text($('.text', selected).text());
203
+ $('#messages').empty();
204
+ $('#message').focus();
205
+ this.layout.resize();
206
+ return this.restoreChat(jid);
207
+ };
208
+ SystemsPage.prototype.restoreChat = function(jid) {
209
+ var chat, messages, msg, _i, _len;
210
+ chat = this.chats[jid];
211
+ messages = [];
212
+ if (chat) {
213
+ messages = chat.messages;
214
+ chat.unread = 0;
215
+ this.eachContact(jid, function(node) {
216
+ return $('.unread', node).text('').hide();
217
+ });
218
+ }
219
+ for (_i = 0, _len = messages.length; _i < _len; _i++) {
220
+ msg = messages[_i];
221
+ this.appendMessage(msg);
222
+ }
223
+ return this.scroll();
224
+ };
225
+ SystemsPage.prototype.scroll = function(opts) {
226
+ var msgs;
227
+ opts || (opts = {});
228
+ msgs = $('#messages');
229
+ if (opts.animate) {
230
+ return msgs.animate({
231
+ scrollTop: msgs.prop('scrollHeight')
232
+ }, 400);
233
+ } else {
234
+ return msgs.scrollTop(msgs.prop('scrollHeight'));
235
+ }
236
+ };
237
+ SystemsPage.prototype.atBottom = function() {
238
+ var bottom, msgs;
239
+ msgs = $('#messages');
240
+ bottom = msgs.prop('scrollHeight') - msgs.outerHeight();
241
+ return msgs.scrollTop() >= bottom;
242
+ };
243
+ SystemsPage.prototype.send = function() {
244
+ var chat, input, jid, text;
245
+ if (!this.currentContact) {
246
+ return false;
247
+ }
248
+ input = $('#message');
249
+ text = input.val().trim();
250
+ if (text) {
251
+ chat = this.chats[this.currentContact];
252
+ jid = chat ? chat.jid : this.currentContact;
253
+ this.message({
254
+ from: this.session.jid(),
255
+ text: text,
256
+ to: jid,
257
+ received: new Date()
258
+ });
259
+ this.session.sendMessage(jid, text);
260
+ this.commands.push(text);
261
+ }
262
+ input.val('');
263
+ return false;
264
+ };
265
+ SystemsPage.prototype.drawBlankSlate = function() {
266
+ $("<form id=\"blank-slate\" class=\"float\">\n <p>\n Services, and individual systems, can be controlled by sending\n them shell commands through this terminal. Select a system to chat with\n to get started.\n </p>\n <input type=\"submit\" value=\"Select System\"/>\n</form>").appendTo('#alpha');
267
+ return $('#blank-slate').submit(__bind(function() {
268
+ $('#roster').show();
269
+ this.layout.resize();
270
+ return false;
271
+ }, this));
272
+ };
273
+ SystemsPage.prototype.draw = function() {
274
+ var contact, name;
275
+ if (!this.session.connected()) {
276
+ window.location.hash = '';
277
+ return;
278
+ }
279
+ $('body').attr('id', 'systems-page');
280
+ $('#container').hide().empty();
281
+ $("<div id=\"alpha\" class=\"primary column x-fill y-fill\">\n <ul id=\"messages\" class=\"scroll y-fill\"></ul>\n <form id=\"message-form\">\n <label id=\"message-label\"></label>\n <input id=\"message\" name=\"message\" type=\"text\" maxlength=\"1024\" placeholder=\"Type a command and press enter to send\"/>\n </form>\n <div id=\"roster\" class=\"float\" style=\"display:none;\">\n <ul id=\"roster-items\"></ul>\n <div id=\"roster-form\"></div>\n </div>\n</div>").appendTo('#container');
282
+ $('#message-form').submit(__bind(function() {
283
+ return this.send();
284
+ }, this));
285
+ $('#messages').click(function() {
286
+ return $('#roster').hide();
287
+ });
288
+ $('#message').focus(function() {
289
+ return $('#roster').hide();
290
+ });
291
+ this.roster();
292
+ $('#message-label').click(__bind(function() {
293
+ return $('#roster').toggle();
294
+ }, this));
295
+ $('#message').keyup(__bind(function(e) {
296
+ switch (e.keyCode) {
297
+ case 38:
298
+ return $('#message').val(this.commands.prev());
299
+ case 40:
300
+ return $('#message').val(this.commands.next());
301
+ }
302
+ }, this));
303
+ if (this.currentContact) {
304
+ if (this.currentContact) {
305
+ this.restoreChat(this.currentContact);
306
+ }
307
+ contact = this.session.roster[this.currentContact];
308
+ name = contact.name || contact.jid.split('@')[0];
309
+ $('#message-label').text(name);
310
+ $('#message').focus();
311
+ } else {
312
+ this.drawBlankSlate();
313
+ }
314
+ $('#container').show();
315
+ this.layout = this.resize();
316
+ this.scroll();
317
+ new Filter({
318
+ list: '#roster-items',
319
+ form: '#roster-form',
320
+ attrs: ['data-jid', 'data-name']
321
+ });
322
+ return $('form', '#roster-form').show();
323
+ };
324
+ SystemsPage.prototype.resize = function() {
325
+ var container, form, items, label, msg, rform, roster;
326
+ container = $('#container');
327
+ roster = $('#roster');
328
+ items = $('#roster-items');
329
+ rform = $('#roster-form');
330
+ msg = $('#message');
331
+ form = $('#message-form');
332
+ label = $('#message-label');
333
+ return new Layout(function() {
334
+ var height;
335
+ msg.width(form.width() - label.width() - 32);
336
+ height = container.height() - form.height() - 10;
337
+ roster.css('max-height', height);
338
+ return items.css('max-height', height - rform.outerHeight() - 10);
339
+ });
340
+ };
341
+ return SystemsPage;
342
+ })();