Album -> DOMVM AlbumView

This commit is contained in:
Timothy Farrell 2017-09-27 12:27:25 -05:00
parent da9e699df4
commit ccfd757aed
6 changed files with 68 additions and 61 deletions

View File

@ -6,16 +6,19 @@ import { getDatabase } from './services/db.js';
import * as imageTag from './context/manageImageTags.js';
import generateThumbnails from './contextLoaders/generateThumbnails.js';
import { ImageView } from './interface/image.js';
import { AlbumView } from './interface/album.js';
window.__DEV__ = true;
window.db = getDatabase();
image.imported.subscribe(refresh);
image.imported.subscribe(generateThumbnails);
image.removed.subscribe(refresh);
index.added.subscribe(refresh);
index.removed.subscribe(refresh);
const header = document.querySelector('h1');
const container = document.querySelector('#app');
const displaySelector = document.querySelector('#display');
image.removed.subscribe(refresh);
// Events
displaySelector.onchange = refresh;
@ -28,27 +31,6 @@ function refresh() {
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() {
container.innerHTML = '';
@ -67,12 +49,17 @@ async function render() {
} else {
header.innerText = 'Albums';
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 => {
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 = '+';
i.appendChild(b);
});

View File

@ -51,26 +51,12 @@ export async function add(imageFileList) {
return docs.filter((d, i) => results[i].ok);
}
export async function remove(ids, rev) {
if (!Array.isArray(ids)) {
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) {
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 remove(ids) {
const docs = await find(Array.isArray(ids) ? ids : [ids]);
const foundDocs = docs.rows.filter(r => !r.error);
const result = await db.bulkDocs(foundDocs.map(r => Object.assign(r.doc, { _deleted: true })));
foundDocs.filter((_, i) => result[i].ok).map(r => removed.fire(r.doc));
return result.reduce((a, r) => a && r.ok, true);
}
export async function update(id, properties) {
@ -162,6 +148,6 @@ const processImportables = backgroundTask(async function _processImportables() {
imported.fire(id, _id, false);
}
remove(_id, _rev);
await db.remove({ _id, _rev });
processImportables();
});

View File

@ -1,9 +1,14 @@
import { log, error } from '../services/console.js';
import { getDatabase, getOrCreate } from '../services/db.js';
import { Event } from '../utils/event.js';
const db = getDatabase();
const PREFIX = 'index';
// Events
export const added = new Event('Index.added');
export const removed = new Event('Index.removed');
// Methods
export const hashString = name =>
name
@ -47,6 +52,7 @@ export async function addMember(id, member) {
if (doc.members.indexOf(member) === -1) {
doc.members.push(member);
await db.put(doc);
added.fire(doc._id, member);
}
return doc;
@ -61,8 +67,10 @@ export async function removeMember(id, member) {
if (doc.members.length > 1) {
doc.members.splice(idx, 1);
await db.put(doc);
removed.fire(doc._id, member);
} else {
await db.remove(doc);
removed.fire(doc._id, member);
}
}
}

View 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
});
})
]);
};
}

View File

@ -3,17 +3,19 @@ import { ThumbnailView } from './thumbnail.js';
export function ImageView(vm, model) {
return function(vm, model, key, opts) {
const { imageRow, imageContainer, showTags, remove, removeTag } = model;
const { thumbnail } = imageRow.doc._attachments;
const { imageRow, showTags, remove, removeTag } = model;
const { doc } = imageRow;
const { thumbnail } = doc._attachments;
const _showTags = showTags !== undefined ? showTags : true;
if (thumbnail) {
return el('div', [
defineView(ThumbnailView, {
id: imageRow.doc._id,
id: doc._id,
rev: doc._rev,
name: 'thumbnail',
doc: thumbnail,
tags: _showTags ? imageRow.doc.tags : [],
tags: _showTags ? doc.tags : [],
remove: remove,
removeTag: removeTag
})

View File

@ -1,12 +1,10 @@
import { defineElement as el } from 'domvm';
export function ThumbnailView(vm, model) {
function onclick(evt) {
model.remove(evt.currentTarget.dataset.id); // .then(refresh);
}
const { remove, removeTag } = model;
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);
return el(`figure#${id}.image`, [
@ -14,18 +12,12 @@ export function ThumbnailView(vm, model) {
src: `data:${doc.content_type};base64,${doc.data}`,
title: `${id} ${name}`,
'data-id': id,
onclick
onclick: [remove, id, rev]
}),
filteredTags.length
? el(
'figcaption',
filteredTags.map(([title, _]) =>
el(
'span.tag',
{ onclick: evt => model.removeTag(title, id) }, // .then(refresh)
[title]
)
)
filteredTags.map(([title, _]) => el('span.tag', { onclick: [removeTag, title, id] }, [title]))
)
: null
]);