Files: 5ed0ef75a42972670b29aada99be810a8bde7b80 / modules / search-box.js
2686 bytesRaw
1 | var h = require('hyperscript') |
2 | var suggest = require('suggest-box') |
3 | var pull = require('pull-stream') |
4 | var plugs = require('../plugs') |
5 | var sbot_query = plugs.first(exports.sbot_query = []) |
6 | var sbot_links2 = plugs.first(exports.sbot_links2 = []) |
7 | |
8 | var channels = [] |
9 | |
10 | var signified = require('../plugs').first(exports.signified = []) |
11 | |
12 | var builtinTabs = [ |
13 | '/public', '/private', '/notifications', |
14 | '/network', '/query', '/theme', '/versions' |
15 | ].map(function (name) { |
16 | return { |
17 | title: name, |
18 | value: name, |
19 | } |
20 | }) |
21 | |
22 | exports.search_box = function (go) { |
23 | |
24 | var suggestBox |
25 | var search = h('input.searchprompt', { |
26 | type: 'search', |
27 | placeholder: '?word, @key, #channel', |
28 | onkeydown: function (ev) { |
29 | switch (ev.keyCode) { |
30 | case 13: // enter |
31 | if (suggestBox && suggestBox.active) { |
32 | suggestBox.complete() |
33 | ev.stopPropagation() |
34 | } |
35 | if (go(search.value.trim(), !ev.ctrlKey)) |
36 | search.blur() |
37 | return |
38 | case 27: // escape |
39 | ev.preventDefault() |
40 | search.blur() |
41 | return |
42 | } |
43 | } |
44 | }) |
45 | |
46 | search.activate = function (sigil, ev) { |
47 | search.focus() |
48 | ev.preventDefault() |
49 | if (search.value[0] === sigil) { |
50 | search.selectionStart = 1 |
51 | search.selectionEnd = search.value.length |
52 | } else { |
53 | search.value = sigil |
54 | } |
55 | } |
56 | |
57 | var suggestions = {} |
58 | |
59 | // delay until the element has a parent |
60 | setTimeout(function () { |
61 | suggestBox = suggest(search, function (word, cb) { |
62 | if(/^#\w/.test(word)) |
63 | cb(null, channels.filter(function (chan) { |
64 | return ('#'+chan.name).substring(0, word.length) === word |
65 | }) |
66 | .map(function (chan) { |
67 | var name = '#'+chan.name |
68 | return { |
69 | title: name, |
70 | value: name, |
71 | subtitle: chan.rank |
72 | } |
73 | })) |
74 | else if(/^@\w/.test(word)) { |
75 | signified(word, function (_, names) { |
76 | cb(null, names.map(function (e) { |
77 | return { |
78 | title: e.name + ':'+e.id.substring(0, 10), |
79 | value: e.id, |
80 | subtitle: e.rank |
81 | } |
82 | })) |
83 | }) |
84 | } else if(/^\//.test(word)) { |
85 | cb(null, builtinTabs.filter(function (name) { |
86 | return name.value.substr(0, word.length) === word |
87 | })) |
88 | } |
89 | }, {}) |
90 | }, 10) |
91 | |
92 | |
93 | pull( |
94 | sbot_query({query: [ |
95 | {$filter: {value: {content: {channel: {$gt: ''}}}}}, |
96 | {$reduce: { |
97 | name: ['value', 'content', 'channel'], |
98 | rank: {$count: true} |
99 | }} |
100 | ]}), |
101 | pull.collect(function (err, chans) { |
102 | if (err) return console.error(err) |
103 | channels = chans |
104 | }) |
105 | ) |
106 | |
107 | return search |
108 | } |
109 | |
110 | |
111 | |
112 |
Built with git-ssb-web