Complete(?) AppBar state management
This commit is contained in:
parent
d83b397b89
commit
8006e98dbc
@ -1,13 +1,27 @@
|
|||||||
import { prop, computed, bundle } from 'frptools';
|
import { prop, computed, container } from 'frptools';
|
||||||
|
|
||||||
|
import { Icon } from './icon.js';
|
||||||
import { defineElement as el, subscribeToRender } from '../../utils/domvm.js';
|
import { defineElement as el, subscribeToRender } from '../../utils/domvm.js';
|
||||||
import { injectStyle, styled } from '../../services/style.js';
|
import { injectStyle, styled } from '../../services/style.js';
|
||||||
|
import { pick } from '../../utils/conversion.js';
|
||||||
|
|
||||||
|
let seq = 0;
|
||||||
|
const getSeq = pick('_seq');
|
||||||
|
|
||||||
export function AppBarView(vm, params, key, opts) {
|
export function AppBarView(vm, params, key, opts) {
|
||||||
const title = prop(params.title);
|
const stateStack = container([], arr => arr.length);
|
||||||
const renderButtons = prop(params.renderButtons || (() => []));
|
|
||||||
const hasBackButton = prop(false);
|
|
||||||
const companionScrollTop = prop(0);
|
const companionScrollTop = prop(0);
|
||||||
|
const previousState = prop({ _seq: seq }, getSeq);
|
||||||
|
|
||||||
|
const currentState = computed(stack => stack[0] || {}, [stateStack]);
|
||||||
|
const title = computed(state => state.title || '', [currentState]);
|
||||||
|
const renderButtons = computed(state => state.buttons, [currentState]);
|
||||||
|
const hasBackButton = computed(stack => stack.length > 1, [stateStack]);
|
||||||
|
const stateChange = computed((c, p) => ({ newState: c, oldState: p }), [
|
||||||
|
currentState,
|
||||||
|
previousState
|
||||||
|
]);
|
||||||
|
|
||||||
const boxShadowStyle = computed(
|
const boxShadowStyle = computed(
|
||||||
t => (t === 0 ? 'none' : `0px ${Math.min(t / 10, 3)}px 3px rgba(0, 0, 0, .2)`),
|
t => (t === 0 ? 'none' : `0px ${Math.min(t / 10, 3)}px 3px rgba(0, 0, 0, .2)`),
|
||||||
[companionScrollTop]
|
[companionScrollTop]
|
||||||
@ -17,22 +31,49 @@ export function AppBarView(vm, params, key, opts) {
|
|||||||
throw new Error('Cannot have more than one AppBar.');
|
throw new Error('Cannot have more than one AppBar.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function pushState(newState) {
|
||||||
|
const oldState = currentState() || {};
|
||||||
|
stateStack.unshift(Object.assign({ _seq: seq++ }, newState));
|
||||||
|
previousState(oldState);
|
||||||
|
}
|
||||||
|
|
||||||
|
function popState() {
|
||||||
|
const oldState = currentState();
|
||||||
|
stateStack.shift();
|
||||||
|
previousState(oldState);
|
||||||
|
}
|
||||||
|
|
||||||
opts.appbar = {
|
opts.appbar = {
|
||||||
title,
|
pushState,
|
||||||
renderButtons,
|
popState,
|
||||||
hasBackButton,
|
companionScrollTop,
|
||||||
companionScrollTop
|
subscribe: stateChange.subscribe
|
||||||
};
|
};
|
||||||
|
|
||||||
subscribeToRender(vm, [boxShadowStyle, renderButtons]);
|
subscribeToRender(vm, [boxShadowStyle, renderButtons, hasBackButton, title]);
|
||||||
|
|
||||||
return (vm, params) => {
|
return (vm, params) => {
|
||||||
const { title } = params;
|
const _buttons = renderButtons() || (() => {});
|
||||||
|
|
||||||
return header(
|
return header(
|
||||||
{
|
{
|
||||||
css: { boxShadow: boxShadowStyle() }
|
css: { boxShadow: boxShadowStyle() }
|
||||||
},
|
},
|
||||||
[titleContainer(title), headerRight(renderButtons()())]
|
[
|
||||||
|
hasBackButton()
|
||||||
|
? backButtonContainer([
|
||||||
|
Icon({
|
||||||
|
name: 'arrow_left',
|
||||||
|
size: 0.75,
|
||||||
|
attrs: {
|
||||||
|
onclick: popState
|
||||||
|
}
|
||||||
|
})
|
||||||
|
])
|
||||||
|
: null,
|
||||||
|
titleContainer(title()),
|
||||||
|
headerRight(_buttons())
|
||||||
|
]
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -45,11 +86,16 @@ const header = styled({
|
|||||||
alignItems: 'center'
|
alignItems: 'center'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const backButtonContainer = styled({
|
||||||
|
marginRight: '1em'
|
||||||
|
});
|
||||||
|
|
||||||
const headerRight = styled({
|
const headerRight = styled({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center'
|
alignItems: 'center'
|
||||||
});
|
});
|
||||||
|
|
||||||
const titleContainer = styled({
|
const titleContainer = styled({
|
||||||
fontSize: '20pt'
|
fontSize: '20pt',
|
||||||
|
flex: 1
|
||||||
});
|
});
|
||||||
|
|||||||
@ -16,14 +16,12 @@ export function GalleryView(vm) {
|
|||||||
let data = null;
|
let data = null;
|
||||||
let laCleanup = null;
|
let laCleanup = null;
|
||||||
const context = {};
|
const context = {};
|
||||||
const title = prop('');
|
|
||||||
const hasData = prop(null);
|
const hasData = prop(null);
|
||||||
|
|
||||||
subscribeToRender(vm, [hasData]);
|
subscribeToRender(vm, [hasData]);
|
||||||
|
|
||||||
routeChanged.subscribe(function onRouteChange(name, params) {
|
routeChanged.subscribe(function onRouteChange(name, params) {
|
||||||
if (name == 'photos') {
|
if (name == 'photos') {
|
||||||
title('Photos');
|
|
||||||
ImageType.find({
|
ImageType.find({
|
||||||
['sizes.thumbnail']: { $exists: true }
|
['sizes.thumbnail']: { $exists: true }
|
||||||
}).then(results => {
|
}).then(results => {
|
||||||
@ -56,14 +54,7 @@ export function GalleryView(vm) {
|
|||||||
|
|
||||||
function renderMain() {
|
function renderMain() {
|
||||||
return [
|
return [
|
||||||
vw(
|
vw(AppBarView, {}, 'appbar', context),
|
||||||
AppBarView,
|
|
||||||
{
|
|
||||||
title: 'Photos'
|
|
||||||
},
|
|
||||||
'appbar',
|
|
||||||
context
|
|
||||||
),
|
|
||||||
content(
|
content(
|
||||||
{
|
{
|
||||||
onscroll: handleContentScroll
|
onscroll: handleContentScroll
|
||||||
|
|||||||
@ -45,7 +45,7 @@ export function deepAssign(to, ...rest) {
|
|||||||
return to;
|
return to;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const pick = id => doc => doc[id];
|
export const pick = id => doc => doc && doc[id];
|
||||||
|
|
||||||
export const extractID = pick('_id');
|
export const extractID = pick('_id');
|
||||||
export const extractREV = pick('_rev');
|
export const extractREV = pick('_rev');
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user