summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--public/gallery.js115
-rw-r--r--public/style.css9
2 files changed, 117 insertions, 7 deletions
diff --git a/public/gallery.js b/public/gallery.js
index 0967534..f18e4a9 100644
--- a/public/gallery.js
+++ b/public/gallery.js
@@ -8,6 +8,8 @@ function call(method, params) {
})
}
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
let BrowseModel = {
path: undefined,
subdirectories: [],
@@ -113,6 +115,8 @@ let Browse = {
},
}
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
let ViewModel = {
sha1: undefined,
width: 0,
@@ -121,10 +125,12 @@ let ViewModel = {
tags: {},
async reload(sha1) {
- this.sha1 = sha1
- this.width = this.height = 0
- this.paths = []
- this.tags = {}
+ if (this.sha1 !== sha1) {
+ this.sha1 = sha1
+ this.width = this.height = 0
+ this.paths = []
+ this.tags = {}
+ }
let resp = await call('info', {sha1: sha1})
this.width = resp.width
@@ -195,20 +201,117 @@ let View = {
: "No image.",
])
return m('.container', {}, [
- m('.header', {}, "View"),
+ m('.header', {}, [
+ "View",
+ m(m.route.Link, {
+ href: `/similar/:key`,
+ params: {key: ViewModel.sha1},
+ }, "Similar")
+ ]),
m('.body', {}, [view, m(ViewBar)]),
])
},
}
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+let SimilarModel = {
+ sha1: undefined,
+ info: {paths: []},
+ groups: {},
+
+ async reload(sha1) {
+ if (this.sha1 !== sha1) {
+ this.sha1 = sha1
+ this.info = {paths: []}
+ this.groups = {}
+ }
+
+ let resp = await call('similar', {sha1: sha1})
+ this.info = resp.info
+ this.groups = resp.groups
+ },
+}
+
+let SimilarThumbnail = {
+ view(vnode) {
+ const info = vnode.attrs.info
+ return m(m.route.Link, {href: `/view/${info.sha1}`},
+ m('img', {src: `/thumb/${info.sha1}`,
+ width: info.thumbW, height: info.thumbH}))
+ },
+}
+
+let SimilarGroup = {
+ view(vnode) {
+ const images = vnode.attrs.images
+ let result = [
+ m('h2', vnode.attrs.name),
+ images.map(info => m('.row', [
+ m(SimilarThumbnail, {info}),
+ m('ul', [
+ m('li', Math.round(info.pixelsRatio * 100) +
+ "% pixels of input image"),
+ info.paths.map(path =>
+ m('li', m(ViewBarPath, {path}))),
+ ]),
+ ]))
+ ]
+ if (!images.length)
+ result.push("No matches.")
+ return result
+ },
+}
+
+let SimilarList = {
+ view(vnode) {
+ if (SimilarModel.sha1 === undefined ||
+ SimilarModel.info.paths.length == 0)
+ return "No image"
+
+ const info = SimilarModel.info
+ return m('.similar', {}, [
+ m('.row', [
+ m(SimilarThumbnail, {info}),
+ m('ul', info.paths.map(path =>
+ m('li', m(ViewBarPath, {path})))),
+ ]),
+ Object.entries(SimilarModel.groups).map(([name, images]) =>
+ m(SimilarGroup, {name, images})),
+ ])
+ },
+}
+
+let Similar = {
+ oninit(vnode) {
+ let sha1 = vnode.attrs.key || ""
+ SimilarModel.reload(sha1)
+ },
+
+ view(vnode) {
+ return m('.container', {}, [
+ m('.header', {}, [
+ "Similarity search",
+ m(m.route.Link, {
+ href: `/view/:key`,
+ params: {key: SimilarModel.sha1},
+ }, "View")
+ ]),
+ m('.body', {}, m(SimilarList)),
+ ])
+ },
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
window.addEventListener('load', () => {
m.route(document.body, "/browse/", {
// The path doesn't need to be escaped, perhaps change that (":key...").
"/browse/": Browse,
"/browse/:key": Browse,
"/view/:key": View,
+ "/similar/:key": Similar,
- "/similar/:sha1": undefined,
"/tags": undefined,
"/tags/:space": undefined,
"/tags/:space/:tag": undefined,
diff --git a/public/style.css b/public/style.css
index 8a42a51..d6c2e3f 100644
--- a/public/style.css
+++ b/public/style.css
@@ -7,7 +7,9 @@ a { color: inherit; }
.body { display: flex; flex-grow: 1; overflow: hidden; }
.header { padding: .25rem .5rem; background: #aaa; color: white;
- border-bottom: 1px solid #444; }
+ border-bottom: 1px solid #444;
+ display: flex; justify-content: space-between; align-items: baseline;
+ column-gap: .5rem; }
ul.sidebar { margin: 0; padding: 0; background: #eee;
border-right: 1px solid #ccc; min-width: 10rem; overflow: auto; }
@@ -47,3 +49,8 @@ ul.sidebar li.child a {
.viewbar li { margin: 0; padding: 0; }
.viewbar meter { width: 1.25rem;
/* background: white; border: 1px solid #ccc; */ }
+
+.similar { padding: .5rem; flex-grow: 1; overflow: auto; }
+.similar h2 { margin: 1em 0 0.5em 0; padding: 0; font-size: 1.2rem; }
+.similar .row { display: flex; }
+.similar .row ul { margin: 0; padding: 0 0 0 1.25em; list-style-type: "- "; }