feat(client): Apply reset context flag to recreate context on client.

This commit is contained in:
Gervwyk 2022-05-01 16:28:38 +02:00
parent f303bc0461
commit 09f49a2072
5 changed files with 37 additions and 9 deletions

View File

@ -23,16 +23,30 @@ import ProgressBarController from './ProgressBarController.js';
import initLowdefyContext from './initLowdefyContext.js';
const Client = ({ Components, config, router, stage, types, window }) => {
const lowdefy = initLowdefyContext({ Components, config, router, types, stage, window });
const Client = ({
Components,
config,
resetContext = { reset: false, setReset: () => undefined },
router,
stage,
types,
window,
}) => {
const lowdefy = initLowdefyContext({ Components, config, router, stage, types, window });
return (
<>
<ProgressBarController
id="page-loader"
key={`${config.pageConfig.id}-loader`}
lowdefy={lowdefy}
resetContext={resetContext}
/>
<Context key={config.pageConfig.id} config={config.pageConfig} lowdefy={lowdefy}>
<Context
key={config.pageConfig.id}
config={config.pageConfig}
lowdefy={lowdefy}
resetContext={resetContext}
>
{(context) => {
if (!context._internal.onInitDone) return '';
return (

View File

@ -19,8 +19,8 @@ import getContext from '@lowdefy/engine';
import MountEvents from './MountEvents.js';
const Context = ({ children, config, lowdefy }) => {
const context = getContext({ config, lowdefy });
const Context = ({ children, config, lowdefy, resetContext }) => {
const context = getContext({ config, lowdefy, resetContext });
return (
<MountEvents
context={context}

View File

@ -21,6 +21,7 @@ const MountEvents = ({ children, context, triggerEvent, triggerEventAsync }) =>
const [error, setError] = useState(null);
useEffect(() => {
let mounted = true;
setLoading(true);
const mount = async () => {
try {
await triggerEvent();

View File

@ -44,12 +44,17 @@ function reducer(state, action) {
progress: state.onMounts - 1 === 0 ? 100 : state.progress,
onMounts: state.onMounts - 1,
};
case 'reset':
return {
progress: 0,
onMounts: 0,
};
default:
throw new Error('Invalid action type for ProgressBarController reducer.');
}
}
const ProgressBarController = ({ id, lowdefy }) => {
const ProgressBarController = ({ id, lowdefy, resetContext }) => {
const [state, dispatch] = useReducer(reducer, initialState);
const ProgressBar = lowdefy._internal.blockComponents.ProgressBar;
lowdefy._internal.progress.state = state;
@ -59,6 +64,9 @@ const ProgressBarController = ({ id, lowdefy }) => {
state.progress < 95 && setInterval(() => dispatch({ type: 'auto-increment' }), 500);
return () => clearInterval(timer);
}, [state]);
if (resetContext.reset && state.progress === 100) {
dispatch({ type: 'reset' });
}
return (
<ProgressBar
basePath={lowdefy.basePath}

View File

@ -55,16 +55,21 @@ const blockData = ({
visible,
});
function getContext({ config, lowdefy }) {
function getContext({
config,
lowdefy,
resetContext = { reset: false, setReset: () => undefined },
}) {
if (!config) {
throw new Error('A page must be provided to get context.');
}
const { id } = config;
if (lowdefy.contexts[id]) {
if (lowdefy.contexts[id] && !resetContext.reset) {
// memoize context if already created, eg between page transitions, unless the reset flag is raised
lowdefy.contexts[id]._internal.update();
return lowdefy.contexts[id];
}
resetContext.setReset(false); // lower context reset flag.
if (!lowdefy.inputs[id]) {
lowdefy.inputs[id] = {};
}