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