git ssb

16+

Dominic / patchbay



Tree: ed0d0518717fe16a686399588766fb35b3e6e37a

Files: ed0d0518717fe16a686399588766fb35b3e6e37a / app / page / image-search.js

3889 bytesRaw
1const nest = require('depnest')
2const { h, Dict, Value, watch, throttle, computed, map, onceTrue } = require('mutant')
3
4exports.gives = nest({
5 'app.page.imageSearch': true,
6 'app.html.menuItem': true
7})
8
9exports.needs = nest({
10 'sbot.obs.connection': 'first',
11 'blob.sync.url': 'first',
12 'app.html.modal': 'first',
13 'app.sync.goTo': 'first',
14 'about.obs.name': 'first',
15 'backlinks.obs.for': 'first'
16})
17
18exports.create = function (api) {
19 return nest({
20 'app.html.menuItem': menuItem,
21 'app.page.imageSearch': searchPage
22 })
23
24 function menuItem () {
25 return h('a', {
26 'ev-click': () => api.app.sync.goTo('/imageSearch')
27 }, '/imageSearch')
28 }
29
30 function searchPage (location) {
31 const query = Value('')
32 const results = Dict({})
33
34 watch(throttle(query, 300), q => {
35 if (q && q.length < 3) return
36 onceTrue(api.sbot.obs.connection, sbot => {
37 sbot.meme.search(q, (err, data) => {
38 if (err) return console.error(err)
39 results.set(data)
40 })
41 })
42 })
43
44 const focusedBlob = Value()
45 const modal = Modal({
46 results,
47 focusedBlob,
48 blobUrl: api.blob.sync.url,
49 name: api.about.obs.name,
50 goTo: api.app.sync.goTo,
51 createModal: api.app.html.modal,
52 backlinks: api.backlinks.obs.for
53 })
54
55 const page = h('Page -imageSearch', [
56 modal,
57 h('section.settings', [
58 h('input', {
59 'placeholder': 'search image by name',
60 'ev-input': ev => query.set(ev.target.value)
61 })
62 ]),
63 h('section.results', computed([results, query], (results, query) => {
64 if (!Object.keys(results).length && query.length >= 3) return h('p', '0 results')
65
66 return Object.keys(results).map(blob => {
67 return h('div', { 'ev-click': () => focusedBlob.set(blob) }, [
68 h('img', { src: api.blob.sync.url(blob) })
69 ])
70 })
71 }))
72 ])
73
74 page.title = '/imageSearch'
75
76 return page
77 }
78}
79
80function Modal ({ results, focusedBlob, blobUrl, name, goTo, createModal, backlinks }) {
81 const onClick = (link) => () => {
82 isOpen.set(false)
83 goTo(link)
84 }
85
86 const isOpen = Value(false)
87 focusedBlob(blob => {
88 if (blob) isOpen.set(true)
89 })
90 const modalContent = computed([focusedBlob], (blob) => {
91 if (!blob) return
92
93 const entries = computed(backlinks(blob), msgs => {
94 return msgs.reduce((soFar, msg) => {
95 const entries = getMentions(msg)
96 .filter(mention => mention.link === blob)
97 // .filter(mention => mention.name)
98 .map(mention => { return { name: mention.name, author: msg.value.author, msg: msg.key, ts: msg.value.timestamp } })
99 return [...soFar, ...entries]
100 }, [])
101 })
102
103 const imageName = Value('CHOOSE YOUR OWN NAME')
104
105 return h('ImageSearchDetails', [
106 h('img', { src: blobUrl(blob) }),
107 h('div.md', [
108 'Copy markdown: ',
109 h('pre', ['![', imageName, '](', blob, ')'])
110 ]),
111 h('table', map(entries, entry => {
112 return h('tr', { 'ev-mouseover': () => entry.name && imageName.set(entry.name) }, [
113 h('td', entry.name),
114 h('td.msg', h('a', { href: '#', 'ev-click': onClick(entry.msg) }, entry.msg.substring(0, 10) + '...')),
115 h('td', h('a', { href: '#', 'ev-click': onClick(entry.author) }, ['@', name(entry.author)])),
116 h('td', JSON.stringify(new Date(entry.ts)).substring(1, 11)) // I am a bad human D:
117 ])
118 })),
119 h('button', {
120 'ev-click': () => {
121 focusedBlob.set()
122 isOpen.set(false)
123 }
124 }, 'Close')
125 ])
126 })
127 return createModal(modalContent, { isOpen })
128}
129
130function getMentions (msg) {
131 if (!msg.value.content.mentions) return []
132 else if (!Array.isArray(msg.value.content.mentions)) return [msg.value.content.mentions]
133 else return msg.value.content.mentions
134}
135

Built with git-ssb-web