diff --git a/packages/gallery/package.json b/packages/gallery/package.json index 9e02f55..9f96566 100644 --- a/packages/gallery/package.json +++ b/packages/gallery/package.json @@ -17,6 +17,7 @@ "exif-parser": "~0.1.9", "extract-text-webpack-plugin": "^3.0.2", "frptools": "2.2.0", + "moment": "~2.19.3", "pica": "~2.0.8", "pouchdb-adapter-http": "~6.3.4", "pouchdb-adapter-idb": "~6.3.4", diff --git a/packages/gallery/src/interface/allImages.js b/packages/gallery/src/interface/allImages.js index 8a04ae6..4e032b1 100644 --- a/packages/gallery/src/interface/allImages.js +++ b/packages/gallery/src/interface/allImages.js @@ -1,3 +1,4 @@ +import * as moment from 'moment'; import { prop, computed, container } from 'frptools'; import { @@ -24,11 +25,28 @@ export function uploadImages(evt, files) { export function AllImagesView(vm, params, key, opts) { const model = prop({}, pouchDocHash); const images = container([], pouchDocArrayHash); - const visibleIds = computed(arr => arr.map(extractID), [images]); const hoverId = prop(null); const selectedIds = container(new Set(), hashSet); const mode = computed(sIds => (sIds.size > 0 ? 'select' : 'view'), [selectedIds]); + const sections = computed( + imageArr => { + const sectionMap = imageArr.reduce((acc, i) => { + const date = i.originalDate.substr(0, 10); + return Object.assign(acc, { [date]: (acc[date] || []).concat(i) }); + }, {}); + const res = Object.entries(sectionMap).reduce( + (acc, [date, sectionImages]) => + Object.assign(acc, { + [moment(date).format('LL')]: sectionImages + }), + {} + ); + return res; + }, + [images] + ); + ImageType.find( { ['sizes.thumbnail']: { $exists: true } @@ -92,15 +110,28 @@ export function AllImagesView(vm, params, key, opts) { } function toggleAll(evt, node, vm) { - if (images.length === selectedIds.size) { - selectedIds.clear(); + const sectionNode = nodeParentWithType(node, 'section'); + const { sectionImageIds } = sectionNode.data; + const selected = sectionImageIds.filter(i => selectedIds.has(i)); + if (sectionImageIds.length === selected.length) { + sectionImageIds.forEach(i => selectedIds.delete(i)); } else { - images.map(extractID).forEach(i => selectedIds.add(i)); + sectionImageIds.forEach(i => selectedIds.add(i)); } } subscribeToRender(vm, [selectedIds, images, hoverId, mode]); + function renderSection([title, _images]) { + return AlbumTemplate({ + title, + id: title, + photos: _images, + selectedIds, + mode: mode() + }); + } + return function() { return el( '.eventSnarfer', @@ -112,15 +143,7 @@ export function AllImagesView(vm, params, key, opts) { '.albumSelectButton .icon svg path': toggleAll } }, - [ - AlbumTemplate({ - title: 'Test', - id: 1, - photos: images, - selectedIds, - mode: mode() - }) - ] + Object.entries(sections()).map(renderSection) ); }; } diff --git a/packages/gallery/src/interface/components/albumTemplate.js b/packages/gallery/src/interface/components/albumTemplate.js index 07ca01e..d1c61e8 100644 --- a/packages/gallery/src/interface/components/albumTemplate.js +++ b/packages/gallery/src/interface/components/albumTemplate.js @@ -8,6 +8,7 @@ import { injectStyle, styled } from '../../services/style.js'; import { DEFAULT_TRANSITION } from '../styles.js'; import { Icon } from './icon.js'; import { AlbumPhotoTemplate } from './albumPhotoTemplate.js'; +import { extractID } from '../../utils/conversion.js'; export function AlbumTemplate(params) { const { id, title, photos, selectedIds, mode } = params; @@ -29,7 +30,11 @@ export function AlbumTemplate(params) { return Album( { onmouseenter: [patchRefStyle, albumSelectButtonRef, 'opacity: 0.7;'], - onmouseleave: [patchRefStyle, albumSelectButtonRef, 'opacity: 0;'] + onmouseleave: [patchRefStyle, albumSelectButtonRef, 'opacity: 0;'], + _data: { + type: 'section', + sectionImageIds: photos.map(extractID) + } }, [ albumTitle([