/* eslint-disable max-lines */ import './editPage.less'; // Common imports import React, { useState, useEffect, useRef, useEffectEvent } from 'react'; import request from '../../utils/request-middleware.js'; import { hbfm } from 'hbmarkedwrapper'; import _ from 'lodash'; import { DEFAULT_BREW_LOAD } from '../../../../server/brewDefaults.js'; import useCommonEditPageFunctions from '../../utils/commonEditPageFunctions.js' import SplitPane from '@components/splitPane/splitPane.jsx'; import Editor from '../../editor/editor.jsx'; import BrewRenderer from '../../brewRenderer/brewRenderer.jsx'; import Nav from '@navbar/nav.jsx'; import Navbar from '@navbar/navbar.jsx'; import NewBrewItem from '@navbar/newbrew.navitem.jsx'; import AccountNavItem from '@navbar/account.navitem.jsx'; import ErrorNavItem from '@navbar/error-navitem.jsx'; import HelpNavItem from '@navbar/help.navitem.jsx'; import VaultNavItem from '@navbar/vault.navitem.jsx'; import PrintNavItem from '@navbar/print.navitem.jsx'; import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; // Page specific imports import Headtags from '../../../../vitreum/headtags.js'; const Meta = Headtags.Meta; import { md5 } from 'hash-wasm'; import { gzipSync, strToU8 } from 'fflate'; import { makePatches, stringifyPatches } from '@sanity/diff-match-patch'; import ShareNavItem from '@navbar/share.navitem.jsx'; import LockNotification from './lockNotification/lockNotification.jsx'; import { updateHistory, versionHistoryGarbageCollection } from '../../utils/versionHistory.js'; import googleDriveIcon from '../../googleDrive.svg'; const BREWKEY = 'HB_newPage_content'; const STYLEKEY = 'HB_newPage_style'; const SNIPKEY = 'HB_newPage_snippets'; const METAKEY = 'HB_newPage_meta'; const useLocalStorage = false; const sandbox = false; const EditPage = (props)=>{ props = { brew : DEFAULT_BREW_LOAD, ...props }; const [currentBrew, setCurrentBrew] = useState(props.brew); const [saveGoogle, setSaveGoogle] = useState(!!props.brew.googleId); const [error, setError] = useState(null); const [HTMLErrors, setHTMLErrors] = useState(hbfm.validate(props.brew.text)); const [currentEditorViewPageNum, setCurrentEditorViewPageNum] = useState(1); const [currentEditorCursorPageNum, setCurrentEditorCursorPageNum] = useState(1); const [currentBrewRendererPageNum, setCurrentBrewRendererPageNum] = useState(1); const [themeBundle, setThemeBundle] = useState({}); const [alertTrashedGoogleBrew, setAlertTrashedGoogleBrew] = useState(props.brew.trashed); const [alertNoGoogleToTransfer, setAlertNoGoogleToTransfer] = useState(false); const [alertOwnershipToTransfer, setAlertOwnershipToTransfer] = useState(false); const [confirmGoogleTransfer, setConfirmGoogleTransfer] = useState(false); const editorRef = useRef(null); const lastSavedBrew = useRef(_.cloneDeep(props.brew)); const updateBrew = (newData)=>setCurrentBrew((prevBrew)=>({ ...prevBrew, style : newData.style, text : newData.text, snippets : newData.snippets })); const handleGoogleClick = ()=>{ if(currentBrew.authors.length > 0 && global.account?.username !== currentBrew.authors[0]) { setAlertOwnershipToTransfer(true); return; } if(!global.account?.googleId) { setAlertNoGoogleToTransfer(true); return; } setConfirmGoogleTransfer((prev)=>!prev); setError(null); }; const closeAlerts = (e)=>{ e.stopPropagation(); //Only handle click once so alert doesn't reopen setAlertTrashedGoogleBrew(false); setAlertNoGoogleToTransfer(false); setConfirmGoogleTransfer(false); setAlertOwnershipToTransfer(false); }; const toggleGoogleStorage = (e)=>{ closeAlerts(e); const newSaveGoogle = !saveGoogle; setSaveGoogle((prev)=>!prev); setError(null); trySave(true, true, newSaveGoogle); }; const save = async (brew, saveToGoogle)=>{ setHTMLErrors(hbfm.validate(brew.text)); await updateHistory(brew).catch(console.error); await versionHistoryGarbageCollection().catch(console.error); //Prepare content to send to server const brewToSave = { ...brew, text : brew.text.normalize('NFC'), pageCount : ((brew.renderer === 'legacy' ? brew.text.match(/\\page/g) : brew.text.match(/^(?=\\page(?:break)?(?: *{[^\n{}]*})?$)/gm)) || []).length + 1, patches : stringifyPatches(makePatches(encodeURI(lastSavedBrew.current.text.normalize('NFC')), encodeURI(brew.text.normalize('NFC')))), hash : await md5(lastSavedBrew.current.text.normalize('NFC')), textBin : undefined, version : lastSavedBrew.current.version }; const compressedBrew = gzipSync(strToU8(JSON.stringify(brewToSave))); const transfer = saveToGoogle === _.isNil(brew.googleId); const params = transfer ? `?${saveToGoogle ? 'saveToGoogle' : 'removeFromGoogle'}=true` : ''; const res = await request .put(`/api/update/${brewToSave.editId}${params}`) .set('Content-Encoding', 'gzip') .set('Content-Type', 'application/json') .send(compressedBrew) .catch((err)=>{ console.error('Error Updating Local Brew'); setError(err); }); if(!res) return; const updatedFields = { googleId : res.body.googleId ?? null, editId : res.body.editId, shareId : res.body.shareId, version : res.body.version }; lastSavedBrew.current = { ...brew, ...updatedFields }; setCurrentBrew((prevBrew)=>({ ...prevBrew, ...updatedFields })); history.replaceState(null, null, `/edit/${res.body.editId}`); }; const renderGoogleDriveIcon = ()=>( Google Drive icon {alertOwnershipToTransfer && (
You must be the Owner to transfer between the Homebrewery and Google Drive! The owner of this file is {currentBrew.authors[0]}.

Okay
)} {alertNoGoogleToTransfer && (
You must be signed in to a Google account to transfer between the Homebrewery and Google Drive!
Sign In
Not Now
)} {alertTrashedGoogleBrew && (
This brew is currently in your Trash folder on Google Drive!
If you want to keep it, make sure to move it before it is deleted permanently!
Save my brew
)} {confirmGoogleTransfer && (
{saveGoogle ? 'Would you like to transfer this brew from your Google Drive storage back to the Homebrewery?' : 'Would you like to transfer this brew from the Homebrewery to your personal Google Drive storage?'}
Yes
No
)}
); const renderAutoSaveButton = ()=>( Autosave ); const renderNavbar = ()=>{ return {currentBrew.title} {renderGoogleDriveIcon()} {error ? : {renderSaveButton()} {renderAutoSaveButton()} } ; }; const { handleSplitMove, handleBrewChange, toggleAutoSave, clearError, renderSaveButton, autoSaveEnabled, trySave } = useCommonEditPageFunctions({ saveGoogle, setError, setThemeBundle, HTMLErrors, setHTMLErrors, currentBrew, setCurrentBrew, useLocalStorage, BREWKEY, STYLEKEY, SNIPKEY, METAKEY, hbfm, sandbox, lastSavedBrew, editorRef, save, }); return (
{renderNavbar()} {currentBrew.lock && }
); }; export default EditPage;