git ssb

2+

mixmix / ticktack



Tree: 165f298ed05493f7f1381ef269c0eca496e4679b

Files: 165f298ed05493f7f1381ef269c0eca496e4679b / app / page / home.js

3833 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
18function 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 container = h('div.container', [])
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 .sort(function (a, b) {
81 return latestUpdate(b) - latestUpdate(a)
82 })
83
84 function latestUpdate(thread) {
85 var m = thread.timestamp
86 if(!thread.replies) return m
87
88 for(var i = 0; i < thread.replies.length; i++)
89 m = Math.max(thread.replies[i].timestamp, m)
90 return m
91 }
92
93 function roots (r) {
94 return Object.keys(r || {}).map(function (k) {
95 return threads.roots[r[k]]
96 }).filter(function (e) {
97 return e && e.value
98 })
99 }
100
101
102 morphdom(container,
103 // LEGACY: some of these containers could be removed
104 // but they are here to be compatible with the old MCSS.
105 h('div.container', [
106 //private section
107 h('section.updates -directMessage', [
108 h('div.threads',
109 groupedThreads.map(thread => {
110 const channel = thread.value.content.channel
111 const onClick = channel
112 ? (ev) => api.history.sync.push({ channel })
113 : null // threadCard will install default onClick
114
115 return api.app.html.threadCard(thread, { onClick })
116 })
117 )
118 ])
119 ])
120 )
121
122 return container
123 }
124 )
125 return h('Page -home', {title: strings.home}, [
126 threadsHtmlObs,
127 h('button', {'ev-click': threadsHtmlObs.more}, [strings.showMore])
128 ])
129 })
130}
131
132
133
134

Built with git-ssb-web