git ssb

2+

mixmix / ticktack



Tree: 2cbf6075c6387cd0e72c91a39e1bbcbc91d0f4fa

Files: 2cbf6075c6387cd0e72c91a39e1bbcbc91d0f4fa / app / page / home.js

3924 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 var container = h('div.container', [])
35
36 // function filterForThread (thread) {
37 // if(thread.value.private)
38 // return {private: toRecpGroup(thread)}
39 // else if(thread.value.content.channel)
40 // return {channel: thread.value.content.channel}
41 // }
42
43 // function filter (rule, thread) {
44 // if(!thread.value) return false
45 // if(!rule) return true
46 // if(rule.channel) {
47 // return rule.channel == thread.value.content.channel
48 // }
49 // else if(rule.group)
50 // return rule.group == thread.value.content.group
51 // else if(rule.private)
52 // return rule.private == toRecpGroup(thread)
53 // else return true
54 // }
55
56 var morePlease = false
57 var threadsObs = api.state.obs.threads()
58
59 // DUCT TAPE: debounce the observable so it doesn't
60 // update the dom more than 1/second
61 threadsObs(function () {
62 if(morePlease) threadsObs.more()
63 })
64 threadsObsDebounced = Debounce(threadsObs, 1000)
65 threadsObsDebounced(function () {
66 morePlease = false
67 })
68 threadsObsDebounced.more = function () {
69 morePlease = true
70 requestIdleCallback(threadsObs.more)
71 }
72
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
111 .map(function (thread) {
112
113 const channel = thread.value.content.channel
114 const onClick = channel
115 ? (ev) => api.history.sync.push({ channel })
116 : null // threadCard will install default onClick
117
118 return api.app.html.threadCard(thread, { onClick })
119 })
120 )
121 ]),
122 ])
123 )
124
125 return container
126 }
127 )
128
129 return h('Page -home', [
130 h('h1', 'Home'),
131 api.app.html.nav(),
132 threadsHtmlObs,
133 h('button', {'ev-click': threadsHtmlObs.more}, [strings.showMore])
134 ])
135 })
136}
137
138

Built with git-ssb-web