git ssb

2+

mixmix / ticktack



Tree: 08bdd1675bfb45b44e82c17c1269c2aafd4ae82b

Files: 08bdd1675bfb45b44e82c17c1269c2aafd4ae82b / app / page / channel.js

3960 bytesRaw
1const nest = require('depnest')
2const { h, computed } = require('mutant')
3const {threadReduce} = require('ssb-reduce-stream')
4const pull = require('pull-stream')
5const isObject = require('lodash/isObject')
6const isString = require('lodash/isString')
7const last = require('lodash/last')
8const get = require('lodash/get')
9const More = require('hypermore')
10const morphdom = require('morphdom')
11const Debounce = require('obv-debounce')
12const PullObv = require('pull-obv')
13
14exports.gives = nest('app.page.channel')
15
16exports.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
26function 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
36exports.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