import { deserializePB, serializePB, useBuilder, useEditor, } from '@tempi/core-editor'; import { defaultRoot, DesignMode, LICENSE_CODE_PUBLISH, Page, Status, useLicense, useSerializedPageContent, } from '@tempi/editor-site'; import { useEffect, useRef, useState } from 'react'; import { Device } from '@tempi/types/pb'; import { debounce, PageBuilderResponse } from '@tempi/core-renderer'; import { useUnloadPage } from 'hooks'; import { AxiosResponse } from 'axios'; import { BuilderState } from '../context'; export interface usePageEditorProps { updatePageService: (id: any, body: any) => Promise>; getPageService: ( id: any, params?: { device: any; }, ) => Promise; } export const useLandingPage = ({ updatePageService, getPageService, }: usePageEditorProps) => { const [page, setPage] = useState(); const [loadingInit, setLoadingInit] = useState(true); const [isValidatingLicense, setIsValidatingLicense] = useState(false); const [isDisabledEditor, setIsDisabledEdtior] = useState(false); const [loading, setLoading] = useState(); const [allowAutoSave, setAllowAutoSave] = useState(false); const { setShouldPreventUnload } = useUnloadPage(); const { checkValidLicense } = useLicense(); const { device, setDevice, initialDevice, pageId, setDesignMode, setAllowConfigResponsive, designMode, setPageFonts, } = useBuilder(); const { actions, getPageContent } = useSerializedPageContent(); // only use to handle auto save when content change and autosave enable const { draftPageContent } = useEditor((_, query) => ({ draftPageContent: serializePB(JSON.parse(query.serialize()), { isEditingBlock: false, isEditingPopup: false, }), })); const [visiblePageSettingModal, setVisiblePageSettingModal] = useState(false); const flagAutoSave = useRef(false); const handleAutoSave = useRef( debounce(async () => { if (visiblePageSettingModal) return; onSavePage(); }, 2000), ).current; const onChangeDesignMode = (designMode) => { setDesignMode(designMode); if (designMode === DesignMode.MOBILE_ONLY) { setDevice(Device.MOBILE); } else { setDevice(Device.DESKTOP); } }; const onChangeDevice = async (newDevice: Device) => { if (device === newDevice) return; setDevice(newDevice); }; const onSavePage = async (data?: object, callBack?: () => void) => { try { setLoading(true); if (!data) data = { content: getPageContent() }; await updatePageService(pageId, { ...data, designMode }); await getPageData(); setShouldPreventUnload(false); callBack?.(); } catch (e) { throw new Error(e); } finally { setLoading(false); } }; const initDesignMode = (newDesignMode: DesignMode) => { if (!designMode || newDesignMode !== page?.designMode) { setDesignMode(newDesignMode); setAllowConfigResponsive(newDesignMode === DesignMode.RESPONSIVE); } if (newDesignMode === DesignMode.MOBILE_ONLY) { setDevice(Device.MOBILE); } else { setDevice(Device.DESKTOP); } }; const checkDisableEdit = async () => { try { setIsValidatingLicense(true); const isValidLicense = await checkValidLicense([LICENSE_CODE_PUBLISH]); setIsDisabledEdtior(!isValidLicense); } finally { setIsValidatingLicense(false); } }; const getPageData = async () => { const page = await getPageService(pageId, { device: initialDevice }); setPage(page); return page; }; const initDataEditor = async () => { try { setLoadingInit(true); const pageData = await getPageData(); initDesignMode(pageData?.designMode); actions.history .ignore() .deserialize( deserializePB( (pageData?.content || defaultRoot) as PageBuilderResponse, false, false, ) as any, ); if (pageData?.status === Status.PUBLISHED) { checkDisableEdit(); } else { setAllowAutoSave(true); } } finally { setLoadingInit(false); } }; useEffect(() => { if (!pageId) return; initDataEditor(); }, [pageId]); // Handle auto save when page changed useEffect(() => { if (!allowAutoSave || !page) return; if (flagAutoSave.current) { handleAutoSave(); } else { flagAutoSave.current = true; } // eslint-disable-next-line react-hooks/exhaustive-deps }, [JSON.stringify(draftPageContent)]); useEffect(() => { setPageFonts(page?.fonts); }, [page?.fonts, setPageFonts]); return { page: page, loadingInit, isValidatingLicense, isDisabledEditor, device, onChangeDevice, onSavePage, allowAutoSave, setAllowAutoSave, loading, getPageContent, setVisiblePageSettingModal, visiblePageSettingModal, designMode, setDesignMode, setDevice, onChangeDesignMode, }; };