Files: 9de2656efd585098ef7eb72d618684bd03e34c37 / app / page / blogSearch.js
3116 bytesRaw
1 | const nest = require('depnest') |
2 | const { h, Value, computed, map, when, resolve } = require('mutant') |
3 | const pull = require('pull-stream') |
4 | |
5 | exports.gives = nest('app.page.blogSearch') |
6 | |
7 | exports.needs = nest({ |
8 | 'app.html.context': 'first', |
9 | 'app.html.blogCard': 'first', |
10 | 'app.html.blogNav': 'first', |
11 | 'app.html.scroller': 'first', |
12 | 'channel.obs.recent': 'first', |
13 | 'feed.pull.public': 'first', |
14 | 'history.sync.push': 'first', |
15 | 'keys.sync.id': 'first', |
16 | 'message.html.channel': 'first', |
17 | 'translations.sync.strings': 'first', |
18 | 'unread.sync.isUnread': 'first' |
19 | }) |
20 | |
21 | exports.create = (api) => { |
22 | return nest('app.page.blogSearch', blogSearch) |
23 | |
24 | function blogSearch (location) { |
25 | // location here can expected to be: { page: 'blogSearch'} |
26 | // OR { page: 'blogSearch', channel: 'scuttlebutt', searchVal: 'scutt'} |
27 | |
28 | var strings = api.translations.sync.strings() |
29 | |
30 | var searchVal = Value(resolve(location.searchVal) || '') |
31 | var searchResults = computed([api.channel.obs.recent(), searchVal], (channels, val) => { |
32 | if (val.length < 2) return [] |
33 | |
34 | return channels.filter(c => c.toLowerCase().indexOf(val.toLowerCase()) > -1) |
35 | }) |
36 | var searchField = h('div.search', [ |
37 | h('div.input', [ |
38 | h('i.fa.fa-search'), |
39 | h('input', { |
40 | 'ev-input': e => searchVal.set(e.target.value), |
41 | value: searchVal |
42 | }) |
43 | ]), |
44 | when(searchResults, |
45 | h('div.results', map(searchResults, channel => { |
46 | const classList = channel === location.channel |
47 | ? ['-channelActive'] |
48 | : '' |
49 | const newLocation = { |
50 | page: 'blogSearch', |
51 | channel, |
52 | searchVal |
53 | } |
54 | return api.message.html.channel(channel, { classList, location: newLocation }) |
55 | })) |
56 | ) |
57 | ]) |
58 | |
59 | var blogs = api.app.html.scroller({ |
60 | classList: ['content'], |
61 | prepend: [ |
62 | api.app.html.blogNav(location), |
63 | searchField |
64 | ], |
65 | stream: api.feed.pull.public, |
66 | filter: () => pull( |
67 | pull.filter(msg => { |
68 | const type = msg.value.content.type |
69 | return type === 'post' || type === 'blog' |
70 | }), |
71 | pull.filter(msg => !msg.value.content.root), // show only root messages |
72 | pull.filter(msg => { |
73 | if (!location.channel) return true |
74 | return msg.value.content.channel === location.channel |
75 | }) |
76 | ), |
77 | // FUTURE : if we need better perf, we can add a persistent cache. At the moment this page is fast enough though. |
78 | // See implementation of app.html.context for example |
79 | // store: recentMsgCache, |
80 | // updateTop: updateRecentMsgCache, |
81 | // updateBottom: updateRecentMsgCache, |
82 | render |
83 | }) |
84 | |
85 | return h('Page -blogSearch', {title: strings.home}, [ |
86 | api.app.html.context(location), |
87 | blogs |
88 | ]) |
89 | } |
90 | |
91 | |
92 | function render (blog) { |
93 | const { recps, channel } = blog.value.content |
94 | var onClick |
95 | if (channel && !recps) |
96 | onClick = (ev) => api.history.sync.push(Object.assign({}, blog, { page: 'blogShow' })) |
97 | |
98 | return api.app.html.blogCard(blog, { onClick }) |
99 | } |
100 | } |
101 | |
102 | |
103 |
Built with git-ssb-web