Initial FocusView

This commit is contained in:
Timothy Farrell 2017-12-28 22:14:46 -06:00
parent 9fd5efc4f9
commit e08db9bae0
6 changed files with 173 additions and 35 deletions

View File

@ -2,6 +2,7 @@ import { prop, computed, container } from 'frptools';
import { Icon } from './icon.js'; import { Icon } from './icon.js';
import { defineElement as el, subscribeToRender } from '../../utils/domvm.js'; import { defineElement as el, subscribeToRender } from '../../utils/domvm.js';
import { pick } from '../../utils/conversion.js';
import { injectStyle, styled } from '../../services/style.js'; import { injectStyle, styled } from '../../services/style.js';
import { CLICKABLE } from '../styles.js'; import { CLICKABLE } from '../styles.js';
@ -13,8 +14,9 @@ export function AppBarView(vm, params, key, opts) {
const companionScrollTop = prop(0); const companionScrollTop = prop(0);
const currentState = computed(stack => stack[0] || {}, [stateStack]); const currentState = computed(stack => stack[0] || {}, [stateStack]);
const title = computed(state => state.title || '', [currentState]); const title = computed(pick('title', ''), [currentState]);
const renderButtons = computed(state => state.buttons, [currentState]); const renderButtons = computed(pick('buttons'), [currentState]);
const stateStyle = computed(pick('style', {}), [currentState]);
const backButton = computed( const backButton = computed(
(state, stack) => (state, stack) =>
stack.length > 1 ? (state.backButton !== undefined ? state.backButton : 'arrow_left') : null, stack.length > 1 ? (state.backButton !== undefined ? state.backButton : 'arrow_left') : null,
@ -27,6 +29,13 @@ export function AppBarView(vm, params, key, opts) {
[companionScrollTop] [companionScrollTop]
); );
const containerStyle = computed(
(boxShadow, style) => ({
css: Object.assign({ boxShadow }, style)
}),
[boxShadowStyle, stateStyle]
);
if (opts.appbar) { if (opts.appbar) {
throw new Error('Cannot have more than one AppBar.'); throw new Error('Cannot have more than one AppBar.');
} }
@ -48,16 +57,12 @@ export function AppBarView(vm, params, key, opts) {
subscribe: stateChange.subscribe subscribe: stateChange.subscribe
}; };
subscribeToRender(vm, [boxShadowStyle, renderButtons, backButton, title]); subscribeToRender(vm, [containerStyle, renderButtons, backButton, title]);
return (vm, params) => { return (vm, params) => {
const _buttons = renderButtons() || (() => {}); const _buttons = renderButtons() || (() => {});
return header( return appBarContainer(containerStyle(), [
{
css: { boxShadow: boxShadowStyle() }
},
[
backButton() !== null backButton() !== null
? backButtonContainer( ? backButtonContainer(
{ {
@ -73,17 +78,17 @@ export function AppBarView(vm, params, key, opts) {
: null, : null,
titleContainer(title()), titleContainer(title()),
headerRight(_buttons()) headerRight(_buttons())
] ]);
);
}; };
} }
const header = styled({ const appBarContainer = styled({
justifyContent: 'space-between', justifyContent: 'space-between',
padding: '1em', padding: '1em',
zIndex: 1000, zIndex: 1000,
display: 'flex', display: 'flex',
alignItems: 'center' alignItems: 'center',
width: '100%'
}); });
const backButtonContainer = styled( const backButtonContainer = styled(

View File

@ -0,0 +1,132 @@
import { prop, computed, container } from 'frptools';
import {
subscribeToRender,
defineView,
nodeParentWithType,
defineElement as el
} from '../utils/domvm.js';
import { ImageType } from '../data/image.js';
import { pouchDocHash, pick } from '../utils/conversion.js';
import { AttachmentImageView } from './components/attachmentImage.js';
import { Overlay } from './components/overlay.js';
import { Icon } from './components/icon.js';
import { styled, injectStyle } from '../services/style.js';
import { error } from '../services/console.js';
import { CLICKABLE } from './styles.js';
export function FocusView(vm, params, key, { appbar }) {
const id = params.vars.id;
const { body } = document;
const windowSize = prop({}, o => (o ? `${o.width}x${o.height}` : ''));
const extractWindowSize = () =>
windowSize({ width: window.innerWidth, height: window.innerHeight });
const doc = container({}, pouchDocHash);
const imageStyle = computed(
({ width: iw, height: ih }, { width: vw, height: vh }) => {
const imageRatio = iw / ih;
const windowRatio = vw / vh;
if (windowRatio > imageRatio) {
return {
height: vw / windowRatio,
width: vw / windowRatio * imageRatio
};
} else {
return {
height: vh * windowRatio / imageRatio,
width: vh * windowRatio
};
}
},
[doc, windowSize]
);
async function goBack() {
history.go(-1);
}
function navBack() {
// appbar.popState();
goBack();
}
async function clickTrash() {
await ImageType.delete(id);
navBack();
}
function renderAppBarButtons() {
return [
trashButtonContainer(
{
onclick: clickTrash
},
[
Icon({
name: 'trash',
size: 0.75
})
]
)
];
}
// Prime our window size
extractWindowSize();
window.addEventListener('resize', extractWindowSize);
// Set the appbar title.
appbar.pushState({ title: '', buttons: renderAppBarButtons, style: { position: 'fixed' } });
// Look for our image and set it.
ImageType.find(id)
.then(d => {
doc.src = d.sizes.full || d.sizes.preview || d.sizes.thumbnail;
doc.width = d.width;
doc.height = d.height;
doc._id = d._id;
})
.catch(error);
// Subscribe to our changables.
subscribeToRender(
vm,
[doc, imageStyle],
[appbar.subscribe(goBack), () => window.removeEventListener('resize', extractWindowSize)]
);
return function() {
if (!doc._id) {
return Overlay('Loading...');
}
return focusContainer([
AttachmentImageView({
src: doc._id ? doc.src : null,
style: imageStyle()
})
]);
};
}
const trashButtonContainer = styled(
{
marginRight: '1em'
},
CLICKABLE
);
const focusContainer = styled({
display: 'flex',
flex: 1,
justifyContent: 'center',
alignItems: 'center',
overflow: 'hidden'
});
const WIDE = injectStyle({ width: '100%' });
const TALL = injectStyle({ height: '100%' });

View File

@ -12,6 +12,7 @@ import { ImageType } from '../data/image.js';
import { AlbumType } from '../data/album.js'; import { AlbumType } from '../data/album.js';
import { ThumbnailTemplate } from './components/thumbnail.js'; import { ThumbnailTemplate } from './components/thumbnail.js';
import { AllImagesView, uploadImages } from './allImages.js'; import { AllImagesView, uploadImages } from './allImages.js';
import { FocusView } from './focus.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';
@ -28,6 +29,7 @@ export function GalleryView(vm) {
routeChanged.subscribe(function onRouteChange(name, params) { routeChanged.subscribe(function onRouteChange(name, params) {
routeName(name); routeName(name);
routeParams(params); routeParams(params);
vm.redraw();
}); });
function handleContentScroll(evt) { function handleContentScroll(evt) {
@ -41,8 +43,8 @@ export function GalleryView(vm) {
{ onscroll: handleContentScroll }, { onscroll: handleContentScroll },
renderSwitch( renderSwitch(
{ {
photos: [AllImagesView, {}, 'allImages', context] photos: [AllImagesView, {}, 'allImages', context],
// focus: renderFocus focus: [FocusView, routeParams(), 'focus', context]
}, },
routeName() routeName()
) )
@ -88,7 +90,6 @@ const fill = injectStyle(FILL_STYLE);
const content = styled( const content = styled(
{ {
overflow: 'scroll',
['-webkit-transform']: 'translate3d(0,0,0);' // http://blog.getpostman.com/2015/01/23/ui-repaint-issue-on-chrome/ ['-webkit-transform']: 'translate3d(0,0,0);' // http://blog.getpostman.com/2015/01/23/ui-repaint-issue-on-chrome/
}, },
FILL_STYLE FILL_STYLE

View File

@ -15,9 +15,9 @@ export const router = Router([
name: 'focus', name: 'focus',
path: '/focus/:id', path: '/focus/:id',
vars: { vars: {
id: /^[_A-Za-z0-9]+$/ id: /[_A-Za-z0-9]+/
}, },
enter: (r, route) => fire('image', route) enter: (r, route) => fire('focus', route)
}, },
{ {
id: '404', id: '404',

View File

@ -45,7 +45,7 @@ export function deepAssign(to, ...rest) {
return to; return to;
} }
export const pick = id => doc => doc && doc[id]; export const pick = (id, def) => doc => (doc && doc.hasOwnProperty(id) ? doc[id] : def);
export const extractID = pick('_id'); export const extractID = pick('_id');
export const extractREV = pick('_rev'); export const extractREV = pick('_rev');

View File

@ -6,7 +6,7 @@ import { deepAssign } from './conversion.js';
import { error } from '../services/console.js'; import { error } from '../services/console.js';
export function subscribeToRender(vm, subscribables, subscriptions) { export function subscribeToRender(vm, subscribables, subscriptions) {
const redraw = (...args) => vm.redraw(); const redraw = () => vm.redraw();
const subList = subscribables.map(s => s.subscribe(redraw)); const subList = subscribables.map(s => s.subscribe(redraw));
vm.config({ vm.config({
@ -48,5 +48,5 @@ export function nodeParentWithType(node, type) {
export function renderSwitch(renderMap, switchValue) { export function renderSwitch(renderMap, switchValue) {
const params = renderMap[switchValue]; const params = renderMap[switchValue];
return params ? defineView.apply(null, params) : 'NOT FOUND'; return params ? defineView.apply(null, params) : `VIEW ${switchValue} NOT FOUND`;
} }