Add album view
This commit is contained in:
parent
9c465cd405
commit
ccd0fafd9e
@ -1,28 +1,29 @@
|
||||
import * as image from './data/image.js';
|
||||
import * as index from './data/indexType.js';
|
||||
import { getDatabase } from './services/db.js';
|
||||
import * as imageTag from './context/manageImageTags.js';
|
||||
|
||||
import './context/generateThumbnails.js';
|
||||
|
||||
document.querySelector('#fInput').onchange = async evt => {
|
||||
image.add(evt.currentTarget.files);
|
||||
};
|
||||
|
||||
window.__DEV__ = true;
|
||||
window.db = getDatabase();
|
||||
|
||||
image.imported.subscribe(refresh);
|
||||
const header = document.querySelector('h1');
|
||||
const container = document.querySelector('#app');
|
||||
const displaySelector = document.querySelector('#display');
|
||||
|
||||
// Events
|
||||
displaySelector.onchange = refresh;
|
||||
document.querySelector('#fInput').onchange = async evt => {
|
||||
image.add(evt.currentTarget.files);
|
||||
};
|
||||
|
||||
// To test the output:
|
||||
function refresh() {
|
||||
setTimeout(() => history.go(0), 100);
|
||||
setTimeout(render, 100);
|
||||
}
|
||||
|
||||
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');
|
||||
@ -47,16 +48,47 @@ db.allDocs({ include_docs: true, attachments: true }).then(async results => {
|
||||
return c;
|
||||
}
|
||||
|
||||
results.rows.forEach(r => {
|
||||
for (let aName in r.doc._attachments) {
|
||||
function renderImage(imageRow, imageContainer, showTags = true) {
|
||||
for (let aName in imageRow.doc._attachments) {
|
||||
if (aName !== 'thumbnail') {
|
||||
continue;
|
||||
}
|
||||
document.body.appendChild(
|
||||
renderThumbnail(r.doc._id, aName, r.doc._attachments[aName], r.doc.tags)
|
||||
imageContainer.appendChild(
|
||||
renderThumbnail(
|
||||
imageRow.doc._id,
|
||||
aName,
|
||||
imageRow.doc._attachments[aName],
|
||||
showTags ? imageRow.doc.tags : []
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function renderAlbum(indexRow) {
|
||||
const doc = indexRow.doc;
|
||||
const l = document.createElement('h2');
|
||||
l.innerText = indexRow.doc.props.title;
|
||||
container.appendChild(l);
|
||||
|
||||
const albumContainer = document.createElement('div');
|
||||
container.appendChild(albumContainer);
|
||||
|
||||
const results = await image.find(doc.members, { attachments: true });
|
||||
results.rows.filter(i => i.doc).forEach(i => renderImage(i, albumContainer, false));
|
||||
}
|
||||
|
||||
async function render() {
|
||||
container.innerHTML = '';
|
||||
|
||||
if (displaySelector.value === 'i') {
|
||||
header.innerText = 'Images';
|
||||
const results = await image.find({ attachments: true });
|
||||
results.rows.forEach(i => renderImage(i, container));
|
||||
} else {
|
||||
header.innerText = 'Albums';
|
||||
const results = await index.find({ attachments: true });
|
||||
results.rows.forEach(renderAlbum);
|
||||
}
|
||||
|
||||
Array.from(document.querySelectorAll('.image')).forEach(i => {
|
||||
const b = document.createElement('button');
|
||||
@ -64,4 +96,6 @@ db.allDocs({ include_docs: true, attachments: true }).then(async results => {
|
||||
b.textContent = '+';
|
||||
i.appendChild(b);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
render();
|
||||
|
||||
@ -3,7 +3,7 @@ import * as index from '../data/indexType.js';
|
||||
|
||||
export async function add(title, imageId, visible = true) {
|
||||
const trimmedTitle = title.trim();
|
||||
await index.add(trimmedTitle, [imageId]);
|
||||
await index.add(trimmedTitle, { title: trimmedTitle }, [imageId]);
|
||||
return image.update(imageId, {
|
||||
tags: { [trimmedTitle]: visible }
|
||||
});
|
||||
@ -14,3 +14,7 @@ export async function remove(title, imageId) {
|
||||
await image.update(imageId, { tags: { [title]: undefined } });
|
||||
await index.removeMember(title, imageId);
|
||||
}
|
||||
|
||||
image.removed.subscribe(image => {
|
||||
Object.keys(image.tags).forEach(t => index.removeMember(t, image._id));
|
||||
});
|
||||
|
||||
@ -8,13 +8,26 @@ import { Event, backgroundTask } from '../utils/event.js';
|
||||
|
||||
const db = getDatabase();
|
||||
const PROCESS_PREFIX = 'importing';
|
||||
const PREFIX = 'image';
|
||||
|
||||
// Events
|
||||
export const imported = new Event('Image.imported');
|
||||
export const removed = new Event('Image.removed');
|
||||
|
||||
// Methods
|
||||
const getId = id => (id.startsWith(PREFIX) ? id : `${PREFIX}_${id}`);
|
||||
|
||||
export async function find(keys, options = {}) {
|
||||
return await db.allDocs(Object.assign({ include_docs: true }, options, { keys }));
|
||||
let opts = { include_docs: true };
|
||||
if (Array.isArray(keys)) {
|
||||
Object.assign(opts, options);
|
||||
opts.keys = keys.map(getId);
|
||||
} else {
|
||||
Object.assign(opts, keys);
|
||||
opts.startkey = `${PREFIX}_0`;
|
||||
opts.endkey = `${PREFIX}_\ufff0`;
|
||||
}
|
||||
return await db.allDocs(opts);
|
||||
}
|
||||
|
||||
export async function add(imageFileList) {
|
||||
@ -45,6 +58,9 @@ export async function remove(ids, rev) {
|
||||
try {
|
||||
const doc = rev ? { _id: ids, _rev: rev } : await db.get(ids);
|
||||
await db.remove(doc);
|
||||
if (doc._id.startsWith(PREFIX)) {
|
||||
removed.fire(doc);
|
||||
}
|
||||
return true;
|
||||
} catch (e) {
|
||||
if (e.status !== 404) {
|
||||
@ -76,8 +92,8 @@ export async function addAttachment(doc, key, blob) {
|
||||
// Internal Functions
|
||||
const processImportables = backgroundTask(async function _processImportables() {
|
||||
const result = await db.allDocs({
|
||||
startkey: `${PROCESS_PREFIX}_0`,
|
||||
endkey: `${PROCESS_PREFIX}_z`,
|
||||
startkey: `${PROCESS_PREFIX}_`,
|
||||
endkey: `${PROCESS_PREFIX}_\ufff0`,
|
||||
include_docs: true,
|
||||
attachments: true,
|
||||
binary: true,
|
||||
@ -97,7 +113,7 @@ const processImportables = backgroundTask(async function _processImportables() {
|
||||
tags.DateTimeOriginal ? new Date(tags.DateTimeOriginal * 1000).toISOString() : doc.modifiedDate
|
||||
);
|
||||
const { _id, _rev } = doc;
|
||||
const id = `image_${originalDate.getTime().toString(36)}_${digest.substr(0, 6)}`;
|
||||
const id = `${PREFIX}_${originalDate.getTime().toString(36)}_${digest.substr(0, 6)}`;
|
||||
|
||||
let continueProcessing = true;
|
||||
try {
|
||||
|
||||
@ -13,13 +13,23 @@ export const hashString = name =>
|
||||
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) }));
|
||||
let opts = { include_docs: true };
|
||||
if (Array.isArray(keys)) {
|
||||
Object.assign(opts, options);
|
||||
opts.keys = keys.map(getId);
|
||||
} else {
|
||||
Object.assign(opts, keys);
|
||||
opts.startkey = `${PREFIX}_`;
|
||||
opts.endkey = `${PREFIX}_\ufff0`;
|
||||
}
|
||||
return await db.allDocs(opts);
|
||||
}
|
||||
|
||||
export async function add(id, members = []) {
|
||||
export async function add(id, props = {}, members = []) {
|
||||
const _id = getId(id);
|
||||
const [results, created] = await getOrCreate({
|
||||
_id,
|
||||
props,
|
||||
members: []
|
||||
});
|
||||
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
<body>
|
||||
<div>
|
||||
Images
|
||||
<input id='fInput' type="file" multiple accept="image/jpeg"/>
|
||||
</div>
|
||||
<select id='display' value='i'>
|
||||
<option value='i'>Images</option>
|
||||
<option value='a'>Albums</option>
|
||||
</select>
|
||||
<h1></h1>
|
||||
<div id='app'></div>
|
||||
</body>
|
||||
|
||||
<script src="/assets/app.bundle.js"></script>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user