git ssb

2+

mixmix / ticktack



Tree: 791d817894b256f9a26d15c977f65c023036c676

Files: 791d817894b256f9a26d15c977f65c023036c676 / app / page / blogIndex.js

3397 bytesRaw
1const nest = require('depnest')
2const { h } = require('mutant')
3
4const isString = require('lodash/isString')
5const More = require('hypermore')
6const morphdom = require('morphdom')
7const Debounce = require('obv-debounce')
8
9exports.gives = nest('app.page.blogIndex')
10
11exports.needs = nest({
12 'history.sync.push': 'first',
13 'keys.sync.id': 'first',
14 'translations.sync.strings': 'first',
15 'state.obs.threads': 'first',
16 'app.html.threadCard': 'first',
17 'unread.sync.isUnread': 'first'
18})
19
20exports.create = (api) => {
21 var contentHtmlObs
22
23 return nest('app.page.blogIndex', function (location) {
24 // location here can expected to be: { page: 'blogIndex'}
25 //
26 var strings = api.translations.sync.strings()
27
28 return h('Page -blogIndex', {title: strings.home}, [
29 h('div.context', 'context (sidebar)'),
30 h('div.content', [
31 blogs(),
32 h('Button -showMore', { 'ev-click': contentHtmlObs.more }, strings.showMore)
33 ]),
34 ])
35 })
36
37 function blogs () {
38 // TODO - replace with actual blogs
39 var morePlease = false
40 var threadsObs = api.state.obs.threads()
41
42 // DUCT TAPE: debounce the observable so it doesn't
43 // update the dom more than 1/second
44 threadsObs(function () {
45 if(morePlease) threadsObs.more()
46 })
47 threadsObsDebounced = Debounce(threadsObs, 1000)
48 threadsObsDebounced(function () {
49 morePlease = false
50 })
51 threadsObsDebounced.more = function () {
52 morePlease = true
53 requestIdleCallback(threadsObs.more)
54 }
55
56 var updates = h('div.threads', [])
57 contentHtmlObs = More(
58 threadsObsDebounced,
59 function render (threads) {
60
61 function latestUpdate(thread) {
62 var m = thread.timestamp || 0
63 if(!thread.replies) return m
64
65 for(var i = 0; i < thread.replies.length; i++)
66 m = Math.max(thread.replies[i].timestamp||0, m)
67 return m
68 }
69
70 var o = {}
71 function roots (r) {
72 return Object.keys(r || {}).map(function (name) {
73 var id = r[name]
74 if(!o[id]) {
75 o[id] = true
76 return threads.roots[id]
77 }
78 }).filter(function (e) {
79 return e && e.value
80 })
81 }
82
83 var groupedThreads = roots(threads.private)
84 .concat(roots(threads.channels))
85 .concat(roots(threads.groups))
86 .filter(function (thread) {
87 return thread.value.content.recps || thread.value.content.channel
88 })
89 .map(function (thread) {
90 var unread = 0
91 if(api.unread.sync.isUnread(thread))
92 unread ++
93 ;(thread.replies || []).forEach(function (msg) {
94 if(api.unread.sync.isUnread(msg)) unread ++
95 })
96 thread.unread = unread
97 return thread
98 })
99 .sort((a, b) => latestUpdate(b) - latestUpdate(a))
100
101 morphdom(
102 updates,
103 h('div.threads',
104 groupedThreads.map(thread => {
105 const { recps, channel } = thread.value.content
106 var onClick
107 if (channel && !recps)
108 onClick = (ev) => api.history.sync.push({ channel })
109
110 return api.app.html.threadCard(thread, { onClick })
111 })
112 )
113 )
114
115 return updates
116 }
117 )
118
119 return contentHtmlObs
120 }
121}
122
123

Built with git-ssb-web