git ssb

2+

mixmix / ticktack



Tree: ec8cfe66cd3dbfa8ddc119bae4546fb25f8c8fd5

Files: ec8cfe66cd3dbfa8ddc119bae4546fb25f8c8fd5 / app / page / home.js

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

Built with git-ssb-web