Split photos view to a separate view

This commit is contained in:
Timothy Farrell 2017-12-01 01:12:23 -06:00
parent dba6f3c204
commit ff281dc3e2
6 changed files with 113 additions and 102 deletions

View File

@ -0,0 +1,67 @@
import { prop, computed } from 'frptools';
import { subscribeToRender, defineView, defineElement as el } from '../utils/domvm.js';
import { ImageType } from '../data/image.js';
import { pouchDocArrayHash, pouchDocHash } from '../utils/conversion.js';
import { ThumbnailTemplate } from './thumbnail.js';
import { injectStyle, styled } from '../services/style.js';
export function uploadImages(evt, files) {
Array.from(files || evt.currentTarget.files).forEach(ImageType.upload);
if (evt.currentTarget) {
evt.currentTarget.value = null;
}
}
export function AllImagesView(vm, params, key, opts) {
const model = prop({}, pouchDocHash);
const images = prop([], pouchDocArrayHash);
ImageType.find(
{
['sizes.thumbnail']: { $exists: true }
},
true
).then(la => {
opts.appbar.renderButtons(renderAppBarButtons);
subscribeToRender(vm, [images], [la.subscribe(images)]);
});
function renderAppBarButtons() {
return [
el('button', [el('label', { for: 'uploadButton' }, 'Upload')]),
el('input', {
id: 'uploadButton',
name: 'uploadButton',
type: 'file',
multiple: true,
accept: '.png,.jpg,.jpeg', // no love for gifs yet
onchange: uploadImages,
class: injectStyle({ display: 'none' })
})
];
}
function deleteImage(i) {
ImageType.delete(i._id);
}
function addAlbum() {
const albumName = prompt('Album Name');
if (albumName && albumName.trim()) {
const a = new AlbumType({
title: albumName.trim(),
count: 0
});
a.save();
}
}
return function() {
const album = model();
return el('div', images().map(i => ThumbnailTemplate(i, deleteImage, i._hash())));
};
}

View File

@ -1,26 +1,33 @@
import { defineElement as el } from '../../utils/domvm.js';
import { prop, computed, bundle } from 'frptools'; import { prop, computed, bundle } from 'frptools';
import { defineElement as el } from '../../utils/domvm.js';
import { injectStyle, styled } from '../../services/style.js'; import { injectStyle, styled } from '../../services/style.js';
export function AppBarView(vm, params, key, opts) { export function AppBarView(vm, params, key, opts) {
const title = prop(params.title);
const renderButtons = prop(params.renderButtons || (() => []));
const hasBackButton = prop(false);
const showDropShadow = prop(false);
if (opts.appbar) { if (opts.appbar) {
throw new Error('Cannot have more than one AppBar.'); throw new Error('Cannot have more than one AppBar.');
} }
const title = prop(params.title); opts.appbar = {
const renderButtons = prop(params.renderButtons); title,
renderButtons,
hasBackButton,
showDropShadow
};
return (vm, params) => { return (vm, params) => {
const { title } = params; const { title } = params;
return header([ return header(
el('div', { style: 'font-size: 20pt' }, title), {
headerRight( css: { boxShadow: showDropShadow() ? '0px 0px 7px gray' : 'none' }
{ },
css: { visibility: /* selectMode */ true ? 'visible' : 'hidden' } [el('div', { style: 'font-size: 20pt' }, title), headerRight(renderButtons()())]
}, );
renderButtons()()
)
]);
}; };
} }

View File

