Initial FocusView
This commit is contained in:
parent
83b458bb41
commit
c0c0898d8c
@ -2,6 +2,7 @@ import { prop, computed, container } from 'frptools';
|
||||
|
||||
import { Icon } from './icon.js';
|
||||
import { defineElement as el, subscribeToRender } from '../../utils/domvm.js';
|
||||
import { pick } from '../../utils/conversion.js';
|
||||
import { injectStyle, styled } from '../../services/style.js';
|
||||
import { CLICKABLE } from '../styles.js';
|
||||
|
||||
@ -13,8 +14,9 @@ export function AppBarView(vm, params, key, opts) {
|
||||
const companionScrollTop = prop(0);
|
||||
|
||||
const currentState = computed(stack => stack[0] || {}, [stateStack]);
|
||||
const title = computed(state => state.title || '', [currentState]);
|
||||
const renderButtons = computed(state => state.buttons, [currentState]);
|
||||
const title = computed(pick('title', ''), [currentState]);
|
||||
const renderButtons = computed(pick('buttons'), [currentState]);
|
||||
const stateStyle = computed(pick('style', {}), [currentState]);
|
||||
const backButton = computed(
|
||||
(state, stack) =>
|
||||
stack.length > 1 ? (state.backButton !== undefined ? state.backButton : 'arrow_left') : null,
|
||||
@ -27,6 +29,13 @@ export function AppBarView(vm, params, key, opts) {
|
||||
[companionScrollTop]
|
||||
);
|
||||
|
||||
const containerStyle = computed(
|
||||
(boxShadow, style) => ({
|
||||
css: Object.assign({ boxShadow }, style)
|
||||
}),
|
||||
[boxShadowStyle, stateStyle]
|
||||
);
|
||||
|
||||
if (opts.appbar) {
|
||||
throw new Error('Cannot have more than one AppBar.');
|
||||
}
|
||||
@ -48,42 +57,38 @@ export function AppBarView(vm, params, key, opts) {
|
||||
subscribe: stateChange.subscribe
|
||||
};
|
||||
|
||||
subscribeToRender(vm, [boxShadowStyle, renderButtons, backButton, title]);
|
||||
subscribeToRender(vm, [containerStyle, renderButtons, backButton, title]);
|
||||
|
||||
return (vm, params) => {
|
||||
const _buttons = renderButtons() || (() => {});
|
||||
|
||||
return header(
|
||||
{
|
||||
css: { boxShadow: boxShadowStyle() }
|
||||
},
|
||||
[
|
||||
backButton() !== null
|
||||
? backButtonContainer(
|
||||
{
|
||||
onclick: popState
|
||||
},
|
||||
[
|
||||
Icon({
|
||||
name: backButton(),
|
||||
size: 0.75
|
||||
})
|
||||
]
|
||||
)
|
||||
: null,
|
||||
titleContainer(title()),
|
||||
headerRight(_buttons())
|
||||
]
|
||||
);
|
||||
return appBarContainer(containerStyle(), [
|
||||
backButton() !== null
|
||||
? backButtonContainer(
|
||||
{
|
||||
onclick: popState
|
||||
},
|
||||
[
|
||||
Icon({
|
||||
name: backButton(),
|
||||
size: 0.75
|
||||
})
|
||||
]
|
||||
)
|
||||
: null,
|
||||
titleContainer(title()),
|
||||
headerRight(_buttons())
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
||||
const header = styled({
|
||||
const appBarContainer = styled({
|
||||
justifyContent: 'space-between',
|
||||
padding: '1em',
|
||||
zIndex: 1000,
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
alignItems: 'center',
|
||||
width: '100%'
|
||||
});
|
||||
|
||||
const backButtonContainer = styled(
|
||||
|
||||
132
packages/gallery/src/interface/focus.js
Normal file
132
packages/gallery/src/interface/focus.js
Normal 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%' });
|
||||
@ -12,6 +12,7 @@ import { ImageType } from '../data/image.js';
|
||||
import { AlbumType } from '../data/album.js';
|
||||
import { ThumbnailTemplate } from './components/thumbnail.js';
|
||||
import { AllImagesView, uploadImages } from './allImages.js';
|
||||
import { FocusView } from './focus.js';
|
||||
import { Dropzone } from './components/dropzone.js';
|
||||
import { Overlay } from './components/overlay.js';
|
||||
import { AppBarView } from './components/appbar.js';
|
||||
@ -28,6 +29,7 @@ export function GalleryView(vm) {
|
||||
routeChanged.subscribe(function onRouteChange(name, params) {
|
||||
routeName(name);
|
||||
routeParams(params);
|
||||
vm.redraw();
|
||||
});
|
||||
|
||||
function handleContentScroll(evt) {
|
||||
@ -41,8 +43,8 @@ export function GalleryView(vm) {
|
||||
{ onscroll: handleContentScroll },
|
||||
renderSwitch(
|
||||
{
|
||||
photos: [AllImagesView, {}, 'allImages', context]
|
||||
// focus: renderFocus
|
||||
photos: [AllImagesView, {}, 'allImages', context],
|
||||
focus: [FocusView, routeParams(), 'focus', context]
|
||||
},
|
||||
routeName()
|
||||
)
|
||||
@ -88,7 +90,6 @@ const fill = injectStyle(FILL_STYLE);
|
||||
|
||||
const content = styled(
|
||||
{
|
||||
overflow: 'scroll',
|
||||
['-webkit-transform']: 'translate3d(0,0,0);' // http://blog.getpostman.com/2015/01/23/ui-repaint-issue-on-chrome/
|
||||
},
|
||||
FILL_STYLE
|
||||
|
||||
@ -15,9 +15,9 @@ export const router = Router([
|
||||
name: 'focus',
|
||||
path: '/focus/:id',
|
||||
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',
|
||||
|
||||
@ -45,7 +45,7 @@ export function deepAssign(to, ...rest) {
|
||||
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 extractREV = pick('_rev');
|
||||
|
||||
@ -6,7 +6,7 @@ import { deepAssign } from './conversion.js';
|
||||
import { error } from '../services/console.js';
|
||||
|
||||
export function subscribeToRender(vm, subscribables, subscriptions) {
|
||||
const redraw = (...args) => vm.redraw();
|
||||
const redraw = () => vm.redraw();
|
||||
const subList = subscribables.map(s => s.subscribe(redraw));
|
||||
|
||||
vm.config({
|
||||
@ -48,5 +48,5 @@ export function nodeParentWithType(node, type) {
|
||||
|
||||
export function renderSwitch(renderMap, switchValue) {
|
||||
const params = renderMap[switchValue];
|
||||
return params ? defineView.apply(null, params) : 'NOT FOUND';
|
||||
return params ? defineView.apply(null, params) : `VIEW ${switchValue} NOT FOUND`;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user