commit
58765f8b0e
47
package-lock.json
generated
47
package-lock.json
generated
@ -305,9 +305,9 @@
|
||||
"integrity": "sha512-Lnle0J8t+Z+jFg78GFFnGo+Fphxaco9K9SppeBDsI27QBRBumxeGAMeOg5wt6XbAuj5pQWmAEWWEwPz4PYGMHw=="
|
||||
},
|
||||
"@fraction/flotilla": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@fraction/flotilla/-/flotilla-5.1.0.tgz",
|
||||
"integrity": "sha512-0y/obrwkU7OtJAgQ1LWdaTZJS8tDXJfgq2wvPezqf9J7BvmnN1rYlTBkzeBIVQ4S9o08o0hUhSJurDm30UUW1A==",
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@fraction/flotilla/-/flotilla-5.2.0.tgz",
|
||||
"integrity": "sha512-9uF6Zq/K/qpO54aWkpMK247YbNHok42NMchkBNN5TVIMK+tQKbNW3YR4xgUyUCmVExaO1L5Xk9vHcevg8Pa1NQ==",
|
||||
"requires": {
|
||||
"debug": "^4.1.1",
|
||||
"lodash.shuffle": "^4.2.0",
|
||||
@ -324,6 +324,7 @@
|
||||
"ssb-lan": "^0.2.0",
|
||||
"ssb-logging": "^1.0.0",
|
||||
"ssb-master": "^1.0.3",
|
||||
"ssb-meme": "^1.0.4",
|
||||
"ssb-no-auth": "^1.0.0",
|
||||
"ssb-onion": "^1.0.0",
|
||||
"ssb-ooo": "^1.3.1",
|
||||
@ -477,7 +478,7 @@
|
||||
},
|
||||
"@types/debug": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==",
|
||||
"dev": true
|
||||
},
|
||||
@ -529,7 +530,7 @@
|
||||
},
|
||||
"@types/highlight.js": {
|
||||
"version": "9.12.3",
|
||||
"resolved": "",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-pGF/zvYOACZ/gLGWdQH8zSwteQS1epp68yRcVLJMgUck/MjEn/FBYmPub9pXT8C1e4a8YZfHo1CKyV8q1vKUnQ==",
|
||||
"dev": true
|
||||
},
|
||||
@ -571,7 +572,7 @@
|
||||
},
|
||||
"@types/koa-mount": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-56iBULArwY3uKLl28eRFchZ2v0diEoJzJbDaHH/ehgruF/s2/KMHyWsKcIhvDJ3tGdKu9oZNQvxaMg++1IKFdA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@ -589,7 +590,7 @@
|
||||
},
|
||||
"@types/koa-static": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-SSpct5fEcAeRkBHa3RiwCIRfDHcD1cZRhwRF///ZfvRt8KhoqRrhK6wpDlYPk/vWHVFE9hPGqh68bhzsHkir4w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@ -599,7 +600,7 @@
|
||||
},
|
||||
"@types/koa__router": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-3ZWfVAEcErHrZA31fWUC2YyZyAgoG4eKtQPy2XwBzdSpQealxjL7GcEEtGY925qPPs1wurW59qDl0KuRB39rrw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@ -620,7 +621,7 @@
|
||||
},
|
||||
"@types/markdown-it": {
|
||||
"version": "0.0.9",
|
||||
"resolved": "",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-IFSepyZXbF4dgSvsk8EsgaQ/8Msv1I5eTL0BZ0X3iGO9jw6tCVtPG8HchIPm3wrkmGdqZOD42kE0zplVi1gYDA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@ -647,7 +648,7 @@
|
||||
},
|
||||
"@types/mkdirp": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-ONFY9//bCEr3DWKON3iDv/Q8LXnhaYYaNDeFSN0AtO5o4sLf9F0pstJKKKjQhXE0kJEeHs8eR6SAsROhhc2Csw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@ -661,7 +662,7 @@
|
||||
},
|
||||
"@types/nodemon": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-nf0PKjNv3wo0pyhlPkHjfpU2oUYMdOIsCXceiFG6kvhYxbTwn2ne9mz2iWvJ/4QtCrJUEPJLNXuyGleyTacdaw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@ -688,7 +689,7 @@
|
||||
},
|
||||
"@types/pull-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-d7cobAytjsYaTluqFTJopLbdZRs1HBkU+N07/zCtsXANZ5s9riDazRkvxkAUfmRzCvXqYAsGgnJHgX2lInIOQg==",
|
||||
"dev": true
|
||||
},
|
||||
@ -774,7 +775,7 @@
|
||||
},
|
||||
"@types/yargs": {
|
||||
"version": "15.0.4",
|
||||
"resolved": "",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@ -1583,7 +1584,7 @@
|
||||
},
|
||||
"changelog-version": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "",
|
||||
"resolved": "https://registry.npmjs.org/changelog-version/-/changelog-version-1.0.1.tgz",
|
||||
"integrity": "sha512-WSY6Zq483wM31n+IhBb2f6uLgSQHCrui3VVmX4wmaxcszueYU15qDBhKzG+ZaKhv7ptfswPfv8epampii7s5Zw==",
|
||||
"dev": true
|
||||
},
|
||||
@ -1915,7 +1916,7 @@
|
||||
},
|
||||
"common-good": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "",
|
||||
"resolved": "https://registry.npmjs.org/common-good/-/common-good-2.0.3.tgz",
|
||||
"integrity": "sha512-GFFvmcOOpzts0x+DTR9vIcXr3Pcl1oKM/mYO4P0GQRkwqtO2B+30P4oH/32lmdCwlBdnaET2ZNYnb69Dklfdwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@ -9225,6 +9226,16 @@
|
||||
"resolved": "https://registry.npmjs.org/ssb-master/-/ssb-master-1.0.3.tgz",
|
||||
"integrity": "sha512-N1Cxm9WscGD9VEZrWbF2amyQai2U2g9gtq57W5zTqbhlQTLUUvl84U9A6fg6GPkECnUXadulnTw+mMYVkLLHjQ=="
|
||||
},
|
||||
"ssb-meme": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/ssb-meme/-/ssb-meme-1.0.4.tgz",
|
||||
"integrity": "sha512-r4JAfdCY7tnRzMQNETdWfcm54FOe6bJMbpanp+9dQA76daLu1Jg3EijQ4jNtnDtv1WDMq1XcDTQyEtzVICrKBg==",
|
||||
"requires": {
|
||||
"flumeview-search": "^1.0.3",
|
||||
"is-my-json-valid": "^2.17.2",
|
||||
"ssb-ref": "^2.11.1"
|
||||
}
|
||||
},
|
||||
"ssb-mentions": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ssb-mentions/-/ssb-mentions-0.5.2.tgz",
|
||||
@ -9976,7 +9987,7 @@
|
||||
},
|
||||
"stylelint-config-recommended": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "",
|
||||
"resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-3.0.0.tgz",
|
||||
"integrity": "sha512-F6yTRuc06xr1h5Qw/ykb2LuFynJ2IxkKfCMf+1xqPffkxh0S09Zc902XCffcsw/XMFq/OzQ1w54fLIDtmRNHnQ==",
|
||||
"dev": true
|
||||
},
|
||||
@ -10147,7 +10158,7 @@
|
||||
"dependencies": {
|
||||
"@babel/helpers": {
|
||||
"version": "7.8.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==",
|
||||
"requires": {
|
||||
"@babel/template": "^7.8.3",
|
||||
@ -10157,7 +10168,7 @@
|
||||
},
|
||||
"@babel/runtime": {
|
||||
"version": "7.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.7.tgz",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg==",
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
|
@ -22,7 +22,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@fraction/base16-css": "^1.1.0",
|
||||
"@fraction/flotilla": "^5.1.0",
|
||||
"@fraction/flotilla": "^5.2.0",
|
||||
"@koa/router": "^8.0.0",
|
||||
"debug": "^4.1.1",
|
||||
"env-paths": "^2.2.0",
|
||||
|
@ -491,6 +491,26 @@ input[type="search"] {
|
||||
margin: var(--size-0) 0;
|
||||
}
|
||||
|
||||
.image-search-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-gap: var(--size-0);
|
||||
}
|
||||
|
||||
.image-search-grid .image-result {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: var(--size--1) 0;
|
||||
background: var(--bg);
|
||||
border-radius: var(--common-radius);
|
||||
}
|
||||
|
||||
.image-search-grid .image-result .result-text {
|
||||
hyphens: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: var(--size--4) solid var(--fg-alt);
|
||||
}
|
||||
|
@ -161,6 +161,7 @@ const {
|
||||
publishView,
|
||||
subtopicView,
|
||||
searchView,
|
||||
imageSearchView,
|
||||
setLanguage,
|
||||
settingsView,
|
||||
topicsView,
|
||||
@ -309,6 +310,13 @@ router
|
||||
|
||||
ctx.body = await searchView({ messages, query });
|
||||
})
|
||||
.get("/imageSearch", async (ctx) => {
|
||||
const { query } = ctx.query;
|
||||
|
||||
const blobs = query ? await blob.search({ query }) : {};
|
||||
|
||||
ctx.body = await imageSearchView({ blobs, query });
|
||||
})
|
||||
.get("/inbox", async (ctx) => {
|
||||
const inbox = async () => {
|
||||
const messages = await post.inbox();
|
||||
|
@ -171,6 +171,18 @@ module.exports = ({ cooler, isPublic }) => {
|
||||
// This does not wait for the blob.
|
||||
ssb.blobs.want(blobId);
|
||||
},
|
||||
search: async ({ query }) => {
|
||||
debug("blob search: %s", query);
|
||||
const ssb = await cooler.open();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
ssb.meme.search(query, (err, blobs) => {
|
||||
if (err) return reject(err);
|
||||
|
||||
return resolve(blobs);
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
models.friend = {
|
||||
|
@ -51,6 +51,7 @@ const i18n = {
|
||||
", sorted by recency. Private posts are encrypted for your public key, and have a maximum of 7 recipients. Recipients cannot be added after the thread has started. Select the timestamp to view the full thread.",
|
||||
],
|
||||
search: "Search",
|
||||
imageSearch: "Image Search",
|
||||
settings: "Settings",
|
||||
// post actions
|
||||
comment: "Comment",
|
||||
@ -157,6 +158,8 @@ const i18n = {
|
||||
acceptInvite: "Accept invite",
|
||||
// search page
|
||||
searchLabel: "Add word(s) to look for in downloaded messages.",
|
||||
// image search page
|
||||
imageSearchLabel: "Enter words to search for images labelled with them",
|
||||
// posts and comments
|
||||
commentDescription: ({ parentUrl }) => [
|
||||
" commented on ",
|
||||
|
@ -132,6 +132,11 @@ const template = (...elements) => {
|
||||
navLink({ href: "/mentions", emoji: "💬", text: i18n.mentions }),
|
||||
navLink({ href: "/inbox", emoji: "✉️", text: i18n.private }),
|
||||
navLink({ href: "/search", emoji: "🔍", text: i18n.search }),
|
||||
navLink({
|
||||
href: "/imageSearch",
|
||||
emoji: "🖼️",
|
||||
text: i18n.imageSearch,
|
||||
}),
|
||||
navLink({ href: "/settings", emoji: "⚙", text: i18n.settings })
|
||||
)
|
||||
),
|
||||
@ -1041,6 +1046,76 @@ exports.searchView = ({ messages, query }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const imageResult = ({ id, infos }) => {
|
||||
const encodedBlobId = encodeURIComponent(id);
|
||||
// only rendering the first message result so far
|
||||
// todo: render links to the others as well
|
||||
const info = infos[0];
|
||||
const encodedMsgId = encodeURIComponent(info.msg);
|
||||
|
||||
return div(
|
||||
{
|
||||
class: "image-result",
|
||||
},
|
||||
[
|
||||
a(
|
||||
{
|
||||
href: `/blob/${encodedBlobId}`,
|
||||
},
|
||||
img({ src: `/image/256/${encodedBlobId}` })
|
||||
),
|
||||
a(
|
||||
{
|
||||
href: `/thread/${encodedMsgId}#${encodedMsgId}`,
|
||||
class: "result-text",
|
||||
},
|
||||
info.name
|
||||
),
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
exports.imageSearchView = ({ blobs, query }) => {
|
||||
const searchInput = input({
|
||||
name: "query",
|
||||
required: false,
|
||||
type: "search",
|
||||
value: query,
|
||||
});
|
||||
|
||||
// - Minimum length of 3 because otherwise SSB-Search hangs forever. :)
|
||||
// https://github.com/ssbc/ssb-search/issues/8
|
||||
// - Using `setAttribute()` because HyperScript (the HyperAxe dependency has
|
||||
// a bug where the `minlength` property is being ignored. No idea why.
|
||||
// https://github.com/hyperhype/hyperscript/issues/91
|
||||
searchInput.setAttribute("minlength", 3);
|
||||
|
||||
return template(
|
||||
section(
|
||||
h1(i18n.imageSearch),
|
||||
form(
|
||||
{ action: "/imageSearch", method: "get" },
|
||||
label(i18n.imageSearchLabel, searchInput),
|
||||
button(
|
||||
{
|
||||
type: "submit",
|
||||
},
|
||||
i18n.submit
|
||||
)
|
||||
)
|
||||
),
|
||||
div(
|
||||
{
|
||||
class: "image-search-grid",
|
||||
},
|
||||
Object.keys(blobs)
|
||||
// todo: add pagination
|
||||
.slice(0, 30)
|
||||
.map((blobId) => imageResult({ id: blobId, infos: blobs[blobId] }))
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
exports.hashtagView = ({ messages, hashtag }) => {
|
||||
return template(
|
||||
section(h1(`#${hashtag}`), p(i18n.hashtagDescription)),
|
||||
|
Loading…
Reference in New Issue
Block a user