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