Fix appbar brain-damage

This commit is contained in:
Timothy Farrell 2017-12-31 05:22:40 -06:00
parent a8a55654d8
commit e65e94789e
3 changed files with 49 additions and 56 deletions

View File

@ -26,13 +26,11 @@ export function uploadImages(evt, files) {
export function AllImagesView(vm, params, key, { appbar }) { export function AllImagesView(vm, params, key, { appbar }) {
const model = prop({}, pouchDocHash); const model = prop({}, pouchDocHash);
const appbarState = prop({});
const images = container([], pouchDocArrayHash); const images = container([], pouchDocArrayHash);
const selectedIds = container(new Set(), hashSet); const selectedIds = container(new Set(), hashSet);
const appBarTitle = computed(s => (s.size > 0 ? `${s.size} selected` : 'Photos'), [selectedIds]); const appBarTitle = computed(s => (s.size > 0 ? `${s.size} selected` : 'Photos'), [selectedIds]);
const hasSelectedIDs = computed(sIds => sIds.size > 0, [selectedIds]); const selectMode = computed(sIds => sIds.size > 0, [selectedIds]);
const selectMode = computed((s, abS) => s && abS.selectMode, [hasSelectedIDs, appbarState]);
const sections = computed( const sections = computed(
imageArr => { imageArr => {
@ -76,7 +74,7 @@ export function AllImagesView(vm, params, key, { appbar }) {
name: 'uploadButton', name: 'uploadButton',
type: 'file', type: 'file',
multiple: true, multiple: true,
accept: '.png,.jpg,.jpeg', // no love for gifs yet accept: '.jpg,.jpeg', // no love for gifs, pngs yet
onchange: uploadImages, onchange: uploadImages,
class: injectStyle({ display: 'none' }) class: injectStyle({ display: 'none' })
}) })
@ -129,11 +127,17 @@ export function AllImagesView(vm, params, key, { appbar }) {
} }
function pushAppBarState() { function pushAppBarState() {
const up = selectMode()
? {
name: 'x',
onclick: () => selectedIds.clear()
}
: undefined;
appbar.pushState({ appbar.pushState({
title: appBarTitle, title: appBarTitle,
buttons: renderAppBarButtons, actions: renderAppBarButtons,
selectMode: hasSelectedIDs(), up
backButton: 'x'
}); });
} }
@ -148,25 +152,14 @@ export function AllImagesView(vm, params, key, { appbar }) {
{ live: true } { live: true }
).then(la => { ).then(la => {
pushAppBarState(); pushAppBarState();
selectMode.subscribe(mode => {
popAppBarState();
pushAppBarState();
}),
subscribeToRender( subscribeToRender(
vm, vm,
[selectedIds, images, selectMode], [selectedIds, images, selectMode],
[ [la.subscribe(res => images.splice(0, images.length, ...res))]
la.subscribe(res => images.splice(0, images.length, ...res)),
appbar.subscribe(({ newState, oldState }) => {
appbarState(newState);
if (!newState.selectMode && hasSelectedIDs()) {
selectedIds.clear();
}
}),
hasSelectedIDs.subscribe(selected => {
if (selected && !selectMode()) {
pushAppBarState();
} else if (!selected && appbarState().selectMode) {
popAppBarState();
}
})
]
); );
}); });

View File

@ -1,6 +1,7 @@
import { prop, computed, container, pick } from 'frptools'; import { prop, computed, container, pick } from 'frptools';
import { Icon } from './icon.js'; import { Icon } from './icon.js';
import { router } from '../../services/router.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 { CLICKABLE } from '../styles.js'; import { CLICKABLE } from '../styles.js';
@ -8,20 +9,19 @@ import { CLICKABLE } from '../styles.js';
let seq = 0; let seq = 0;
export function AppBarView(vm, params, key, opts) { export function AppBarView(vm, params, key, opts) {
let previousState = { _seq: seq };
const stateStack = container([], arr => arr.length); const stateStack = container([], arr => arr.length);
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(pick('title', ''), [currentState]); const title = computed(pick('title', ''), [currentState]);
const renderButtons = computed(pick('buttons'), [currentState]); const renderActions = computed(pick('actions'), [currentState]);
const stateStyle = computed(pick('style', {}), [currentState]); const up = computed(pick('up'), [currentState]);
const backButton = computed( const upButton = computed(pick('name', 'arrow_left'), [up]);
(state, stack) => const upAction = computed(
stack.length > 1 ? (state.backButton !== undefined ? state.backButton : 'arrow_left') : null, upState => (upState.onclick ? upState.onclick : [popState, upState.navigateTo]),
[currentState, stateStack] [up]
); );
const stateChange = computed(c => ({ newState: c, oldState: previousState }), [currentState]); const stateStyle = computed(pick('style', {}), [currentState]);
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)`),
@ -40,36 +40,36 @@ export function AppBarView(vm, params, key, opts) {
} }
function pushState(newState) { function pushState(newState) {
previousState = currentState();
stateStack.unshift(Object.assign({ _seq: seq++ }, newState)); stateStack.unshift(Object.assign({ _seq: seq++ }, newState));
} }
function popState() { function popState(navigateTo) {
previousState = currentState();
stateStack.shift(); stateStack.shift();
if (navigateTo) {
router.goto(navigateTo);
}
} }
opts.appbar = { opts.appbar = {
pushState, pushState,
popState, popState,
companionScrollTop, companionScrollTop
subscribe: stateChange.subscribe
}; };
subscribeToRender(vm, [containerStyle, renderButtons, backButton, title]); subscribeToRender(vm, [containerStyle, renderActions, up, title]);
return (vm, params) => { return (vm, params) => {
const _buttons = renderButtons() || (() => {}); const _buttons = renderActions() || (() => {});
return appBarContainer(containerStyle(), [ return appBarContainer(containerStyle(), [
backButton() !== null up()
? backButtonContainer( ? upButtonContainer(
{ {
onclick: popState onclick: upAction()
}, },
[ [
Icon({ Icon({
name: backButton(), name: upButton(),
size: 0.75 size: 0.75
}) })
] ]
@ -90,7 +90,7 @@ const appBarContainer = styled({
width: '100%' width: '100%'
}); });
const backButtonContainer = styled( const upButtonContainer = styled(
{ {
marginRight: '1em' marginRight: '1em'
}, },

View File

@ -48,13 +48,8 @@ export function FocusView(vm, params, key, { appbar }) {
[doc, windowSize] [doc, windowSize]
); );
async function goBack() {
router.goto('home');
}
function navBack() { function navBack() {
// appbar.popState(); appbar.popState('home');
goBack();
} }
async function clickTrash() { async function clickTrash() {
@ -79,7 +74,14 @@ export function FocusView(vm, params, key, { appbar }) {
} }
// Set the appbar title. // Set the appbar title.
appbar.pushState({ title: '', buttons: renderAppBarButtons, style: { position: 'fixed' } }); appbar.pushState({
title: '',
actions: renderAppBarButtons,
style: { position: 'fixed' },
up: {
navigateTo: 'home'
}
});
// Prime our window size // Prime our window size
extractWindowSize(); extractWindowSize();
@ -90,8 +92,6 @@ export function FocusView(vm, params, key, { appbar }) {
vm, vm,
[doc, imageStyle, nextLink, prevLink], [doc, imageStyle, nextLink, prevLink],
[ [
appbar.subscribe(goBack),
// Keep up with the window resizing // Keep up with the window resizing
() => window.removeEventListener('resize', extractWindowSize), () => window.removeEventListener('resize', extractWindowSize),