Split photos view to a separate view
This commit is contained in:
parent
81a2e6e845
commit
db4474cdab
67
packages/gallery/src/interface/allImages.js
Normal file
67
packages/gallery/src/interface/allImages.js
Normal 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())));
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -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: { visibility: /* selectMode */ true ? 'visible' : 'hidden' }
|
css: { boxShadow: showDropShadow() ? '0px 0px 7px gray' : 'none' }
|
||||||
},
|
},
|
||||||
renderButtons()()
|
[el('div', { style: 'font-size: 20pt' }, title), headerRight(renderButtons()())]
|
||||||
)
|
);
|
||||||
]);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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...')]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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',
|
||||||
|
|||||||
@ -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()) } });
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user