Files: 753e1dbdb9d539b25c1a4fcd3ecf10b862d28b9c / app / page / home.js
3201 bytesRaw
1 | const nest = require('depnest') |
2 | const { h } = require('mutant') |
3 | const {threadReduce} = require('ssb-reduce-stream') |
4 | const pull = require('pull-stream') |
5 | const when = require('mutant/when') |
6 | const isObject = require('lodash/isObject') |
7 | const isString = require('lodash/isString') |
8 | const last = require('lodash/last') |
9 | const get = require('lodash/get') |
10 | |
11 | exports.gives = nest('app.page.home') |
12 | |
13 | exports.needs = nest({ |
14 | 'about.html.image': 'first', |
15 | 'app.html.nav': 'first', |
16 | 'feed.pull.public': 'first', |
17 | 'history.sync.push': 'first', |
18 | 'message.sync.unbox': 'first', |
19 | }) |
20 | |
21 | function firstLine (text) { |
22 | if(text.length < 80 && !~text.indexOf('\n')) return text |
23 | |
24 | return text.split('\n')[0].substring(0, 80) |
25 | } |
26 | |
27 | exports.create = (api) => { |
28 | return nest('app.page.home', home) |
29 | |
30 | function home (location) { |
31 | // location here can expected to be: { page: 'home' } |
32 | |
33 | var container = h('div.container', []) |
34 | |
35 | function subject (msg) { |
36 | const { subject, text } = msg.value.content |
37 | return firstLine(subject|| text) |
38 | } |
39 | |
40 | function link(location) { |
41 | return {'ev-click': () => api.history.sync.push(location)} |
42 | } |
43 | |
44 | function item (name, thread) { |
45 | if(!thread.value) return |
46 | const lastReply = thread.replies && last(thread.replies) |
47 | |
48 | return h('div.threadLink', link(thread), [ |
49 | name, |
50 | h('div.subject', [subject(thread)]), |
51 | lastReply ? h('div.reply', [subject(lastReply)]) : null |
52 | ]) |
53 | } |
54 | |
55 | function threadGroup (threads, obj, toName) { |
56 | // threads = a state object for all the types of threads |
57 | // obj = a map of keys to root ids, where key ∈ (channel | group | concatenated list of pubkeys) |
58 | // toName = fn that derives a name from a particular thread |
59 | |
60 | var div = h('div.group') |
61 | for(var k in obj) { |
62 | var id = obj[k] |
63 | var thread = get(threads, ['roots', id]) |
64 | if(thread && thread.value) { |
65 | //throw new Error('missing thread:'+id+' for channel:'+k) |
66 | var el = item(toName(k, thread), thread) |
67 | if(el) div.appendChild(el) |
68 | } |
69 | } |
70 | return div |
71 | } |
72 | |
73 | pull( |
74 | api.feed.pull.public({reverse: true, limit: 1000}), |
75 | pull.through(console.log), |
76 | pull.collect(function (err, messages) { |
77 | |
78 | var threads = messages |
79 | .map(function (data) { |
80 | if(isObject(data.value.content)) return data |
81 | return api.message.sync.unbox(data) |
82 | }) |
83 | .filter(Boolean) |
84 | .reduce(threadReduce, null) |
85 | |
86 | container.appendChild(threadGroup( |
87 | threads, |
88 | threads.private, |
89 | function (_, msg) { |
90 | // NB: msg passed in is actually a 'thread', but only care about root msg |
91 | |
92 | return h('div.recps', [ |
93 | msg.value.content.recps.map(function (link) { |
94 | return api.about.html.image(isString(link) ? link : link.link) |
95 | }) |
96 | ]) |
97 | } |
98 | )) |
99 | |
100 | container.appendChild(threadGroup( |
101 | threads, |
102 | threads.channels, |
103 | ch => h('h2.title', '#'+ch) |
104 | )) |
105 | }) |
106 | ) |
107 | |
108 | return h('Page -home', [ |
109 | h('h1', 'Home'), |
110 | api.app.html.nav(), |
111 | container |
112 | ]) |
113 | } |
114 | } |
115 | |
116 | |
117 | |
118 |
Built with git-ssb-web