react-native-twopane-navigation
Version:
React Native package for dual screen devices navigation support (Surface Duo)
128 lines (108 loc) • 4.59 kB
text/typescript
import { store } from '../../appStore';
import {
IExtensionOptions,
paneType
} from '../../utilities/interfaces';
import { pushKey, popToFront, popScreen, moveToFront, changeScreen } from '../../shared/screenStore/keyStore/key.actions';
import { pushHeader, replaceHeader, removeHeaderByKey } from '../../shared/screenStore/headerStore/header.actions';
import { pushElement, removePaneElementByKey, replacePaneElement } from '../../shared/screenStore/paneElementStore/paneElement.action';
import { ReactElement } from 'react';
import { IHeader } from '../../shared/screenStore/headerStore/header.interface';
import { IKeyState, IKeyObject } from '../../shared/screenStore/keyStore/key.interface';
const AddPaneElement= (key: string, element: ReactElement, header?: IHeader, isMerge: boolean = false, extensionOptions?: IExtensionOptions) => {
store.dispatch(pushKey(paneType.ONE, key, isMerge, extensionOptions));
store.dispatch(pushElement(`${paneType.ONE}_${key}`, element));
if (header) {
store.dispatch(pushHeader(`${paneType.ONE}_${key}`, header));
}
}
/**
* Pushes element to the top of the onePane stack or replaces the original with the new element
*/
const Add = (key: string, element: ReactElement, header?: IHeader, isMerge: boolean = false, extensionOptions?: IExtensionOptions) => {
const keys: IKeyState = store.getState().KeyReducers;
const index = keys.keys.findIndex(val => val.key === `${paneType.ONE}_${key}`);
if(index > -1) {
//remove old entry
store.dispatch(removeHeaderByKey(keys.keys[index].key))
store.dispatch(removePaneElementByKey(keys.keys[index].key))
// push new entry
store.dispatch(pushElement(`${paneType.ONE}_${key}`, element));
if (header) {
store.dispatch(pushHeader(`${paneType.ONE}_${key}`, header));
}
store.dispatch(moveToFront(paneType.ONE, `${paneType.ONE}_${key}`));
} else {
AddPaneElement(key, element, header, isMerge, extensionOptions)
}
};
/**
* Pushes element to the top of the onePane stack or moves the original to the top of the stack
*/
const AddOrMoveToFront = (key: string, element: React.ReactElement, header?: IHeader, isMerge: boolean = false) => {
const keys: IKeyState = store.getState().KeyReducers;
const onePaneState: IKeyObject[] = keys.keys.filter(x => x.screen === paneType.ONE)
if (!onePaneState.some(val => val.key === `${paneType.ONE}_${key}`)) {
AddPaneElement(key, element, header, isMerge)
} else {
store.dispatch(moveToFront(paneType.ONE, `${paneType.ONE}_${key}`));
}
}
/**
* when the app active panes changes move panes marked as isMerged to twoPane
*/
const mergeToOppositePane= () => {
const keys: IKeyState = store.getState().KeyReducers;
keys.keys.map(val => {
if (val.screen === paneType.ONE && val.isMerge) {
store.dispatch(changeScreen(paneType.TWO, val.key))
}
})
}
/**
* Removes all elements of the onePane stack
* and returns the base element of the onePane stack
*/
const BackToHome = () => {
const keys: IKeyState = store.getState().KeyReducers;
const onePaneState: IKeyObject[] = keys.keys.filter(x => x.screen === paneType.ONE)
for (let i = 1; i < onePaneState.length; i++) {
store.dispatch(removeHeaderByKey(onePaneState[i].key));
store.dispatch(removePaneElementByKey(onePaneState[i].key));
}
store.dispatch(popToFront(paneType.ONE));
};
/**
* Go back one element in the onePane stack
*/
const GoBack = () => {
const keys: IKeyState = store.getState().KeyReducers;
const onePaneState: IKeyObject[] = keys.keys.filter(x => x.screen === paneType.ONE)
store.dispatch(removeHeaderByKey(onePaneState.peek().key));
store.dispatch(removePaneElementByKey(onePaneState.peek().key));
store.dispatch(popScreen(onePaneState.peek().key));
};
/**
* Replace the current element for this onePane component
*/
const ReplacePane = (key: string, element: React.ReactElement) => {
store.dispatch(replacePaneElement(`${paneType.ONE}_${key}`, element))
}
/**
* Replace the default header for this onePane component
*/
const ReplaceHeader = (key: string, header: IHeader) => {
store.dispatch(replaceHeader(`${paneType.ONE}_${key}`, header));
};
const _onePaneFunctions = {
Add,
AddOrMoveToFront,
mergeToOppositePane,
BackToHome,
GoBack,
ReplacePane,
ReplaceHeader,
};
type onePaneFunctions = typeof _onePaneFunctions;
const onePane: onePaneFunctions = _onePaneFunctions;
export default onePane;