overleaf/services/web/frontend/js/shared/context/editor-context.js
Miguel Serrano 260b878b7d [ReactNavToolbar] Chat Toggle Button + chat-context (#3625)
* Added toggle chat button to navigation header

* new `useBrowserWindow` hook to work with browser title and focus

* react2angular chat toggle button plumbing

GitOrigin-RevId: 4380f1db9c7cc9a25bfb8d7a33e18d61b1d32993
2021-02-10 03:04:39 +00:00

76 lines
2 KiB
JavaScript

import React, { createContext, useCallback, useContext, useEffect } from 'react'
import PropTypes from 'prop-types'
import usePersistedState from '../../infrastructure/persisted-state-hook'
export const EditorContext = createContext()
export function EditorProvider({
children,
loading,
chatIsOpenAngular,
setChatIsOpenAngular
}) {
const cobranding = window.brandVariation
? {
logoImgUrl: window.brandVariation.logo_url,
brandVariationName: window.brandVariation.name,
brandVariationHomeUrl: window.brandVariation.home_url
}
: undefined
const ownerId =
window._ide.$scope.project && window._ide.$scope.project.owner
? window._ide.$scope.project.owner._id
: null
const [chatIsOpen, setChatIsOpen] = usePersistedState(
'editor.ui.chat.open',
false
)
const toggleChatOpen = useCallback(() => {
setChatIsOpen(!chatIsOpen)
setChatIsOpenAngular(!chatIsOpen)
}, [chatIsOpen, setChatIsOpenAngular, setChatIsOpen])
// updates React's `chatIsOpen` state when the chat is opened by Angular.
// In order to prevent race conditions with `toggleChatOpen` it's not a 1:1 binding:
// Angular forces the React state to `true`, but can only set it to `false` when
// the React state is explicitly `true`.
useEffect(() => {
if (chatIsOpenAngular) {
setChatIsOpen(true)
} else if (chatIsOpen) {
setChatIsOpen(false)
}
}, [chatIsOpenAngular, chatIsOpen, setChatIsOpen])
const editorContextValue = {
cobranding,
loading,
projectId: window.project_id,
isProjectOwner: ownerId === window.user.id,
ui: {
chatIsOpen,
toggleChatOpen
}
}
return (
<EditorContext.Provider value={editorContextValue}>
{children}
</EditorContext.Provider>
)
}
EditorProvider.propTypes = {
children: PropTypes.any,
loading: PropTypes.bool,
chatIsOpenAngular: PropTypes.bool,
setChatIsOpenAngular: PropTypes.func.isRequired
}
export function useEditorContext() {
const editorContext = useContext(EditorContext)
return editorContext
}