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 { 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(
|
||||||
|
|||||||
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 { 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
|
||||||
|
|||||||
@ -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',
|
||||||
|
|||||||
@ -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');
|
||||||
|
|||||||
@ -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`;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user