git ssb

16+

Dominic / patchbay



Tree: 581254ceab1c7f5bcd943eb7f7393dfba611529c

Files: 581254ceab1c7f5bcd943eb7f7393dfba611529c / app / page / imageSearch.js

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

Built with git-ssb-web