@ -24,7 +24,7 @@ export function AttachmentImageView(vm, params) {
}); });
async function loadImageFromBlob() { async function loadImageFromBlob() {
const options = ['thumbnail', 'full'].filter(o => sizes().hasOwnProperty(o)); const options = ['thumbnail', 'preview', 'full'].filter(o => sizes().hasOwnProperty(o));
for (let attempt of options) { for (let attempt of options) {
try { try {

View File

@ -1,75 +1,37 @@
import { prop } from 'frptools'; import { prop } from 'frptools';
import { defineView as vw, defineElement as el } from '../utils/domvm.js'; import { subscribeToRender, defineView as vw, defineElement as el } from '../utils/domvm.js';
import { ImageType } from '../data/image.js'; import { ImageType } from '../data/image.js';
import { AlbumType } from '../data/album.js'; import { AlbumType } from '../data/album.js';
import { ThumbnailTemplate } from './thumbnail.js'; import { ThumbnailTemplate } from './thumbnail.js';
import { AlbumView } from './album.js'; import { AllImagesView, uploadImages } from './allImages.js';
import { Dropzone } from './components/dropzone.js'; import { Dropzone } from './components/dropzone.js';
import { Overlay } from './components/overlay.js'; import { Overlay } from './components/overlay.js';
import { AppBarView } from './components/appbar.js'; import { AppBarView } from './components/appbar.js';
import { Icon } from './components/icon.js'; import { Icon } from './components/icon.js';
import { router, routeChanged } from '../services/router.js'; import { routeChanged } from '../services/router.js';
import { injectStyle, styled } from '../services/style.js'; import { injectStyle } from '../services/style.js';
export function GalleryView(vm) { export function GalleryView(vm) {
const NAV_OPTIONS = {
images: {
data: ImageType.find(
{
['sizes.thumbnail']: { $exists: true }
},
true
),
title: 'Images'
},
albums: {
data: AlbumType.find({}, true),
title: 'Albums'
}
};
let data = null; let data = null;
let laCleanup = null; let laCleanup = null;
const context = {}; const context = {};
const title = prop(''); const title = prop('');
const hasData = prop(null);
function uploadImages(evt, files) { subscribeToRender(vm, [hasData]);
Array.from(files || evt.currentTarget.files).forEach(ImageType.upload);
if (evt.currentTarget) { routeChanged.subscribe(function onRouteChange(name, params) {
evt.currentTarget.value = null; if (name == 'photos') {
} title('Photos');
} ImageType.find({
['sizes.thumbnail']: { $exists: true }
function deleteImage(i) { }).then(results => {
ImageType.delete(i._id); hasData(results.length > 0);
}
function addAlbum() {
const albumName = prompt('Album Name');
if (albumName && albumName.trim()) {
const a = new AlbumType({
title: albumName.trim(),
count: 0
}); });
a.save(); } else {
throw new Error('Should not happen');
} }
}
routeChanged.subscribe(function onRouteChange(router, route) {
if (laCleanup) {
laCleanup();
}
const o = NAV_OPTIONS[route.name];
title(o.title);
return o.data.then(la => {
data = la;
laCleanup = data.subscribe(() => {
vm.redraw();
});
});
}); });
function renderWelcomePane() { function renderWelcomePane() {
@ -88,28 +50,12 @@ export function GalleryView(vm) {
]; ];
} }
function renderAppBarButtons() {
return [
el('button', [el('label', { for: 'uploadButton' }, 'Upload')]),
el('input', {
id: 'uploadButton',
name: 'uploadButton',
type: 'file',
multiple: true,
accept: '.png,.jpg,.jpeg', // no love for gifs yet
onchange: uploadImages,
class: injectStyle({ display: 'none' })
})
];
}
function renderMain() { function renderMain() {
return [ return [
vw( vw(
AppBarView, AppBarView,
{ {
title: 'Photos', title: 'Photos'
renderButtons: renderAppBarButtons
}, },
'appbar', 'appbar',
context context
@ -117,17 +63,13 @@ export function GalleryView(vm) {
el( el(
'div', 'div',
{ class: fill }, { class: fill },
data().length hasData() ? [vw(AllImagesView, {}, 'allImages', context)] : [renderWelcomePane()]
? data().map(i => {
return ThumbnailTemplate(i, deleteImage, i._hash());
})
: [renderWelcomePane()]
) )
]; ];
} }
return function render() { return function render() {
if (!data || !data.ready()) { if (hasData() === null) {
return Overlay([el('h1', 'Loading...')]); return Overlay([el('h1', 'Loading...')]);
} }

View File

@ -9,19 +9,7 @@ export const router = Router([
{ {
name: 'home', name: 'home',
path: '/', path: '/',
enter: (r, route) => { enter: (r, route) => fire('photos', route)
r.goto('images');
}
},
{
name: 'images',
path: '/images',
enter: fire
},
{
name: 'albums',
path: '/albums',
enter: fire
}, },
{ {
id: '404', id: '404',

View File

@ -1,2 +1,9 @@
// export * from 'domvm/dist/dev/domvm.dev.js'; // export * from 'domvm/dist/dev/domvm.dev.js';
export * from 'domvm/dist/mini/domvm.mini.js'; export * from 'domvm/dist/mini/domvm.mini.js';
export function subscribeToRender(vm, subscribables, subscriptions) {
const redraw = () => vm.redraw();
const subList = subscribables.map(s => s.subscribe(redraw)).concat(subscriptions);
vm.config({ hooks: { willUnmount: () => subList.forEach(s => s()) } });
}