Tag support
This commit is contained in:
parent
a7d5a976ca
commit
6576cf9a18
@ -1,5 +1,6 @@
|
|||||||
import * as image from './data/image.js';
|
import * as image from './data/image.js';
|
||||||
import { getDatabase } from './services/db.js';
|
import { getDatabase } from './services/db.js';
|
||||||
|
import * as imageTag from './context/manageImageTags.js';
|
||||||
|
|
||||||
import './context/generateThumbnails.js';
|
import './context/generateThumbnails.js';
|
||||||
|
|
||||||
@ -17,16 +18,50 @@ function refresh() {
|
|||||||
setTimeout(() => history.go(0), 100);
|
setTimeout(() => history.go(0), 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
imagedb.allDocs({ include_docs: true, attachments: true }).then(results => {
|
db.allDocs({ include_docs: true, attachments: true }).then(async results => {
|
||||||
|
results.rows.forEach(r => {
|
||||||
|
const doc = r.doc;
|
||||||
|
});
|
||||||
|
|
||||||
|
function renderThumbnail(id, name, doc, tags) {
|
||||||
|
const c = document.createElement('div');
|
||||||
|
const e = document.createElement('img');
|
||||||
|
|
||||||
|
c.appendChild(e);
|
||||||
|
c.id = id;
|
||||||
|
c.className = 'image';
|
||||||
|
e.title = `${id} ${name}`;
|
||||||
|
e.src = `data:${doc.content_type};base64,${doc.data}`;
|
||||||
|
e.dataset.id = id;
|
||||||
|
e.onclick = evt => image.remove(evt.currentTarget.dataset.id).then(refresh);
|
||||||
|
|
||||||
|
Object.entries(tags)
|
||||||
|
.filter(([_, visible]) => visible)
|
||||||
|
.forEach(([title, _]) => {
|
||||||
|
const t = document.createElement('span');
|
||||||
|
t.textContent = title;
|
||||||
|
t.className = 'tag';
|
||||||
|
t.onclick = evt => imageTag.remove(title, id).then(refresh);
|
||||||
|
c.appendChild(t);
|
||||||
|
});
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
results.rows.forEach(r => {
|
results.rows.forEach(r => {
|
||||||
for (let aName in r.doc._attachments) {
|
for (let aName in r.doc._attachments) {
|
||||||
const a = r.doc._attachments[aName];
|
if (aName !== 'thumbnail') {
|
||||||
const e = document.createElement('img');
|
continue;
|
||||||
document.body.appendChild(e);
|
}
|
||||||
e.title = `${r.doc._id} ${aName}`;
|
document.body.appendChild(
|
||||||
e.src = `data:${a.content_type};base64,${a.data}`;
|
renderThumbnail(r.doc._id, aName, r.doc._attachments[aName], r.doc.tags)
|
||||||
e.dataset.id = r.doc._id;
|
);
|
||||||
e.onclick = evt => image.remove(evt.currentTarget.dataset.id).then(refresh);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Array.from(document.querySelectorAll('.image')).forEach(i => {
|
||||||
|
const b = document.createElement('button');
|
||||||
|
b.onclick = evt => imageTag.add(prompt('Tag Name'), i.id).then(refresh);
|
||||||
|
b.textContent = '+';
|
||||||
|
i.appendChild(b);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
16
packages/gallery/src/context/manageImageTags.js
Normal file
16
packages/gallery/src/context/manageImageTags.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import * as image from '../data/image.js';
|
||||||
|
import * as index from '../data/indexType.js';
|
||||||
|
|
||||||
|
export async function add(title, imageId, visible = true) {
|
||||||
|
const trimmedTitle = title.trim();
|
||||||
|
await index.add(trimmedTitle, [imageId]);
|
||||||
|
return image.update(imageId, {
|
||||||
|
tags: { [trimmedTitle]: visible }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function remove(title, imageId) {
|
||||||
|
const id = index.hashString(title);
|
||||||
|
await image.update(imageId, { tags: { [title]: undefined } });
|
||||||
|
await index.removeMember(title, imageId);
|
||||||
|
}
|
||||||
@ -25,6 +25,7 @@ export async function add(imageFileList) {
|
|||||||
size: f.size,
|
size: f.size,
|
||||||
modifiedDate: new Date(f.lastModified).toISOString(),
|
modifiedDate: new Date(f.lastModified).toISOString(),
|
||||||
uploadedDate: new Date().toISOString(),
|
uploadedDate: new Date().toISOString(),
|
||||||
|
tags: {},
|
||||||
_attachments: {
|
_attachments: {
|
||||||
image: {
|
image: {
|
||||||
content_type: f.type,
|
content_type: f.type,
|
||||||
|
|||||||
58
packages/gallery/src/data/indexType.js
Normal file
58
packages/gallery/src/data/indexType.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import { log, error } from '../services/console.js';
|
||||||
|
import { getDatabase, getOrCreate } from '../services/db.js';
|
||||||
|
|
||||||
|
const db = getDatabase();
|
||||||
|
const PREFIX = 'index';
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
export const hashString = name =>
|
||||||
|
name
|
||||||
|
.trim()
|
||||||
|
.replace(/[ \-~!@#$%^&]/g, '_')
|
||||||
|
.toLowerCase();
|
||||||
|
const getId = id => (id.startsWith(PREFIX) ? id : `${PREFIX}_${hashString(id)}`);
|
||||||
|
|
||||||
|
export async function find(keys, options = {}) {
|
||||||
|
return await db.allDocs(Object.assign({ include_docs: true }, options, { keys: keys.map(getId) }));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function add(id, members = []) {
|
||||||
|
const _id = getId(id);
|
||||||
|
const [results, created] = await getOrCreate({
|
||||||
|
_id,
|
||||||
|
members: []
|
||||||
|
});
|
||||||
|
|
||||||
|
if (members.length) {
|
||||||
|
members.forEach(async m => await addMember(_id, m));
|
||||||
|
}
|
||||||
|
|
||||||
|
return created || results.ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function addMember(id, member) {
|
||||||
|
const results = await find([id]);
|
||||||
|
const doc = results.rows[0].doc;
|
||||||
|
|
||||||
|
if (doc.members.indexOf(member) === -1) {
|
||||||
|
doc.members.push(member);
|
||||||
|
await db.put(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function removeMember(id, member) {
|
||||||
|
const results = await find([id]);
|
||||||
|
const doc = results.rows[0].doc;
|
||||||
|
const idx = doc.members.indexOf(member);
|
||||||
|
|
||||||
|
if (idx !== -1) {
|
||||||
|
if (doc.members.length > 1) {
|
||||||
|
doc.members.splice(idx, 1);
|
||||||
|
await db.put(doc);
|
||||||
|
} else {
|
||||||
|
await db.remove(doc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,3 +15,16 @@ export function getDatabase(name = 'gallery') {
|
|||||||
}
|
}
|
||||||
return dbs.get(name);
|
return dbs.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getOrCreate(doc) {
|
||||||
|
try {
|
||||||
|
const results = await db.get(doc._id);
|
||||||
|
return [results, false];
|
||||||
|
} catch (e) {
|
||||||
|
if (e.status === 404) {
|
||||||
|
const results = db.put(doc);
|
||||||
|
return [results, true];
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user