Album -> DOMVM AlbumView
This commit is contained in:
parent
da9e699df4
commit
ccfd757aed
@ -6,16 +6,19 @@ import { getDatabase } from './services/db.js';
|
|||||||
import * as imageTag from './context/manageImageTags.js';
|
import * as imageTag from './context/manageImageTags.js';
|
||||||
import generateThumbnails from './contextLoaders/generateThumbnails.js';
|
import generateThumbnails from './contextLoaders/generateThumbnails.js';
|
||||||
import { ImageView } from './interface/image.js';
|
import { ImageView } from './interface/image.js';
|
||||||
|
import { AlbumView } from './interface/album.js';
|
||||||
|
|
||||||
window.__DEV__ = true;
|
window.__DEV__ = true;
|
||||||
window.db = getDatabase();
|
window.db = getDatabase();
|
||||||
|
|
||||||
image.imported.subscribe(refresh);
|
image.imported.subscribe(refresh);
|
||||||
image.imported.subscribe(generateThumbnails);
|
image.imported.subscribe(generateThumbnails);
|
||||||
|
image.removed.subscribe(refresh);
|
||||||
|
index.added.subscribe(refresh);
|
||||||
|
index.removed.subscribe(refresh);
|
||||||
const header = document.querySelector('h1');
|
const header = document.querySelector('h1');
|
||||||
const container = document.querySelector('#app');
|
const container = document.querySelector('#app');
|
||||||
const displaySelector = document.querySelector('#display');
|
const displaySelector = document.querySelector('#display');
|
||||||
image.removed.subscribe(refresh);
|
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
displaySelector.onchange = refresh;
|
displaySelector.onchange = refresh;
|
||||||
@ -28,27 +31,6 @@ function refresh() {
|
|||||||
setTimeout(render, 100);
|
setTimeout(render, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 => {
|
|
||||||
createView(ImageView, {
|
|
||||||
imageRow: i,
|
|
||||||
imageContainer: albumContainer,
|
|
||||||
showTags: false,
|
|
||||||
remove: image.remove,
|
|
||||||
removeTag: imageTag.remove
|
|
||||||
}).mount(albumContainer);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function render() {
|
async function render() {
|
||||||
container.innerHTML = '';
|
container.innerHTML = '';
|
||||||
|
|
||||||
@ -67,12 +49,17 @@ async function render() {
|
|||||||
} else {
|
} else {
|
||||||
header.innerText = 'Albums';
|
header.innerText = 'Albums';
|
||||||
const results = await index.find({ attachments: true });
|
const results = await index.find({ attachments: true });
|
||||||
results.rows.forEach(renderAlbum);
|
results.rows.forEach(i => {
|
||||||
|
createView(AlbumView, {
|
||||||
|
albumRow: i,
|
||||||
|
remove: imageTag.remove
|
||||||
|
}).mount(container);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Array.from(document.querySelectorAll('.image')).forEach(i => {
|
Array.from(document.querySelectorAll('.image')).forEach(i => {
|
||||||
const b = document.createElement('button');
|
const b = document.createElement('button');
|
||||||
b.onclick = evt => imageTag.add(prompt('Tag Name'), i.id).then(refresh);
|
b.onclick = evt => imageTag.add(prompt('Tag Name'), i.id);
|
||||||
b.textContent = '+';
|
b.textContent = '+';
|
||||||
i.appendChild(b);
|
i.appendChild(b);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -51,26 +51,12 @@ export async function add(imageFileList) {
|
|||||||
return docs.filter((d, i) => results[i].ok);
|
return docs.filter((d, i) => results[i].ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function remove(ids, rev) {
|
export async function remove(ids) {
|
||||||
if (!Array.isArray(ids)) {
|
const docs = await find(Array.isArray(ids) ? ids : [ids]);
|
||||||
try {
|
const foundDocs = docs.rows.filter(r => !r.error);
|
||||||
const doc = rev ? { _id: ids, _rev: rev } : await db.get(ids);
|
const result = await db.bulkDocs(foundDocs.map(r => Object.assign(r.doc, { _deleted: true })));
|
||||||
await db.remove(doc);
|
foundDocs.filter((_, i) => result[i].ok).map(r => removed.fire(r.doc));
|
||||||
if (doc._id.startsWith(PREFIX)) {
|
return result.reduce((a, r) => a && r.ok, true);
|
||||||
removed.fire(doc);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} catch (e) {
|
|
||||||
if (e.status !== 404) {
|
|
||||||
error(`Error removing Image ${_id}`, e);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const docs = await find(ids);
|
|
||||||
const result = await db.bulkDocs(docs.rows.map(r => Object.assign(r.doc, { _deleted: true })));
|
|
||||||
return result.map(r => r.ok);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function update(id, properties) {
|
export async function update(id, properties) {
|
||||||
@ -162,6 +148,6 @@ const processImportables = backgroundTask(async function _processImportables() {
|
|||||||
imported.fire(id, _id, false);
|
imported.fire(id, _id, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(_id, _rev);
|
await db.remove({ _id, _rev });
|
||||||
processImportables();
|
processImportables();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,9 +1,14 @@
|
|||||||
import { log, error } from '../services/console.js';
|
import { log, error } from '../services/console.js';
|
||||||
import { getDatabase, getOrCreate } from '../services/db.js';
|
import { getDatabase, getOrCreate } from '../services/db.js';
|
||||||
|
import { Event } from '../utils/event.js';
|
||||||
|
|
||||||
const db = getDatabase();
|
const db = getDatabase();
|
||||||
const PREFIX = 'index';
|
const PREFIX = 'index';
|
||||||
|
|
||||||
|
// Events
|
||||||
|
export const added = new Event('Index.added');
|
||||||
|
export const removed = new Event('Index.removed');
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
export const hashString = name =>
|
export const hashString = name =>
|
||||||
name
|
name
|
||||||
@ -47,6 +52,7 @@ export async function addMember(id, member) {
|
|||||||
if (doc.members.indexOf(member) === -1) {
|
if (doc.members.indexOf(member) === -1) {
|
||||||
doc.members.push(member);
|
doc.members.push(member);
|
||||||
await db.put(doc);
|
await db.put(doc);
|
||||||
|
added.fire(doc._id, member);
|
||||||
}
|
}
|
||||||
|
|
||||||
return doc;
|
return doc;
|
||||||
@ -61,8 +67,10 @@ export async function removeMember(id, member) {
|
|||||||
if (doc.members.length > 1) {
|
if (doc.members.length > 1) {
|
||||||
doc.members.splice(idx, 1);
|
doc.members.splice(idx, 1);
|
||||||
await db.put(doc);
|
await db.put(doc);
|
||||||
|
removed.fire(doc._id, member);
|
||||||
} else {
|
} else {
|
||||||
await db.remove(doc);
|
await db.remove(doc);
|
||||||
|
removed.fire(doc._id, member);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
packages/gallery/src/interface/album.js
Normal file
32
packages/gallery/src/interface/album.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { defineView, defineElement as el } from 'domvm';
|
||||||
|
import * as image from '../data/image.js';
|
||||||
|
import { ImageView } from './image.js';
|
||||||
|
|
||||||
|
export function AlbumView(vm, model) {
|
||||||
|
const { albumRow, remove } = model;
|
||||||
|
const { props, members } = albumRow.doc;
|
||||||
|
const title = props.title;
|
||||||
|
let images = [];
|
||||||
|
|
||||||
|
image.find(members, { attachments: true }).then(res => {
|
||||||
|
images = res.rows.filter(i => i.doc);
|
||||||
|
vm.redraw(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
function removeImageFromAlbum(id, rev) {
|
||||||
|
remove(title, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return function(vm, model, key, opts) {
|
||||||
|
return el('.album', [
|
||||||
|
el('h2', [title]),
|
||||||
|
...images.map(i => {
|
||||||
|
return defineView(ImageView, {
|
||||||
|
imageRow: i,
|
||||||
|
showTags: false,
|
||||||
|
remove: removeImageFromAlbum
|
||||||
|
});
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -3,17 +3,19 @@ import { ThumbnailView } from './thumbnail.js';
|
|||||||
|
|
||||||
export function ImageView(vm, model) {
|
export function ImageView(vm, model) {
|
||||||
return function(vm, model, key, opts) {
|
return function(vm, model, key, opts) {
|
||||||
const { imageRow, imageContainer, showTags, remove, removeTag } = model;
|
const { imageRow, showTags, remove, removeTag } = model;
|
||||||
const { thumbnail } = imageRow.doc._attachments;
|
const { doc } = imageRow;
|
||||||
|
const { thumbnail } = doc._attachments;
|
||||||
const _showTags = showTags !== undefined ? showTags : true;
|
const _showTags = showTags !== undefined ? showTags : true;
|
||||||
|
|
||||||
if (thumbnail) {
|
if (thumbnail) {
|
||||||
return el('div', [
|
return el('div', [
|
||||||
defineView(ThumbnailView, {
|
defineView(ThumbnailView, {
|
||||||
id: imageRow.doc._id,
|
id: doc._id,
|
||||||
|
rev: doc._rev,
|
||||||
name: 'thumbnail',
|
name: 'thumbnail',
|
||||||
doc: thumbnail,
|
doc: thumbnail,
|
||||||
tags: _showTags ? imageRow.doc.tags : [],
|
tags: _showTags ? doc.tags : [],
|
||||||
remove: remove,
|
remove: remove,
|
||||||
removeTag: removeTag
|
removeTag: removeTag
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import { defineElement as el } from 'domvm';
|
import { defineElement as el } from 'domvm';
|
||||||
|
|
||||||
export function ThumbnailView(vm, model) {
|
export function ThumbnailView(vm, model) {
|
||||||
function onclick(evt) {
|
const { remove, removeTag } = model;
|
||||||
model.remove(evt.currentTarget.dataset.id); // .then(refresh);
|
|
||||||
}
|
|
||||||
|
|
||||||
return function(vm, model, key, opts) {
|
return function(vm, model, key, opts) {
|
||||||
const { id, name, doc, tags } = model;
|
const { id, rev, name, doc, tags } = model;
|
||||||
const filteredTags = Object.entries(tags).filter(([_, visible]) => visible);
|
const filteredTags = Object.entries(tags).filter(([_, visible]) => visible);
|
||||||
|
|
||||||
return el(`figure#${id}.image`, [
|
return el(`figure#${id}.image`, [
|
||||||
@ -14,18 +12,12 @@ export function ThumbnailView(vm, model) {
|
|||||||
src: `data:${doc.content_type};base64,${doc.data}`,
|
src: `data:${doc.content_type};base64,${doc.data}`,
|
||||||
title: `${id} ${name}`,
|
title: `${id} ${name}`,
|
||||||
'data-id': id,
|
'data-id': id,
|
||||||
onclick
|
onclick: [remove, id, rev]
|
||||||
}),
|
}),
|
||||||
filteredTags.length
|
filteredTags.length
|
||||||
? el(
|
? el(
|
||||||
'figcaption',
|
'figcaption',
|
||||||
filteredTags.map(([title, _]) =>
|
filteredTags.map(([title, _]) => el('span.tag', { onclick: [removeTag, title, id] }, [title]))
|
||||||
el(
|
|
||||||
'span.tag',
|
|
||||||
{ onclick: evt => model.removeTag(title, id) }, // .then(refresh)
|
|
||||||
[title]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
: null
|
: null
|
||||||
]);
|
]);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user