git ssb

2+

mixmix / ticktack



Tree: fee2e3b7fdd8450fbfe1e46220642ed555f52eab

Files: fee2e3b7fdd8450fbfe1e46220642ed555f52eab / app / page / blogIndex.js

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

Built with git-ssb-web