Gallery -> DOMVM GalleryView
The whole app is converted to be base in DOMVM now. But there are bugs.
This commit is contained in:
parent
ccfd757aed
commit
e1c1c0e18a
@ -21,6 +21,7 @@
|
||||
"pouchdb-binary-utils": "~6.1.2",
|
||||
"pouchdb-core": "~6.1.2",
|
||||
"pouchdb-replication": "~6.1.2",
|
||||
"router": "2.0.0",
|
||||
"webpack": "^2.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@ -1,68 +1,50 @@
|
||||
import { createView } from 'domvm';
|
||||
import { createView } from 'domvm/dist/dev/domvm.dev.js';
|
||||
|
||||
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 generateThumbnails from './contextLoaders/generateThumbnails.js';
|
||||
import { ImageView } from './interface/image.js';
|
||||
import { AlbumView } from './interface/album.js';
|
||||
import { GalleryView } from './interface/gallery.js';
|
||||
import { router, routeChanged } from './services/router.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');
|
||||
|
||||
// Events
|
||||
displaySelector.onchange = refresh;
|
||||
document.querySelector('#fInput').onchange = async evt => {
|
||||
image.add(evt.currentTarget.files);
|
||||
const NAV_OPTIONS = {
|
||||
images: {
|
||||
model: image,
|
||||
title: 'Images'
|
||||
},
|
||||
albums: {
|
||||
model: index,
|
||||
title: 'Albums'
|
||||
}
|
||||
};
|
||||
|
||||
// To test the output:
|
||||
function refresh() {
|
||||
setTimeout(render, 100);
|
||||
}
|
||||
|
||||
async function render() {
|
||||
container.innerHTML = '';
|
||||
|
||||
if (displaySelector.value === 'i') {
|
||||
header.innerText = 'Images';
|
||||
const results = await image.find({ attachments: true });
|
||||
results.rows.forEach(i => {
|
||||
createView(ImageView, {
|
||||
imageRow: i,
|
||||
imageContainer: container,
|
||||
showTags: true,
|
||||
remove: image.remove,
|
||||
removeTag: imageTag.remove
|
||||
}).mount(container);
|
||||
});
|
||||
} else {
|
||||
header.innerText = 'Albums';
|
||||
const results = await index.find({ attachments: true });
|
||||
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);
|
||||
b.textContent = '+';
|
||||
i.appendChild(b);
|
||||
async function update(route) {
|
||||
const o = NAV_OPTIONS[route.name];
|
||||
gallery.update({
|
||||
title: o.title,
|
||||
members: (await o.model.find({ attachments: true })).rows
|
||||
});
|
||||
}
|
||||
function redraw() {
|
||||
update(router.current());
|
||||
}
|
||||
function onRouteChange(router, route) {
|
||||
update(route);
|
||||
}
|
||||
|
||||
render();
|
||||
image.imported.subscribe(generateThumbnails);
|
||||
image.imported.subscribe(redraw);
|
||||
image.removed.subscribe(redraw);
|
||||
index.added.subscribe(redraw);
|
||||
index.removed.subscribe(redraw);
|
||||
routeChanged.subscribe(onRouteChange);
|
||||
|
||||
const gallery = createView(GalleryView, {
|
||||
title: '',
|
||||
members: []
|
||||
}).mount(document.querySelector('#app'));
|
||||
|
||||
router.start('home');
|
||||
|
||||
@ -5,12 +5,6 @@
|
||||
<link rel="stylesheet" href="">
|
||||
</head>
|
||||
<body>
|
||||
<input id='fInput' type="file" multiple accept="image/jpeg"/>
|
||||
<select id='display' value='i'>
|
||||
<option value='i'>Images</option>
|
||||
<option value='a'>Albums</option>
|
||||
</select>
|
||||
<h1></h1>
|
||||
<div id='app'></div>
|
||||
<script src="/assets/app.bundle.js"></script>
|
||||
</body>
|
||||
|
||||
@ -8,9 +8,10 @@ export function AlbumView(vm, model) {
|
||||
const title = props.title;
|
||||
let images = [];
|
||||
|
||||
// FIXME - If the album is updated, this does not properly refresh.
|
||||
image.find(members, { attachments: true }).then(res => {
|
||||
images = res.rows.filter(i => i.doc);
|
||||
vm.redraw(true);
|
||||
vm.redraw();
|
||||
});
|
||||
|
||||
function removeImageFromAlbum(id, rev) {
|
||||
@ -21,11 +22,15 @@ export function AlbumView(vm, model) {
|
||||
return el('.album', [
|
||||
el('h2', [title]),
|
||||
...images.map(i => {
|
||||
return defineView(ImageView, {
|
||||
imageRow: i,
|
||||
showTags: false,
|
||||
remove: removeImageFromAlbum
|
||||
});
|
||||
return defineView(
|
||||
ImageView,
|
||||
{
|
||||
imageRow: i,
|
||||
showTags: false,
|
||||
remove: removeImageFromAlbum
|
||||
},
|
||||
i._id
|
||||
);
|
||||
})
|
||||
]);
|
||||
};
|
||||
|
||||
53
packages/gallery/src/interface/gallery.js
Normal file
53
packages/gallery/src/interface/gallery.js
Normal file
@ -0,0 +1,53 @@
|
||||
import { defineView, defineElement as el } from 'domvm';
|
||||
import * as image from '../data/image.js';
|
||||
import * as imageTag from '../context/manageImageTags.js';
|
||||
import { ImageView } from './image.js';
|
||||
import { AlbumView } from './album.js';
|
||||
import { router } from '../services/router.js';
|
||||
|
||||
export function GalleryView(vm, model) {
|
||||
function uploadImages(evt) {
|
||||
image.add(evt.currentTarget.files);
|
||||
}
|
||||
|
||||
return function(vm, model, key, opts) {
|
||||
const { title, members } = model;
|
||||
|
||||
return el('.gallery', [
|
||||
el('input#fInput', {
|
||||
type: 'file',
|
||||
multiple: true,
|
||||
accept: 'image/jpeg',
|
||||
onchange: uploadImages
|
||||
}),
|
||||
el('a', { href: router.href('images') }, 'Images'),
|
||||
el('a', { href: router.href('albums') }, 'Albums'),
|
||||
el('h1', title),
|
||||
...(title === 'Images'
|
||||
? members.map(i => {
|
||||
return defineView(
|
||||
ImageView,
|
||||
{
|
||||
imageRow: i,
|
||||
showTags: true,
|
||||
addTag: imageTag.add,
|
||||
remove: image.remove,
|
||||
removeTag: imageTag.remove
|
||||
},
|
||||
i._id
|
||||
);
|
||||
})
|
||||
: members.map(a => {
|
||||
return defineView(
|
||||
AlbumView,
|
||||
{
|
||||
albumRow: a,
|
||||
addTag: imageTag.add,
|
||||
remove: imageTag.remove
|
||||
},
|
||||
a._id
|
||||
);
|
||||
}))
|
||||
]);
|
||||
};
|
||||
}
|
||||
@ -2,8 +2,14 @@ import { defineView, defineElement as el } from 'domvm';
|
||||
import { ThumbnailView } from './thumbnail.js';
|
||||
|
||||
export function ImageView(vm, model) {
|
||||
const { addTag } = model;
|
||||
|
||||
function onAddTag(image_id) {
|
||||
addTag(prompt('Tag Name'), image_id);
|
||||
}
|
||||
|
||||
return function(vm, model, key, opts) {
|
||||
const { imageRow, showTags, remove, removeTag } = model;
|
||||
const { imageRow, showTags, remove, addTag, removeTag } = model;
|
||||
const { doc } = imageRow;
|
||||
const { thumbnail } = doc._attachments;
|
||||
const _showTags = showTags !== undefined ? showTags : true;
|
||||
@ -18,7 +24,8 @@ export function ImageView(vm, model) {
|
||||
tags: _showTags ? doc.tags : [],
|
||||
remove: remove,
|
||||
removeTag: removeTag
|
||||
})
|
||||
}),
|
||||
addTag ? el('button', { onclick: [onAddTag, doc._id] }, '+') : null
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
import { defineElement as el } from 'domvm';
|
||||
|
||||
export function ThumbnailView(vm, model) {
|
||||
const { remove, removeTag } = model;
|
||||
|
||||
return function(vm, model, key, opts) {
|
||||
const { id, rev, name, doc, tags } = model;
|
||||
const { id, rev, name, doc, tags, remove, removeTag } = model;
|
||||
const filteredTags = Object.entries(tags).filter(([_, visible]) => visible);
|
||||
|
||||
return el(`figure#${id}.image`, [
|
||||
|
||||
31
packages/gallery/src/services/router.js
Normal file
31
packages/gallery/src/services/router.js
Normal file
@ -0,0 +1,31 @@
|
||||
import { Router } from 'router';
|
||||
import { Event } from '../utils/event.js';
|
||||
|
||||
export const routeChanged = new Event('Router.newRoute');
|
||||
|
||||
const fire = routeChanged.fire.bind(routeChanged);
|
||||
|
||||
export const router = Router([
|
||||
{
|
||||
name: 'home',
|
||||
path: '/',
|
||||
enter: (r, route) => {
|
||||
r.goto('images');
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'images',
|
||||
path: '/images',
|
||||
enter: fire
|
||||
},
|
||||
{
|
||||
name: 'albums',
|
||||
path: '/albums',
|
||||
enter: fire
|
||||
},
|
||||
{
|
||||
id: '404',
|
||||
path: ':vars',
|
||||
enter: r => r.goto('home')
|
||||
}
|
||||
]);
|
||||
@ -14,5 +14,10 @@ module.exports = {
|
||||
devServer: {
|
||||
contentBase: path.resolve(__dirname, './src')
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
__DEV__: true
|
||||
})
|
||||
],
|
||||
devtool: 'source-map'
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user