@nitrogenbuilder/client-react
Version:
Nitrogen Builder React Client
161 lines (134 loc) • 4.38 kB
text/typescript
import { useEffect, useState } from 'react';
import type { RequestedPageData } from '@nitrogenbuilder/types/socket-server';
// USED IN CLIENT SIDE REACT (NextJS Pages, or App Dir Client Component, or other react frameworks that are client side)
// Host, token come from window.location
type Params = Omit<RequestedPageData, 'host' | 'token'>;
export function useNitrogenData(requestedData: Params) {
const hasData = requestedData.data && requestedData.data.length > 0;
const [data, setData] = useState<any>({
id: requestedData.id,
data: hasData ? requestedData.data : [],
dynamicData: requestedData.dynamicData,
});
useEffect(() => {
const hasData = requestedData.data && requestedData.data.length > 0;
if (requestedData.id === data.id) return;
setData({
id: requestedData.id,
data: hasData ? requestedData.data : [],
dynamicData: requestedData.dynamicData,
});
}, [data, requestedData.id]);
useEffect(() => {
if (typeof window === 'undefined') {
console.log('window is undefined');
return;
}
// if we are not in builder return and use the data passed in (page data from server)
const urlParams = new URLSearchParams(window.location.search);
const isBuilder = urlParams.get('nitrogen-builder');
// TODO: Add isPreview urlParams thing or something here to also get live updates when previewing.
if (!isBuilder) {
return;
}
function windowOnMessage(event: MessageEvent<any>) {
console.log('windowOnMessage', event);
if (!event.data) {
return;
}
let data;
try {
data = JSON.parse(event.data);
} catch (e) {
return;
}
if (data.channel !== 'nitrogen-builder') {
return;
}
if (data.type === 'corePageData') {
console.log('got corePageData from iframe', data.data);
if (typeof window !== 'undefined') {
window.dispatchEvent(
new CustomEvent('nitrogen-page-data', {
detail: { data: data.data, requestedData },
})
);
}
setData((prevData: any) => ({
...prevData,
data: data.data,
}));
} else if (data.type === 'patchPageData') {
console.log('got patchPageData from iframe', data.page);
if (typeof window !== 'undefined') {
window.dispatchEvent(
new CustomEvent('nitrogen-page-data', {
detail: { data: data.data, requestedData },
})
);
}
setData((prevData: any) => ({
...prevData,
data: data.data,
}));
} else if (data.type === 'patchDynamicData') {
const dynamicData = data.dynamicData;
setData((data: any) => {
return {
...data,
dynamicData: {
...data.dynamicData,
...dynamicData.dynamicData,
},
};
});
} else if (data.type === 'usersJoined') {
if (!window.nitrogen) return;
window.nitrogen.users = { ...window.nitrogen.users, ...data.users };
} else if (data.type === 'userLeft') {
if (!window.nitrogen) return;
const newUsers = { ...window.nitrogen.users };
delete newUsers[data.userSocketId];
window.nitrogen.users = newUsers;
} else if (data.type === 'startScreenUsage') {
if (!window.nitrogen) return;
const newScreenUsage = [
...window.nitrogen.screenUsage,
data.screenUsage,
];
window.nitrogen.screenUsage = newScreenUsage;
} else if (data.type === 'setScreenUsage') {
if (!window.nitrogen) return;
window.nitrogen.screenUsage = data.screenUsage;
} else if (data.type === 'stopScreenUsage') {
if (!window.nitrogen) return;
const newScreenUsage = window.nitrogen.screenUsage.filter((usage) => {
return !(
usage.screen === data.screenUsage.screen &&
usage.socketId === data.screenUsage.socketId
);
});
window.nitrogen.screenUsage = newScreenUsage;
}
}
function setup() {
if (!window.nitrogen) {
console.log('window.nitrogen is undefined');
setTimeout(setup, 100);
return;
}
console.log('connecting window to iFrame message listener');
window.addEventListener('message', windowOnMessage);
}
setup();
return () => {
console.log('disconnecting window from iFrame message listener');
window.removeEventListener('message', windowOnMessage);
};
}, []);
if (requestedData?.moduleId) {
return data?.data?.find((d: any) => d.id === requestedData.moduleId) || {};
}
// console.log('returning data', data);
return data;
}