git ssb

16+

cel / patchfoo



Commit a3dca9e424477c2745c59f482342a1580ed807f0

Merge branch 'votes'

cel committed on 6/7/2017, 9:25:30 AM
Parent: e9b1ee71a12fcd6c15a2f0b06671bc819da98303
Parent: 0e9903642e2e2c9cfb6f89f80a0256fa6f53ef5c

Files changed

lib/app.jschanged
lib/render.jschanged
lib/serve.jschanged
lib/app.jsView
@@ -388,8 +388,68 @@
388388 App.prototype.createContactStreams = function (id) {
389389 return new Contacts(this.sbot).createContactStreams(id)
390390 }
391391
392 +function compareVoted(a, b) {
393 + return b.value - a.value
394 +}
395 +
396 +App.prototype.getVoted = function (_opts, cb) {
397 + if (isNaN(_opts.limit)) return pull.error(new Error('missing limit'))
398 + var self = this
399 + var opts = {
400 + type: 'vote',
401 + limit: _opts.limit * 100,
402 + reverse: !!_opts.reverse,
403 + gt: _opts.gt || undefined,
404 + lt: _opts.lt || undefined,
405 + }
406 +
407 + var votedObj = {}
408 + var votedArray = []
409 + var numItems = 0
410 + var firstTimestamp, lastTimestamp
411 + pull(
412 + self.sbot.messagesByType(opts),
413 + self.unboxMessages(),
414 + pull.take(function () {
415 + return numItems < _opts.limit
416 + }),
417 + pull.drain(function (msg) {
418 + if (!firstTimestamp) firstTimestamp = msg.timestamp
419 + lastTimestamp = msg.timestamp
420 + var vote = msg.value.content.vote
421 + if (!vote) return
422 + var target = u.linkDest(vote)
423 + var votes = votedObj[target]
424 + if (!votes) {
425 + numItems++
426 + votes = {id: target, value: 0, feedsObj: {}, feeds: []}
427 + votedObj[target] = votes
428 + votedArray.push(votes)
429 + }
430 + if (msg.value.author in votes.feedsObj) {
431 + if (!opts.reverse) return // leave latest vote value as-is
432 + // remove old vote value
433 + votes.value -= votes.feedsObj[msg.value.author]
434 + } else {
435 + votes.feeds.push(msg.value.author)
436 + }
437 + var value = vote.value > 0 ? 1 : vote.value < 0 ? -1 : 0
438 + votes.feedsObj[msg.value.author] = value
439 + votes.value += value
440 + }, function (err) {
441 + if (err) return cb(err)
442 + var items = votedArray
443 + if (opts.reverse) items.reverse()
444 + items.sort(compareVoted)
445 + cb(null, {items: items,
446 + firstTimestamp: firstTimestamp,
447 + lastTimestamp: lastTimestamp})
448 + })
449 + )
450 +}
451 +
392452 App.prototype.createAboutStreams = function (id) {
393453 return this.about.createAboutStreams(id)
394454 }
395455
lib/render.jsView
@@ -312,4 +312,37 @@
312312 return isMarkdown
313313 ? h('div', {innerHTML: this.markdown('\n' + body)})
314314 : h('pre', this.linkify('\n' + body))
315315 }
316 +
317 +Render.prototype.getName = function (id, cb) {
318 + // TODO: consolidate the get name/link functions
319 + var self = this
320 + switch (id && id[0]) {
321 + case '%':
322 + return self.app.getMsgDecrypted(id, function (err, msg) {
323 + if (err && err.name == 'NotFoundError')
324 + return cb(null, String(id).substring(0, 8) + '…(missing)')
325 + if (err) return fallback()
326 + new RenderMsg(self, self.app, msg, {wrap: false}).title(cb)
327 + })
328 + case '@': // fallthrough
329 + case '&':
330 + return self.app.getAbout(id, function (err, about) {
331 + if (err || !about || !about.name) return fallback()
332 + cb(null, about.name)
333 + })
334 + default:
335 + return cb(null, String(id))
336 + }
337 + function fallback() {
338 + cb(null, String(id).substr(0, 8) + '…')
339 + }
340 +}
341 +
342 +Render.prototype.getNameLink = function (id, cb) {
343 + var self = this
344 + self.getName(id, function (err, name) {
345 + if (err) return cb(err)
346 + cb(null, h('a', {href: self.toUrl(id)}, name))
347 + })
348 +}
lib/serve.jsView
@@ -283,8 +283,9 @@
283283 case '/friends': return this.friends(m[2])
284284 case '/live': return this.live(m[2])
285285 case '/compose': return this.compose(m[2])
286286 case '/emojis': return this.emojis(m[2])
287 + case '/votes': return this.votes(m[2])
287288 }
288289 m = /^(\/?[^\/]*)(\/.*)?$/.exec(url)
289290 switch (m[1]) {
290291 case '/channel': return this.channel(m[2])
@@ -525,8 +526,92 @@
525526 )
526527 })
527528 }
528529
530 +Serve.prototype.votes = function (path) {
531 + if (path) return pull(
532 + pull.once(u.renderError(new Error('Not implemented')).outerHTML),
533 + this.wrapPage('#' + channel),
534 + this.respondSink(404, {'Content-Type': ctype('html')})
535 + )
536 +
537 + var self = this
538 + var q = self.query
539 + var opts = {
540 + reverse: !q.forwards,
541 + limit: Number(q.limit) || 50,
542 + }
543 + var gt = Number(q.gt)
544 + if (gt) opts.gt = gt
545 + var lt = Number(q.lt)
546 + if (lt) opts.lt = lt
547 +
548 + self.app.getVoted(opts, function (err, voted) {
549 + if (err) return pull(
550 + pull.once(u.renderError(err).outerHTML),
551 + self.wrapPage('#' + channel),
552 + self.respondSink(500, {'Content-Type': ctype('html')})
553 + )
554 +
555 + pull(
556 + ph('table', [
557 + ph('thead', [
558 + ph('tr', [
559 + ph('td', {colspan: 2}, self.syncPager({
560 + first: voted.firstTimestamp,
561 + last: voted.lastTimestamp,
562 + }))
563 + ])
564 + ]),
565 + ph('tbody', pull(
566 + pull.values(voted.items),
567 + paramap(function (item, cb) {
568 + cb(null, ph('tr', [
569 + ph('td', [String(item.value)]),
570 + ph('td', [
571 + self.phIdLink(item.id),
572 + pull.once(' dug by '),
573 + self.renderIdsList()(pull.values(item.feeds))
574 + ])
575 + ]))
576 + }, 8)
577 + )),
578 + ph('tfoot', {}, []),
579 + ]),
580 + self.wrapPage('votes'),
581 + self.respondSink(200, {
582 + 'Content-Type': ctype('html')
583 + })
584 + )
585 + })
586 +}
587 +
588 +Serve.prototype.syncPager = function (opts) {
589 + var q = this.query
590 + var reverse = !q.forwards
591 + var min = (reverse ? opts.last : opts.first) || Number(q.gt)
592 + var max = (reverse ? opts.first : opts.last) || Number(q.lt)
593 + var minDate = new Date(min)
594 + var maxDate = new Date(max)
595 + var qOlder = mergeOpts(q, {lt: min, gt: undefined, forwards: undefined})
596 + var qNewer = mergeOpts(q, {gt: max, lt: undefined, forwards: 1})
597 + var atNewest = reverse ? !q.lt : !max
598 + var atOldest = reverse ? !min : !q.gt
599 + if (atNewest && !reverse) qOlder.lt++
600 + if (atOldest && reverse) qNewer.gt--
601 + return h('div',
602 + atOldest ? 'oldest' : [
603 + h('a', {href: '?' + qs.stringify(qOlder)}, '<<'), ' ',
604 + h('span', {title: minDate.toString()}, htime(minDate)), ' ',
605 + ],
606 + ' - ',
607 + atNewest ? 'now' : [
608 + h('span', {title: maxDate.toString()}, htime(maxDate)), ' ',
609 + h('a', {href: '?' + qs.stringify(qNewer)}, '>>')
610 + ]
611 + ).outerHTML
612 +}
613 +
529614 Serve.prototype.peers = function (ext) {
530615 var self = this
531616 if (self.data.action === 'connect') {
532617 return self.app.sbot.gossip.connect(self.data.address, function (err) {
@@ -619,16 +704,8 @@
619704 })
620705 )
621706 }
622707
623-Serve.prototype.phIdLink = function (id) {
624- return pull(
625- pull.once(id),
626- pull.asyncMap(this.renderIdLink.bind(this)),
627- pull.map(u.toHTML)
628- )
629-}
630-
631708 Serve.prototype.contacts = function (path) {
632709 var self = this
633710 var id = String(path).substr(1)
634711 var contacts = self.app.createContactStreams(id)
@@ -1158,8 +1235,9 @@
11581235 h('a', {href: render.toUrl('/friends')}, 'friends'), ' ',
11591236 h('a', {href: render.toUrl('/advsearch')}, 'search'), ' ',
11601237 h('a', {href: render.toUrl('/live')}, 'live'), ' ',
11611238 h('a', {href: render.toUrl('/compose')}, 'compose'), ' ',
1239 + h('a', {href: render.toUrl('/votes')}, 'votes'), ' ',
11621240 h('a', {href: render.toUrl('/emojis')}, 'emojis'), ' ',
11631241 render.idLink(self.app.sbot.id, done()), ' ',
11641242 h('input.search-input', {name: 'q', value: searchQ,
11651243 placeholder: 'search'})
@@ -1178,27 +1256,20 @@
11781256 })
11791257 )
11801258 }
11811259
1182-Serve.prototype.renderIdLink = function (id, cb) {
1183- var render = this.app.render
1184- var el = render.idLink(id, function (err) {
1185- if (err || !el) {
1186- el = h('a', {href: render.toUrl(id)}, id)
1187- }
1188- cb(null, el)
1189- })
1260 +Serve.prototype.phIdLink = function (id) {
1261 + return pull(
1262 + pull.once(id),
1263 + this.renderIdsList()
1264 + )
11901265 }
11911266
11921267 Serve.prototype.friends = function (path) {
11931268 var self = this
11941269 pull(
11951270 self.app.sbot.friends.createFriendStream({hops: 1}),
1196- self.renderFriends(),
1197- pull.map(function (el) {
1198- return [el, ' ']
1199- }),
1200- pull.map(u.toHTML),
1271 + self.renderIdsList(),
12011272 u.hyperwrap(function (items, cb) {
12021273 cb(null, [
12031274 h('section',
12041275 h('h3', 'Friends')
@@ -1212,16 +1283,19 @@
12121283 })
12131284 )
12141285 }
12151286
1216-Serve.prototype.renderFriends = function () {
1287 +Serve.prototype.renderIdsList = function () {
12171288 var self = this
1218- return paramap(function (id, cb) {
1219- self.renderIdLink(id, function (err, el) {
1220- if (err) el = u.renderError(err, ext)
1221- cb(null, el)
1222- })
1223- }, 8)
1289 + return pull(
1290 + paramap(function (id, cb) {
1291 + self.app.render.getNameLink(id, cb)
1292 + }, 8),
1293 + pull.map(function (el) {
1294 + return [el, ' ']
1295 + }),
1296 + pull.map(u.toHTML)
1297 + )
12241298 }
12251299
12261300 var relationships = [
12271301 '',

Built with git-ssb-web