Files: 60479658b26b297158dd59938d021562a5b447ec / app / page / home.js
4166 bytesRaw
1 | const nest = require('depnest') |
2 | const { h, computed } = 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 | const More = require('hypermore') |
10 | const morphdom = require('morphdom') |
11 | const Debounce = require('obv-debounce') |
12 | |
13 | exports.gives = nest('app.page.home') |
14 | |
15 | exports.needs = nest({ |
16 | 'app.html.nav': 'first', |
17 | 'history.sync.push': 'first', |
18 | 'keys.sync.id': 'first', |
19 | 'translations.sync.strings': 'first', |
20 | 'state.obs.threads': 'first', |
21 | 'app.html.threadCard': 'first' |
22 | }) |
23 | |
24 | function toRecpGroup(msg) { |
25 | //cannocialize |
26 | return Array.isArray(msg.value.content.repcs) && |
27 | msg.value.content.recps.map(function (e) { |
28 | return (isString(e) ? e : e.link) |
29 | }).sort().map(function (id) { |
30 | return id.substring(0, 10) |
31 | }).join(',') |
32 | } |
33 | |
34 | exports.create = (api) => { |
35 | return nest('app.page.home', function (location) { |
36 | // location here can expected to be: { page: 'home' } |
37 | var strings = api.translations.sync.strings() |
38 | |
39 | var container = h('div.container', []) |
40 | |
41 | function filterForThread (thread) { |
42 | if(thread.value.private) |
43 | return {private: toRecpGroup(thread)} |
44 | else if(thread.value.content.channel) |
45 | return {channel: thread.value.content.channel} |
46 | } |
47 | |
48 | function filter (rule, thread) { |
49 | if(!thread.value) return false |
50 | if(!rule) return true |
51 | if(rule.channel) { |
52 | return rule.channel == thread.value.content.channel |
53 | } |
54 | else if(rule.group) |
55 | return rule.group == thread.value.content.group |
56 | else if(rule.private) |
57 | return rule.private == toRecpGroup(thread) |
58 | else return true |
59 | } |
60 | |
61 | var morePlease = false |
62 | var threadsObs = api.state.obs.threads() |
63 | |
64 | // DUCT TAPE: debounce the observable so it doesn't |
65 | // update the dom more than 1/second |
66 | threadsObs(function () { |
67 | if(morePlease) threadsObs.more() |
68 | }) |
69 | threadsObsDebounced = Debounce(threadsObs, 1000) |
70 | threadsObsDebounced(function () { |
71 | morePlease = false |
72 | }) |
73 | threadsObsDebounced.more = function () { |
74 | morePlease = true |
75 | requestIdleCallback(threadsObs.more) |
76 | } |
77 | |
78 | var threadsHtmlObs = More( |
79 | threadsObsDebounced, |
80 | function render (threads) { |
81 | |
82 | var groupedThreads = |
83 | roots(threads.private) |
84 | .concat(roots(threads.channels)) |
85 | .concat(roots(threads.groups)) |
86 | .sort(function (a, b) { |
87 | return latestUpdate(b) - latestUpdate(a) |
88 | }) |
89 | |
90 | function latestUpdate(thread) { |
91 | var m = thread.timestamp |
92 | if(!thread.replies) return m |
93 | |
94 | for(var i = 0; i < thread.replies.length; i++) |
95 | m = Math.max(thread.replies[i].timestamp, m) |
96 | return m |
97 | } |
98 | |
99 | function roots (r) { |
100 | return Object.keys(r || {}).map(function (k) { |
101 | return threads.roots[r[k]] |
102 | }).filter(function (e) { |
103 | return e && e.value |
104 | }) |
105 | } |
106 | |
107 | |
108 | morphdom(container, |
109 | // LEGACY: some of these containers could be removed |
110 | // but they are here to be compatible with the old MCSS. |
111 | h('div.container', [ |
112 | //private section |
113 | h('section.updates -directMessage', [ |
114 | h('div.threads', |
115 | groupedThreads |
116 | .map(function (thread) { |
117 | var el = api.app.html |
118 | .threadCard(thread, opts) |
119 | |
120 | if(thread.value.content.channel) { |
121 | el.onclick = function (ev) { |
122 | api.history.sync.push({channel: thread.value.content.channel}) |
123 | ev.preventDefault() |
124 | } |
125 | } |
126 | |
127 | return el |
128 | }) |
129 | ) |
130 | ]), |
131 | ]) |
132 | ) |
133 | |
134 | return container |
135 | } |
136 | ) |
137 | |
138 | return h('Page -home', [ |
139 | h('h1', 'Home'), |
140 | api.app.html.nav(), |
141 | threadsHtmlObs, |
142 | h('button', {'ev-click': threadsHtmlObs.more}, [strings.showMore]) |
143 | ]) |
144 | }) |
145 | } |
146 | |
147 |
Built with git-ssb-web