Files: fb0788760b2ce15437b50ead1e804b650cc19077 / app / page / blogIndex.js
3803 bytesRaw
1 | const nest = require('depnest') |
2 | const { h } = require('mutant') |
3 | |
4 | const isString = require('lodash/isString') |
5 | const More = require('hypermore') |
6 | const morphdom = require('morphdom') |
7 | const Debounce = require('obv-debounce') |
8 | |
9 | exports.gives = nest('app.page.blogIndex') |
10 | |
11 | exports.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 | |
21 | exports.create = (api) => { |
22 | var contentHtmlObs |
23 | |
24 | return nest('app.page.blogIndex', function (location) { |
25 | // location here can expected to be: { page: 'blogIndex'} or { page: 'home' } |
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 | if (contentHtmlObs) return contentHtmlObs |
42 | // TODO - replace with actual blogs |
43 | var morePlease = false |
44 | |
45 | var threadsObs = api.state.obs.threads() |
46 | // var timestamp = new Date() |
47 | // threadsObs(ev => console.log(timestamp, ev)) |
48 | |
49 | var threadsObsDebounced = threadsObs // TODO rename or fix debounce |
50 | |
51 | // DUCT TAPE: debounce the observable so it doesn't |
52 | // update the dom more than 1/second |
53 | // threadsObs(function () { |
54 | // console.log('blogs - update?', morePlease) |
55 | // if(morePlease) threadsObs.more() |
56 | // }) |
57 | // threadsObsDebounced = Debounce(threadsObs, 1000) |
58 | // threadsObsDebounced(function () { |
59 | // console.log('blogs - set morePlease: false') |
60 | // morePlease = false |
61 | // }) |
62 | // threadsObsDebounced.more = function () { |
63 | // console.log('blogs - set morePlease: true', 'requestIdleCallback') |
64 | // morePlease = true |
65 | // requestIdleCallback(threadsObs.more) |
66 | // } |
67 | |
68 | var updates = h('div.blogs', []) |
69 | contentHtmlObs = More( |
70 | threadsObsDebounced, |
71 | function render (threads) { |
72 | |
73 | function latestUpdate(thread) { |
74 | var m = thread.timestamp || 0 |
75 | if(!thread.replies) return m |
76 | |
77 | for(var i = 0; i < thread.replies.length; i++) |
78 | m = Math.max(thread.replies[i].timestamp||0, m) |
79 | return m |
80 | } |
81 | |
82 | var groupedThreads = |
83 | Object.keys(threads.roots || {}).map(function (id) { |
84 | return threads.roots[id] |
85 | }) |
86 | .filter(function (thread) { |
87 | return thread.value |
88 | }) |
89 | .filter(function (thread) { |
90 | //show public messages only |
91 | return !thread.value.content.recps |
92 | }) |
93 | .map(function (thread) { |
94 | var unread = 0 |
95 | if(api.unread.sync.isUnread(thread)) |
96 | unread ++ |
97 | ;(thread.replies || []).forEach(function (msg) { |
98 | if(api.unread.sync.isUnread(msg)) unread ++ |
99 | }) |
100 | thread.unread = unread |
101 | return thread |
102 | }) |
103 | .sort((a, b) => latestUpdate(b) - latestUpdate(a)) |
104 | |
105 | morphdom( |
106 | updates, |
107 | h('div.blogs', |
108 | groupedThreads.map(thread => { |
109 | const { recps, channel } = thread.value.content |
110 | var onClick |
111 | if (channel && !recps) |
112 | onClick = (ev) => api.history.sync.push(Object.assign({}, thread, { page: 'blogShow' })) |
113 | |
114 | return api.app.html.blogCard(thread, { onClick }) |
115 | }) |
116 | ) |
117 | ) |
118 | |
119 | return updates |
120 | } |
121 | ) |
122 | |
123 | return contentHtmlObs |
124 | } |
125 | } |
126 | |
127 |
Built with git-ssb-web