Commit a397d2b2add6be261bf7ddda868de8161e8ae5f3
allow searching backlinks and add to context menu
search by prefixing ID with `?`Matt McKegg committed on 4/20/2018, 11:36:42 AM
Parent: 10f58a04da1ab33c03a561753d15c0f77098cbbb
Files changed
lib/context-menu-and-spellcheck.js | ||
---|---|---|
@@ -2,11 +2,13 @@ | ||
2 | 2 | var {SpellCheckHandler, ContextMenuListener, ContextMenuBuilder} = require('electron-spellchecker') |
3 | 3 | var {MenuItem, Menu} = remote |
4 | 4 | var ref = require('ssb-ref') |
5 | 5 | |
6 | +var navigateHandler = null | |
6 | 7 | module.exports = setupContextMenuAndSpellCheck |
7 | 8 | |
8 | -function setupContextMenuAndSpellCheck (config) { | |
9 | +function setupContextMenuAndSpellCheck (config, navigate) { | |
10 | + navigateHandler = navigate | |
9 | 11 | window.spellCheckHandler = new SpellCheckHandler() |
10 | 12 | window.spellCheckHandler.attachToInput() |
11 | 13 | |
12 | 14 | // Start off as US English, America #1 (lol) |
@@ -40,8 +42,17 @@ | ||
40 | 42 | menu.append(openLink) |
41 | 43 | } |
42 | 44 | |
43 | 45 | if (extractedRef) { |
46 | + if (navigateHandler) { | |
47 | + menu.append(new MenuItem({ | |
48 | + label: 'Find Link References', | |
49 | + click: function () { | |
50 | + navigateHandler('?' + extractedRef) | |
51 | + } | |
52 | + })) | |
53 | + this.addSeparator(menu) | |
54 | + } | |
44 | 55 | var copyRef = new MenuItem({ |
45 | 56 | label: `Copy Link Ref (${extractedRef.slice(0, 10)}...)`, |
46 | 57 | click: () => { |
47 | 58 | // Omit the mailto: portion of the link; we just want the address |
@@ -61,9 +72,9 @@ | ||
61 | 72 | |
62 | 73 | return menu |
63 | 74 | } |
64 | 75 | |
65 | - module.exports = new ContextMenuListener((info) => { | |
76 | + module.exports.menu = new ContextMenuListener((info) => { | |
66 | 77 | contextMenuBuilder.buildMenuForElement(info).then((menu) => { |
67 | 78 | var element = document.elementFromPoint(info.x, info.y) |
68 | 79 | while (element && !element.msg) { |
69 | 80 | element = element.parentNode |
locales/en.json | ||
---|---|---|
@@ -190,6 +190,7 @@ | ||
190 | 190 | "Choose a title": "Choose a title", |
191 | 191 | "Choose date and time": "Choose date and time", |
192 | 192 | "Choose Banner Image...": "Choose Banner Image...", |
193 | 193 | "Describe the gathering (if you want)": "Describe the gathering (if you want)", |
194 | - "Create Gathering": "Create Gathering" | |
194 | + "Create Gathering": "Create Gathering", | |
195 | + "liked": "liked" | |
195 | 196 | } |
main-window.js | ||
---|---|---|
@@ -45,9 +45,9 @@ | ||
45 | 45 | 'settings.obs.get': 'first', |
46 | 46 | 'intl.sync.i18n': 'first' |
47 | 47 | })) |
48 | 48 | |
49 | - setupContextMenuAndSpellCheck(api.config.sync.load()) | |
49 | + setupContextMenuAndSpellCheck(api.config.sync.load(), navigate) | |
50 | 50 | |
51 | 51 | const i18n = api.intl.sync.i18n |
52 | 52 | |
53 | 53 | var id = api.keys.sync.id() |
modules/page/html/render/search.js | ||
---|---|---|
@@ -5,14 +5,16 @@ | ||
5 | 5 | var pullAbortable = require('pull-abortable') |
6 | 6 | var Scroller = require('../../../../lib/scroller') |
7 | 7 | var nest = require('depnest') |
8 | 8 | var Proxy = require('mutant/proxy') |
9 | +var ref = require('ssb-ref') | |
9 | 10 | |
10 | 11 | exports.needs = nest({ |
11 | 12 | 'sbot.pull.stream': 'first', |
12 | 13 | 'keys.sync.id': 'first', |
13 | 14 | 'message.html.render': 'first', |
14 | - 'intl.sync.i18n': 'first' | |
15 | + 'intl.sync.i18n': 'first', | |
16 | + 'sbot.pull.backlinks': 'first' | |
15 | 17 | }) |
16 | 18 | |
17 | 19 | exports.gives = nest('page.html.render') |
18 | 20 | |
@@ -56,9 +58,9 @@ | ||
56 | 58 | |
57 | 59 | var realtimeAborter = pullAbortable() |
58 | 60 | |
59 | 61 | pull( |
60 | - api.sbot.pull.stream(sbot => sbot.patchwork.linearSearch({old: false, query: query.split(whitespace)})), | |
62 | + getStream(query, true), | |
61 | 63 | realtimeAborter, |
62 | 64 | pull.drain(msg => { |
63 | 65 | updates.set(updates() + 1) |
64 | 66 | }) |
@@ -100,17 +102,17 @@ | ||
100 | 102 | done.set(true) |
101 | 103 | }) |
102 | 104 | |
103 | 105 | pull( |
104 | - api.sbot.pull.stream(sbot => sbot.search.query({query})), | |
106 | + getStream(query, false), | |
105 | 107 | pull.through(() => count.set(count() + 1)), |
106 | 108 | aborter, |
107 | 109 | pull.filter(msg => msg.value), |
108 | 110 | scroller |
109 | 111 | ) |
110 | 112 | |
111 | 113 | loading.set(computed([done, scroller.queue], (done, queue) => { |
112 | - return !done && queue < 5 | |
114 | + return !done | |
113 | 115 | })) |
114 | 116 | } |
115 | 117 | |
116 | 118 | function renderMsg (msg) { |
@@ -118,8 +120,25 @@ | ||
118 | 120 | highlight(el, createOrRegExp(query.split(whitespace))) |
119 | 121 | return el |
120 | 122 | } |
121 | 123 | }) |
124 | + | |
125 | + function getStream (query, realtime = false) { | |
126 | + if (ref.isLink(query) || query.startsWith('#')) { | |
127 | + return api.sbot.pull.backlinks({ | |
128 | + query: [ {$filter: { dest: query }} ], | |
129 | + reverse: true, | |
130 | + old: !realtime, | |
131 | + index: 'DTA' // use asserted timestamps | |
132 | + }) | |
133 | + } else { | |
134 | + if (realtime) { | |
135 | + return api.sbot.pull.stream(sbot => sbot.patchwork.linearSearch({old: false, query: query.split(whitespace)})) | |
136 | + } else { | |
137 | + return api.sbot.pull.stream(sbot => sbot.search.query({query})) | |
138 | + } | |
139 | + } | |
140 | + } | |
122 | 141 | } |
123 | 142 | |
124 | 143 | function createOrRegExp (ary) { |
125 | 144 | return new RegExp(ary.map(function (e) { |
plugs/message/html/layout/mini.js | ||
---|---|---|
@@ -32,9 +32,9 @@ | ||
32 | 32 | }) |
33 | 33 | |
34 | 34 | return nest('message.html.layout', layout) |
35 | 35 | |
36 | - function layout (msg, {layout, previousId, priority, miniContent, content, includeReferences, includeForks = true}) { | |
36 | + function layout (msg, {layout, previousId, priority, miniContent, content, includeReferences, includeForks = true, actions = true}) { | |
37 | 37 | if (!(layout === 'mini')) return |
38 | 38 | |
39 | 39 | var classList = ['Message -mini'] |
40 | 40 | |
@@ -66,10 +66,10 @@ | ||
66 | 66 | messageHeader(msg, { |
67 | 67 | replyInfo, priority, miniContent |
68 | 68 | }), |
69 | 69 | h('section', [content]), |
70 | - computed(msg.key, (key) => { | |
71 | - if (ref.isMsg(key)) { | |
70 | + computed([msg.key, actions], (key, actions) => { | |
71 | + if (ref.isMsg(key) && actions) { | |
72 | 72 | return h('footer', [ |
73 | 73 | h('div.actions', [ |
74 | 74 | api.message.html.action(msg) |
75 | 75 | ]) |
plugs/message/html/render/vote.js | ||
---|---|---|
@@ -1,0 +1,51 @@ | ||
1 | +var nest = require('depnest') | |
2 | +var extend = require('xtend') | |
3 | + | |
4 | +exports.needs = nest({ | |
5 | + 'message.html': { | |
6 | + decorate: 'reduce', | |
7 | + layout: 'first', | |
8 | + link: 'first' | |
9 | + }, | |
10 | + 'intl.sync.i18n': 'first' | |
11 | +}) | |
12 | + | |
13 | +exports.gives = nest('message.html', { | |
14 | + canRender: true, | |
15 | + render: true | |
16 | +}) | |
17 | + | |
18 | +exports.create = function (api) { | |
19 | + const i18n = api.intl.sync.i18n | |
20 | + return nest('message.html', { | |
21 | + canRender: isRenderable, | |
22 | + render: function (msg, opts) { | |
23 | + if (!isRenderable(msg)) return | |
24 | + | |
25 | + var element = api.message.html.layout(msg, extend({ | |
26 | + miniContent: messageContent(msg), | |
27 | + layout: 'mini', | |
28 | + actions: false | |
29 | + }, opts)) | |
30 | + | |
31 | + return api.message.html.decorate(element, { | |
32 | + msg | |
33 | + }) | |
34 | + } | |
35 | + }) | |
36 | + | |
37 | + function messageContent (msg) { | |
38 | + var liked = msg.value.content.vote.value > 0 | |
39 | + var link = msg.value.content.vote.link | |
40 | + | |
41 | + if (liked) { | |
42 | + return [ i18n('liked'), ' ', api.message.html.link(link) ] | |
43 | + } else { | |
44 | + return [ i18n('unliked'), ' ', api.message.html.link(link) ] | |
45 | + } | |
46 | + } | |
47 | + | |
48 | + function isRenderable (msg) { | |
49 | + return (msg.value.content.type === 'vote' ? true : undefined) && msg.value.content.vote | |
50 | + } | |
51 | +} |
Built with git-ssb-web