vines 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -29,7 +29,7 @@ Session = (function() {
29
29
  callback(true);
30
30
  return this.findRoster(__bind(function() {
31
31
  this.notify('roster');
32
- this.xmpp.send($pres().tree());
32
+ this.xmpp.send($('<presence/>').get(0));
33
33
  return this.findCards();
34
34
  }, this));
35
35
  }
@@ -59,6 +59,9 @@ Session = (function() {
59
59
  Session.prototype.bareJid = function() {
60
60
  return this.xmpp.jid.split('/')[0];
61
61
  };
62
+ Session.prototype.uniqueId = function() {
63
+ return this.xmpp.getUniqueId();
64
+ };
62
65
  Session.prototype.avatar = function(jid) {
63
66
  var card;
64
67
  card = this.loadCard(jid);
@@ -106,11 +109,12 @@ Session = (function() {
106
109
  return this.findCard(jids.shift(), success);
107
110
  };
108
111
  Session.prototype.findCard = function(jid, callback) {
109
- var handler, iq;
112
+ var node;
110
113
  if (!jid) {
111
114
  return;
112
115
  }
113
- handler = function(result) {
116
+ node = this.xml("<iq id=\"" + (this.uniqueId()) + "\" to=\"" + jid + "\" type=\"get\">\n <vCard xmlns=\"vcard-temp\"/>\n</iq>");
117
+ return this.sendIQ(node, function(result) {
114
118
  var bin, card, photo, type, vcard;
115
119
  card = $('vCard', result);
116
120
  photo = $('PHOTO', card);
@@ -126,15 +130,7 @@ Session = (function() {
126
130
  retrieved: new Date()
127
131
  };
128
132
  return callback(card.size() > 0 ? vcard : null);
129
- };
130
- iq = $iq({
131
- type: 'get',
132
- to: jid,
133
- id: this.xmpp.getUniqueId()
134
- }).c('vCard', {
135
- xmlns: 'vcard-temp'
136
- }).up();
137
- return this.xmpp.sendIQ(iq, handler, handler, 5000);
133
+ });
138
134
  };
139
135
  Session.prototype.parseRoster = function(node) {
140
136
  return $('item', node).map(function() {
@@ -142,8 +138,9 @@ Session = (function() {
142
138
  }).get();
143
139
  };
144
140
  Session.prototype.findRoster = function(callback) {
145
- var handler, iq;
146
- handler = __bind(function(result) {
141
+ var node;
142
+ node = $("<iq id='" + (this.uniqueId()) + "' type=\"get\">\n <query xmlns=\"jabber:iq:roster\"/>\n</iq>");
143
+ return this.sendIQ(node.get(0), __bind(function(result) {
147
144
  var contact, contacts, _i, _len;
148
145
  contacts = this.parseRoster(result);
149
146
  for (_i = 0, _len = contacts.length; _i < _len; _i++) {
@@ -151,96 +148,62 @@ Session = (function() {
151
148
  this.roster[contact.jid] = contact;
152
149
  }
153
150
  return callback();
154
- }, this);
155
- iq = $iq({
156
- type: 'get',
157
- id: this.xmpp.getUniqueId()
158
- }).c('query', {
159
- xmlns: 'jabber:iq:roster'
160
- }).up();
161
- return this.xmpp.sendIQ(iq, handler, handler, 5000);
151
+ }, this));
162
152
  };
163
153
  Session.prototype.sendMessage = function(jid, message) {
164
- var stanza;
165
- stanza = $msg({
166
- to: jid,
167
- from: this.xmpp.jid,
168
- type: 'chat'
169
- }).c('body').t(message).up();
170
- return this.xmpp.send(stanza.tree());
154
+ var node;
155
+ node = this.xml("<message id=\"" + (this.uniqueId()) + "\" to=\"" + jid + "\" type=\"chat\">\n <body></body>\n</message>");
156
+ $('body', node).text(message);
157
+ return this.xmpp.send(node);
171
158
  };
172
159
  Session.prototype.sendPresence = function(away, status) {
173
- var stanza;
174
- stanza = $pres();
160
+ var node;
161
+ node = $('<presence/>');
175
162
  if (away) {
176
- stanza.c('show').t('xa').up();
163
+ node.append($('<show>xa</show>'));
177
164
  if (status !== 'Away') {
178
- stanza.c('status').t(status);
165
+ node.append($('<status/>').text(status));
179
166
  }
180
167
  } else {
181
168
  if (status !== 'Available') {
182
- stanza.c('status').t(status);
169
+ node.append($('<status/>').text(status));
183
170
  }
184
171
  }
185
- return this.xmpp.send(stanza.tree());
172
+ return this.xmpp.send(node.get(0));
173
+ };
174
+ Session.prototype.sendIQ = function(node, callback) {
175
+ return this.xmpp.sendIQ(node, callback, callback, 5000);
186
176
  };
187
177
  Session.prototype.updateContact = function(contact, add) {
188
- var group, iq, _i, _len, _ref;
189
- iq = $iq({
190
- type: 'set',
191
- id: this.xmpp.getUniqueId()
192
- }).c('query', {
193
- xmlns: 'jabber:iq:roster'
194
- }).c('item', {
195
- jid: contact.jid,
196
- name: contact.name
197
- });
178
+ var group, node, _i, _len, _ref;
179
+ node = $("<iq id=\"" + (this.uniqueId()) + "\" type=\"set\">\n <query xmlns=\"jabber:iq:roster\">\n <item name=\"\" jid=\"" + contact.jid + "\"/>\n </query>\n</iq>");
180
+ $('item', node).attr('name', contact.name);
198
181
  _ref = contact.groups;
199
182
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
200
183
  group = _ref[_i];
201
- iq.c('group', group).up();
184
+ $('item', node).append($('<group></group>').text(group));
202
185
  }
203
- this.xmpp.send(iq.up().tree());
186
+ this.xmpp.send(node.get(0));
204
187
  if (add) {
205
- return this.xmpp.send($pres({
206
- type: 'subscribe',
207
- to: contact.jid
208
- }).tree());
188
+ return this.sendSubscribe(contact.jid);
209
189
  }
210
190
  };
211
191
  Session.prototype.removeContact = function(jid) {
212
- var iq;
213
- iq = $iq({
214
- type: 'set',
215
- id: this.xmpp.getUniqueId()
216
- }).c('query', {
217
- xmlns: 'jabber:iq:roster'
218
- }).c('item', {
219
- jid: jid,
220
- subscription: 'remove'
221
- }).up().up();
222
- return this.xmpp.send(iq.tree());
192
+ var node;
193
+ node = $("<iq id=\"" + (this.uniqueId()) + "\" type=\"set\">\n <query xmlns=\"jabber:iq:roster\">\n <item jid=\"" + jid + "\" subscription=\"remove\"/>\n </query>\n</iq>");
194
+ return this.xmpp.send(node.get(0));
223
195
  };
224
196
  Session.prototype.sendSubscribe = function(jid) {
225
- return this.xmpp.send($pres({
226
- type: 'subscribe',
227
- to: jid,
228
- id: this.xmpp.getUniqueId()
229
- }).tree());
197
+ return this.xmpp.send(this.presence(jid, 'subscribe'));
230
198
  };
231
199
  Session.prototype.sendSubscribed = function(jid) {
232
- return this.xmpp.send($pres({
233
- type: 'subscribed',
234
- to: jid,
235
- id: this.xmpp.getUniqueId()
236
- }).tree());
200
+ return this.xmpp.send(this.presence(jid, 'subscribed'));
237
201
  };
238
202
  Session.prototype.sendUnsubscribed = function(jid) {
239
- return this.xmpp.send($pres({
240
- type: 'unsubscribed',
241
- to: jid,
242
- id: this.xmpp.getUniqueId()
243
- }).tree());
203
+ return this.xmpp.send(this.presence(jid, 'unsubscribed'));
204
+ };
205
+ Session.prototype.presence = function(to, type) {
206
+ return $("<presence\n id=\"" + (this.uniqueId()) + "\"\n to=\"" + to + "\"\n type=\"" + type + "\"/>").get(0);
244
207
  };
245
208
  Session.prototype.handleIq = function(node) {
246
209
  var contact, contacts, ns, old, type, _i, _len;
@@ -318,5 +281,8 @@ Session = (function() {
318
281
  }
319
282
  return _results;
320
283
  };
284
+ Session.prototype.xml = function(xml) {
285
+ return $.parseXML(xml).documentElement;
286
+ };
321
287
  return Session;
322
288
  })();
@@ -0,0 +1,134 @@
1
+ var Transfer;
2
+ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
3
+ Transfer = (function() {
4
+ var Chunks;
5
+ function Transfer(options) {
6
+ this.session = options.session;
7
+ this.file = options.file;
8
+ this.to = options.to;
9
+ this.progress = options.progress;
10
+ this.complete = options.complete;
11
+ this.chunks = new Chunks(this.file);
12
+ this.opened = false;
13
+ this.closed = false;
14
+ this.sid = this.session.uniqueId();
15
+ this.seq = 0;
16
+ this.sent = 0;
17
+ }
18
+ Transfer.prototype.start = function() {
19
+ var callback, node;
20
+ node = $("<iq id=\"" + (this.session.uniqueId()) + "\" to=\"" + this.to + "\" type=\"set\">\n <si xmlns=\"http://jabber.org/protocol/si\" id=\"" + (this.session.uniqueId()) + "\" profile=\"http://jabber.org/protocol/si/profile/file-transfer\">\n <file xmlns=\"http://jabber.org/protocol/si/profile/file-transfer\" name=\"\" size=\"" + this.file.size + "\"/>\n <feature xmlns=\"http://jabber.org/protocol/feature-neg\">\n <x xmlns=\"jabber:x:data\" type=\"form\">\n <field var=\"stream-method\" type=\"list-single\">\n <option><value>http://jabber.org/protocol/ibb</value></option>\n </field>\n </x>\n </feature>\n </si>\n</iq>");
21
+ $('file', node).attr('name', this.file.name);
22
+ callback = __bind(function(result) {
23
+ var m, methods, ok;
24
+ methods = $('si feature x field[var="stream-method"] value', result);
25
+ ok = ((function() {
26
+ var _i, _len, _results;
27
+ _results = [];
28
+ for (_i = 0, _len = methods.length; _i < _len; _i++) {
29
+ m = methods[_i];
30
+ if ($(m).text() === 'http://jabber.org/protocol/ibb') {
31
+ _results.push(true);
32
+ }
33
+ }
34
+ return _results;
35
+ })()).length > 0;
36
+ if (ok) {
37
+ return this.open();
38
+ }
39
+ }, this);
40
+ return this.session.sendIQ(node.get(0), callback);
41
+ };
42
+ Transfer.prototype.open = function() {
43
+ var callback, node;
44
+ node = $("<iq id=\"" + (this.session.uniqueId()) + "\" to=\"" + this.to + "\" type=\"set\">\n <open xmlns=\"http://jabber.org/protocol/ibb\" sid=\"" + this.sid + "\" block-size=\"4096\"/>\n</iq>");
45
+ callback = __bind(function(result) {
46
+ if (this.ok(result)) {
47
+ this.opened = true;
48
+ return this.chunks.start(__bind(function() {
49
+ return this.sendChunk();
50
+ }, this));
51
+ }
52
+ }, this);
53
+ return this.session.sendIQ(node.get(0), callback);
54
+ };
55
+ Transfer.prototype.sendChunk = function() {
56
+ var callback, chunk, node;
57
+ if (this.closed) {
58
+ return;
59
+ }
60
+ if (!(chunk = this.chunks.chunk())) {
61
+ this.close();
62
+ return;
63
+ }
64
+ node = $("<iq id=\"" + (this.session.uniqueId()) + "\" to=\"" + this.to + "\" type=\"set\">\n <data xmlns=\"http://jabber.org/protocol/ibb\" sid=\"" + this.sid + "\" seq=\"" + (this.seq++) + "\">" + chunk + "</data>\n</iq>");
65
+ if (this.seq > 65535) {
66
+ this.seq = 0;
67
+ }
68
+ callback = __bind(function(result) {
69
+ var pct;
70
+ if (!this.ok(result)) {
71
+ return;
72
+ }
73
+ pct = Math.ceil(++this.sent / this.chunks.total * 100);
74
+ this.progress(pct);
75
+ return this.sendChunk();
76
+ }, this);
77
+ return this.session.sendIQ(node.get(0), callback);
78
+ };
79
+ Transfer.prototype.close = function() {
80
+ var node;
81
+ if (this.closed) {
82
+ return;
83
+ }
84
+ this.closed = true;
85
+ node = $("<iq id=\"" + (this.session.uniqueId()) + "\" to=\"" + this.to + "\" type=\"set\">\n <close xmlns=\"http://jabber.org/protocol/ibb\" sid=\"" + this.sid + "\"/>\n</iq>");
86
+ this.session.sendIQ(node.get(0), function() {});
87
+ return this.complete();
88
+ };
89
+ Transfer.prototype.stop = function() {
90
+ if (this.opened) {
91
+ return this.close();
92
+ } else {
93
+ return this.complete();
94
+ }
95
+ };
96
+ Transfer.prototype.ok = function(result) {
97
+ return $(result).attr('type') === 'result';
98
+ };
99
+ Chunks = (function() {
100
+ function Chunks(file) {
101
+ this.file = file;
102
+ this.chunks = [];
103
+ this.total = 0;
104
+ }
105
+ Chunks.prototype.chunk = function() {
106
+ return this.chunks.shift();
107
+ };
108
+ Chunks.prototype.start = function(callback) {
109
+ var reader;
110
+ reader = new FileReader();
111
+ reader.onload = __bind(function(event) {
112
+ var chunk, data;
113
+ data = btoa(event.target.result);
114
+ this.chunks = (function() {
115
+ var _i, _len, _ref, _results;
116
+ _ref = data.split(/(.{1,4096})/);
117
+ _results = [];
118
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
119
+ chunk = _ref[_i];
120
+ if (chunk) {
121
+ _results.push(chunk);
122
+ }
123
+ }
124
+ return _results;
125
+ })();
126
+ this.total = this.chunks.length;
127
+ return callback();
128
+ }, this);
129
+ return reader.readAsBinaryString(this.file);
130
+ };
131
+ return Chunks;
132
+ })();
133
+ return Transfer;
134
+ })();
@@ -189,11 +189,11 @@ optgroup option {
189
189
  width: 100%;
190
190
  }
191
191
  #navbar #nav-links li a svg {
192
- height: 30px;
193
- width: 30px;
192
+ height: 32px;
193
+ width: 32px;
194
194
  position: absolute;
195
- left: 32px;
196
- top: 3px;
195
+ left: 33px;
196
+ top: 4px;
197
197
  }
198
198
  #navbar #nav-links li a span {
199
199
  position: relative;
@@ -220,4 +220,128 @@ optgroup option {
220
220
  bottom: 0;
221
221
  left: 0;
222
222
  right: 0;
223
- }
223
+ }
224
+ .filter-button {
225
+ cursor: pointer;
226
+ display: inline-block;
227
+ line-height: 1;
228
+ position: absolute;
229
+ right: 10px;
230
+ top: 6px;
231
+ }
232
+ .filter-button svg {
233
+ height: 16px;
234
+ width: 16px;
235
+ }
236
+ .filter-form {
237
+ border-bottom: 1px solid #ddd;
238
+ padding: 5px 10px;
239
+ }
240
+ .filter-text {
241
+ width: 100%;
242
+ }
243
+ .scroll {
244
+ overflow-y: auto;
245
+ }
246
+ .scroll::-webkit-scrollbar {
247
+ width: 6px;
248
+ }
249
+ .scroll::-webkit-scrollbar-thumb {
250
+ border-radius: 10px;
251
+ }
252
+ .scroll::-webkit-scrollbar-thumb:vertical {
253
+ background: rgba(0, 0, 0, .2);
254
+ }
255
+ ul.selectable li.selected {
256
+ background: #4693FF;
257
+ background: -moz-linear-gradient(#4693FF, #015de6);
258
+ background: -o-linear-gradient(#4693FF, #015de6);
259
+ background: -webkit-gradient(linear, left top, left bottom, from(#4693FF), to(#015de6));
260
+ border-bottom: 1px solid #fff;
261
+ color: #fff;
262
+ text-shadow: 0 -1px 1px #1b3a65;
263
+ }
264
+ .column {
265
+ height: 100%;
266
+ position: absolute;
267
+ }
268
+ .column h2 {
269
+ border-bottom: 1px solid #ddd;
270
+ font-size: 10pt;
271
+ padding-left: 10px;
272
+ position: relative;
273
+ text-shadow: 0 -1px 1px #fff;
274
+ }
275
+ .column .controls {
276
+ background: rgba(255, 255, 255, 0.05);
277
+ border-top: 1px solid #ddd;
278
+ height: 50px;
279
+ position: absolute;
280
+ bottom: 0;
281
+ width: 260px;
282
+ }
283
+ .column .controls > div {
284
+ cursor: pointer;
285
+ display: inline-block;
286
+ height: 27px;
287
+ margin: 0 10px;
288
+ position: relative;
289
+ top: 10px;
290
+ width: 27px;
291
+ }
292
+ .column .controls > div > svg {
293
+ height: 27px;
294
+ width: 27px;
295
+ }
296
+ .primary {
297
+ -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.5), 0 0 40px rgba(0, 0, 0, 0.1) inset;
298
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.5), 0 0 40px rgba(0, 0, 0, 0.1) inset;
299
+ width: 460px;
300
+ left: 260px;
301
+ z-index: 1;
302
+ }
303
+ .sidebar {
304
+ background: #f8f8f8;
305
+ -webkit-box-shadow: 0 0 40px rgba(0, 0, 0, 0.1) inset;
306
+ box-shadow: 0 0 40px rgba(0, 0, 0, 0.1) inset;
307
+ width: 260px;
308
+ }
309
+ form.overlay {
310
+ background: inherit;
311
+ border-bottom: 1px solid #ddd;
312
+ border-top: 1px solid #fff;
313
+ -webkit-box-shadow: 0px -3px 5px rgba(0, 0, 0, 0.1);
314
+ box-shadow: 0px -3px 5px rgba(0, 0, 0, 0.1);
315
+ padding-top: 10px;
316
+ position: absolute;
317
+ bottom: 50px;
318
+ left: 0;
319
+ width: 260px;
320
+ }
321
+ form.overlay h2,
322
+ form.inset h2 {
323
+ border: none !important;
324
+ line-height: 1;
325
+ margin-bottom: 10px;
326
+ }
327
+ form.overlay p,
328
+ form.inset p {
329
+ line-height: 1.5;
330
+ margin: 0 10px 10px 10px;
331
+ text-shadow: 0 1px 1px #fff;
332
+ }
333
+ form.inset p {
334
+ margin-top: -5px;
335
+ }
336
+ form.overlay .buttons,
337
+ form.inset .buttons {
338
+ padding-right: 10px;
339
+ text-align: right;
340
+ }
341
+ form.overlay input[type="text"],
342
+ form.overlay input[type="email"] {
343
+ margin-bottom: 10px;
344
+ width: 228px;
345
+ position: relative;
346
+ left: 10px;
347
+ }
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: vines
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.0
5
+ version: 0.2.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - David Graham
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2011-07-11 00:00:00 -06:00
14
+ date: 2011-07-22 00:00:00 -06:00
15
15
  default_executable:
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
@@ -261,17 +261,22 @@ files:
261
261
  - web/chat/javascripts/logout.js
262
262
  - web/chat/stylesheets/chat.css
263
263
  - web/favicon.png
264
+ - web/lib/coffeescripts/button.coffee
264
265
  - web/lib/coffeescripts/contact.coffee
266
+ - web/lib/coffeescripts/filter.coffee
265
267
  - web/lib/coffeescripts/layout.coffee
266
268
  - web/lib/coffeescripts/login.coffee
267
269
  - web/lib/coffeescripts/navbar.coffee
268
270
  - web/lib/coffeescripts/router.coffee
269
271
  - web/lib/coffeescripts/session.coffee
272
+ - web/lib/coffeescripts/transfer.coffee
270
273
  - web/lib/images/default-user.png
271
274
  - web/lib/images/logo-large.png
272
275
  - web/lib/images/logo-small.png
273
276
  - web/lib/javascripts/base.js
277
+ - web/lib/javascripts/button.js
274
278
  - web/lib/javascripts/contact.js
279
+ - web/lib/javascripts/filter.js
275
280
  - web/lib/javascripts/icons.js
276
281
  - web/lib/javascripts/jquery.cookie.js
277
282
  - web/lib/javascripts/jquery.js
@@ -282,6 +287,7 @@ files:
282
287
  - web/lib/javascripts/router.js
283
288
  - web/lib/javascripts/session.js
284
289
  - web/lib/javascripts/strophe.js
290
+ - web/lib/javascripts/transfer.js
285
291
  - web/lib/stylesheets/base.css
286
292
  - web/lib/stylesheets/login.css
287
293
  - test/config_test.rb