git ssb

2+

mixmix / ticktack



Tree: b361e2bf3aa5a852f1427695f6377cf100494224

Files: b361e2bf3aa5a852f1427695f6377cf100494224 / app / page / home.js

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

Built with git-ssb-web