git ssb

2+

mixmix / ticktack



Tree: 34736f8234e840203c81e10a3b49e1570aa2a801

Files: 34736f8234e840203c81e10a3b49e1570aa2a801 / app / page / blogIndex.js

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

Built with git-ssb-web