vines 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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