mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
[web] Remove instances of $scope and _ide (#26297)
* Remove `$scope` from `getMockIde` * Replace `...getMockIde()` by `_id: projectId` * Simplify stories decorator scope.tsx: less reliance on `window` * Update helper editor-providers.jsx: pass data instead directly instead of using `window` * Remove `cleanUpContext` * Remove unused prop `clsiServerId` * Update types to reflect unused properties * Remove comment * Add `ol-chatEnabled` in Storybook * Revert moving `getMeta` outside of the component This causes issues in Storybook GitOrigin-RevId: dc2558ce814c2d738fb39450c57c104f4419efb8
This commit is contained in:
@@ -13,6 +13,7 @@ import en from '../../../services/web/locales/en.json'
|
||||
function resetMeta() {
|
||||
window.metaAttributesCache = new Map()
|
||||
window.metaAttributesCache.set('ol-i18n', { currentLangCode: 'en' })
|
||||
window.metaAttributesCache.set('ol-chatEnabled', true)
|
||||
window.metaAttributesCache.set('ol-ExposedSettings', {
|
||||
adminEmail: 'placeholder@example.com',
|
||||
appName: 'Overleaf',
|
||||
|
||||
@@ -176,7 +176,6 @@ export default function FileTreeUploadDoc() {
|
||||
// close the modal when all the uploads completed successfully
|
||||
.on('complete', result => {
|
||||
if (!result.failed.length) {
|
||||
// $scope.$emit('done', { name: name })
|
||||
cancel()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -16,7 +16,6 @@ import {
|
||||
} from '@/features/ide-react/create-ide-event-emitter'
|
||||
import { JoinProjectPayload } from '@/features/ide-react/connection/join-project-payload'
|
||||
import { useConnectionContext } from '@/features/ide-react/context/connection-context'
|
||||
import { getMockIde } from '@/shared/context/mock/mock-ide'
|
||||
import { populateEditorScope } from '@/features/ide-react/scope-adapters/editor-manager-context-adapter'
|
||||
import { postJSON } from '@/infrastructure/fetch-json'
|
||||
import { ReactScopeEventEmitter } from '@/features/ide-react/scope-event-emitter/react-scope-event-emitter'
|
||||
@@ -157,11 +156,11 @@ export const IdeReactProvider: FC<React.PropsWithChildren> = ({ children }) => {
|
||||
|
||||
const ide = useMemo(() => {
|
||||
return {
|
||||
...getMockIde(),
|
||||
_id: projectId,
|
||||
socket,
|
||||
reportError,
|
||||
}
|
||||
}, [socket, reportError])
|
||||
}, [projectId, socket, reportError])
|
||||
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
|
||||
@@ -4,7 +4,6 @@ import { ScopeEventEmitter } from '../../../../types/ide/scope-event-emitter'
|
||||
import { Socket } from '@/features/ide-react/connection/types/socket'
|
||||
|
||||
export type Ide = {
|
||||
$scope: Record<string, any>
|
||||
socket: Socket
|
||||
}
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
import getMeta from '../../../utils/meta'
|
||||
|
||||
// When rendered without Angular, ide isn't defined. In that case we use
|
||||
// a mock object that only has the required properties to pass proptypes
|
||||
// checks and the values needed for the app. In the longer term, the mock
|
||||
// object will replace ide completely.
|
||||
export const getMockIde = () => {
|
||||
return {
|
||||
_id: getMeta('ol-project_id'),
|
||||
$scope: {
|
||||
$on: () => {},
|
||||
$watch: () => {},
|
||||
$applyAsync: () => {},
|
||||
user: {},
|
||||
project: {
|
||||
_id: getMeta('ol-project_id'),
|
||||
name: getMeta('ol-projectName'),
|
||||
rootDocId: '',
|
||||
members: [],
|
||||
invites: [],
|
||||
features: {
|
||||
collaborators: 0,
|
||||
compileGroup: 'standard',
|
||||
trackChangesVisible: false,
|
||||
references: false,
|
||||
mendeley: false,
|
||||
zotero: false,
|
||||
},
|
||||
publicAccessLevel: '',
|
||||
owner: {
|
||||
_id: '',
|
||||
email: '',
|
||||
},
|
||||
},
|
||||
permissionsLevel: 'readOnly',
|
||||
editor: {
|
||||
sharejs_doc: null,
|
||||
showSymbolPalette: false,
|
||||
toggleSymbolPalette: () => {},
|
||||
},
|
||||
ui: {
|
||||
view: 'pdf',
|
||||
chatOpen: false,
|
||||
reviewPanelOpen: false,
|
||||
leftMenuShown: false,
|
||||
pdfLayout: 'flat',
|
||||
},
|
||||
pdf: {
|
||||
uncompiled: true,
|
||||
logEntryAnnotations: {},
|
||||
},
|
||||
settings: { syntaxValidation: false, pdfViewer: 'pdfjs' },
|
||||
hasLintingError: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import React, { FC, useEffect, useState } from 'react'
|
||||
import { get } from 'lodash'
|
||||
import { User, UserId } from '../../../types/user'
|
||||
import { Project } from '../../../types/project'
|
||||
import {
|
||||
@@ -24,86 +23,68 @@ import { ReactContextRoot } from '@/features/ide-react/context/react-context-roo
|
||||
|
||||
const scopeWatchers: [string, (value: any) => void][] = []
|
||||
|
||||
const initialize = () => {
|
||||
const user: User = {
|
||||
id: 'story-user' as UserId,
|
||||
email: 'story-user@example.com',
|
||||
allowedFreeTrial: true,
|
||||
features: { dropbox: true, symbolPalette: true },
|
||||
}
|
||||
const user: User = {
|
||||
id: 'story-user' as UserId,
|
||||
email: 'story-user@example.com',
|
||||
allowedFreeTrial: true,
|
||||
features: { dropbox: true, symbolPalette: true },
|
||||
}
|
||||
|
||||
const project: Project = {
|
||||
_id: '63e21c07946dd8c76505f85a',
|
||||
name: 'A Project',
|
||||
features: { mendeley: true, zotero: true, referencesSearch: true },
|
||||
tokens: {},
|
||||
owner: {
|
||||
_id: 'a-user',
|
||||
email: 'stories@overleaf.com',
|
||||
const project: Project = {
|
||||
_id: '63e21c07946dd8c76505f85a',
|
||||
name: 'A Project',
|
||||
features: { mendeley: true, zotero: true, referencesSearch: true },
|
||||
tokens: {},
|
||||
owner: {
|
||||
_id: 'a-user',
|
||||
email: 'stories@overleaf.com',
|
||||
},
|
||||
members: [],
|
||||
invites: [],
|
||||
rootDoc_id: '5e74f1a7ce17ae0041dfd056',
|
||||
rootFolder: [
|
||||
{
|
||||
_id: 'root-folder-id',
|
||||
name: 'rootFolder',
|
||||
docs: [
|
||||
{ _id: 'test-file-id', name: 'testfile.tex' },
|
||||
{ _id: 'test-bib-file-id', name: 'testsources.bib' },
|
||||
],
|
||||
fileRefs: [{ _id: 'test-image-id', name: 'frog.jpg', hash: '42' }],
|
||||
folders: [],
|
||||
},
|
||||
members: [],
|
||||
invites: [],
|
||||
rootDoc_id: '5e74f1a7ce17ae0041dfd056',
|
||||
rootFolder: [
|
||||
{
|
||||
_id: 'root-folder-id',
|
||||
name: 'rootFolder',
|
||||
docs: [
|
||||
{ _id: 'test-file-id', name: 'testfile.tex' },
|
||||
{ _id: 'test-bib-file-id', name: 'testsources.bib' },
|
||||
],
|
||||
fileRefs: [{ _id: 'test-image-id', name: 'frog.jpg', hash: '42' }],
|
||||
folders: [],
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
const scope = {
|
||||
user,
|
||||
project,
|
||||
$watch: (key: string, callback: () => void) => {
|
||||
scopeWatchers.push([key, callback])
|
||||
const initialScope = {
|
||||
user,
|
||||
project,
|
||||
ui: {
|
||||
chatOpen: true,
|
||||
pdfLayout: 'flat',
|
||||
},
|
||||
settings: {
|
||||
pdfViewer: 'js',
|
||||
syntaxValidation: true,
|
||||
},
|
||||
editor: {
|
||||
richText: false,
|
||||
sharejs_doc: {
|
||||
doc_id: 'test-doc',
|
||||
getSnapshot: () => 'some doc content',
|
||||
hasBufferedOps: () => false,
|
||||
},
|
||||
$applyAsync: (callback: () => void) => {
|
||||
window.setTimeout(() => {
|
||||
callback()
|
||||
for (const [key, watcher] of scopeWatchers) {
|
||||
watcher(get(ide.$scope, key))
|
||||
}
|
||||
}, 0)
|
||||
},
|
||||
$on: () => {
|
||||
//
|
||||
},
|
||||
$broadcast: () => {},
|
||||
ui: {
|
||||
chatOpen: true,
|
||||
pdfLayout: 'flat',
|
||||
},
|
||||
settings: {
|
||||
pdfViewer: 'js',
|
||||
syntaxValidation: true,
|
||||
},
|
||||
editor: {
|
||||
richText: false,
|
||||
sharejs_doc: {
|
||||
doc_id: 'test-doc',
|
||||
getSnapshot: () => 'some doc content',
|
||||
hasBufferedOps: () => false,
|
||||
},
|
||||
open_doc_name: 'testfile.tex',
|
||||
},
|
||||
hasLintingError: false,
|
||||
permissionsLevel: 'owner',
|
||||
}
|
||||
open_doc_name: 'testfile.tex',
|
||||
},
|
||||
hasLintingError: false,
|
||||
permissionsLevel: 'owner',
|
||||
}
|
||||
|
||||
const ide = {
|
||||
$scope: scope,
|
||||
socket: new SocketIOShim.SocketShimNoop(
|
||||
new SocketIOMock()
|
||||
) as unknown as Socket,
|
||||
}
|
||||
const socket = new SocketIOShim.SocketShimNoop(
|
||||
new SocketIOMock()
|
||||
) as unknown as Socket
|
||||
|
||||
const initializeMetaTags = () => {
|
||||
// window.metaAttributesCache is reset in preview.tsx
|
||||
window.metaAttributesCache.set('ol-user', user)
|
||||
window.metaAttributesCache.set('ol-project_id', project._id)
|
||||
@@ -111,8 +92,6 @@ const initialize = () => {
|
||||
'ol-gitBridgePublicBaseUrl',
|
||||
'https://git.stories.com'
|
||||
)
|
||||
|
||||
window._ide = ide
|
||||
}
|
||||
|
||||
type ScopeDecoratorOptions = {
|
||||
@@ -125,7 +104,7 @@ export const ScopeDecorator = (
|
||||
opts: ScopeDecoratorOptions = { mockCompileOnLoad: true },
|
||||
meta: Record<string, any> = {}
|
||||
) => {
|
||||
initialize()
|
||||
initializeMetaTags()
|
||||
|
||||
// mock compile on load
|
||||
useFetchMock(fetchMock => {
|
||||
@@ -171,7 +150,7 @@ const ConnectionProvider: FC<React.PropsWithChildren> = ({ children }) => {
|
||||
error: '',
|
||||
}
|
||||
return {
|
||||
socket: window._ide.socket as Socket,
|
||||
socket,
|
||||
connectionState,
|
||||
isConnected: true,
|
||||
isStillReconnecting: false,
|
||||
@@ -215,9 +194,8 @@ const IdeReactProvider: FC<React.PropsWithChildren> = ({ children }) => {
|
||||
}))
|
||||
|
||||
const [ideContextValue] = useState(() => {
|
||||
const ide = window._ide
|
||||
const scopeStore = createReactScopeValueStore(projectId)
|
||||
for (const [key, value] of Object.entries(ide.$scope)) {
|
||||
for (const [key, value] of Object.entries(initialScope)) {
|
||||
scopeStore.set(key, value)
|
||||
}
|
||||
const scopeEventEmitter = new ReactScopeEventEmitter(new IdeEventEmitter())
|
||||
@@ -231,7 +209,7 @@ const IdeReactProvider: FC<React.PropsWithChildren> = ({ children }) => {
|
||||
}
|
||||
|
||||
return {
|
||||
...ide,
|
||||
socket,
|
||||
scopeStore,
|
||||
scopeEventEmitter,
|
||||
}
|
||||
|
||||
@@ -7,10 +7,7 @@ import {
|
||||
import fetchMock from 'fetch-mock'
|
||||
|
||||
import ChatPane from '../../../../../frontend/js/features/chat/components/chat-pane'
|
||||
import {
|
||||
cleanUpContext,
|
||||
renderWithEditorContext,
|
||||
} from '../../../helpers/render-with-context'
|
||||
import { renderWithEditorContext } from '../../../helpers/render-with-context'
|
||||
import { stubMathJax, tearDownMathJaxStubs } from './stubs'
|
||||
|
||||
describe('<ChatPane />', function () {
|
||||
@@ -47,8 +44,6 @@ describe('<ChatPane />', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
fetchMock.removeRoutes().clearHistory()
|
||||
cleanUpContext()
|
||||
|
||||
stubMathJax()
|
||||
})
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
useChatContext,
|
||||
chatClientIdGenerator,
|
||||
} from '@/features/chat/context/chat-context'
|
||||
import { cleanUpContext } from '../../../helpers/render-with-context'
|
||||
import { stubMathJax, tearDownMathJaxStubs } from '../components/stubs'
|
||||
import { SocketIOMock } from '@/ide/connection/SocketIoShim'
|
||||
import { EditorProviders } from '../../../helpers/editor-providers'
|
||||
@@ -24,7 +23,6 @@ describe('ChatContext', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
fetchMock.removeRoutes().clearHistory()
|
||||
cleanUpContext()
|
||||
|
||||
stubMathJax()
|
||||
|
||||
|
||||
@@ -5,10 +5,7 @@ import fetchMock from 'fetch-mock'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import ShareProjectModal from '../../../../../frontend/js/features/share-project-modal/components/share-project-modal'
|
||||
import {
|
||||
renderWithEditorContext,
|
||||
cleanUpContext,
|
||||
} from '../../../helpers/render-with-context'
|
||||
import { renderWithEditorContext } from '../../../helpers/render-with-context'
|
||||
import {
|
||||
EditorProviders,
|
||||
USER_EMAIL,
|
||||
@@ -100,7 +97,6 @@ describe('<ShareProjectModal/>', function () {
|
||||
afterEach(function () {
|
||||
this.locationWrapperSandbox.restore()
|
||||
fetchMock.removeRoutes().clearHistory()
|
||||
cleanUpContext()
|
||||
})
|
||||
|
||||
it('renders the modal', async function () {
|
||||
|
||||
@@ -12,7 +12,7 @@ describe('<WordCountModal />', function () {
|
||||
})
|
||||
|
||||
cy.mount(
|
||||
<EditorProviders projectId="project-1" clsiServerId="clsi-server-1">
|
||||
<EditorProviders projectId="project-1">
|
||||
<WordCountModal show handleHide={cy.stub()} />
|
||||
</EditorProviders>
|
||||
)
|
||||
@@ -30,7 +30,7 @@ describe('<WordCountModal />', function () {
|
||||
})
|
||||
|
||||
cy.mount(
|
||||
<EditorProviders projectId="project-1" clsiServerId="clsi-server-1">
|
||||
<EditorProviders projectId="project-1">
|
||||
<WordCountModal show handleHide={cy.stub()} />
|
||||
</EditorProviders>
|
||||
)
|
||||
@@ -48,7 +48,7 @@ describe('<WordCountModal />', function () {
|
||||
})
|
||||
|
||||
cy.mount(
|
||||
<EditorProviders projectId="project-1" clsiServerId="clsi-server-1">
|
||||
<EditorProviders projectId="project-1">
|
||||
<WordCountModal show handleHide={cy.stub()} />
|
||||
</EditorProviders>
|
||||
)
|
||||
@@ -64,7 +64,7 @@ describe('<WordCountModal />', function () {
|
||||
})
|
||||
|
||||
cy.mount(
|
||||
<EditorProviders projectId="project-1" clsiServerId="clsi-server-1">
|
||||
<EditorProviders projectId="project-1">
|
||||
<WordCountModal show handleHide={cy.stub()} />
|
||||
</EditorProviders>
|
||||
)
|
||||
@@ -87,7 +87,7 @@ describe('<WordCountModal />', function () {
|
||||
})
|
||||
|
||||
cy.mount(
|
||||
<EditorProviders projectId="project-1" clsiServerId="clsi-server-1">
|
||||
<EditorProviders projectId="project-1">
|
||||
<WordCountModal show handleHide={cy.stub()} />
|
||||
</EditorProviders>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Disable prop type checks for test harnesses
|
||||
/* eslint-disable react/prop-types */
|
||||
import sinon from 'sinon'
|
||||
import { get, merge } from 'lodash'
|
||||
import { merge } from 'lodash'
|
||||
import { SocketIOMock } from '@/ide/connection/SocketIoShim'
|
||||
import { IdeContext } from '@/shared/context/ide-context'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
@@ -48,8 +47,7 @@ export function EditorProviders({
|
||||
compiler = 'pdflatex',
|
||||
socket = new SocketIOMock(),
|
||||
isRestrictedTokenMember = false,
|
||||
clsiServerId = '1234',
|
||||
scope = {},
|
||||
scope: defaultScope = {},
|
||||
features = {
|
||||
referencesSearch: true,
|
||||
},
|
||||
@@ -71,18 +69,6 @@ export function EditorProviders({
|
||||
},
|
||||
],
|
||||
ui = { view: 'editor', pdfLayout: 'sideBySide', chatOpen: true },
|
||||
fileTreeManager = {
|
||||
findEntityById: () => null,
|
||||
findEntityByPath: () => null,
|
||||
getEntityPath: () => '',
|
||||
getRootDocDirname: () => '',
|
||||
getPreviewByPath: path => ({ url: path, extension: 'png' }),
|
||||
},
|
||||
editorManager = {
|
||||
getCurrentDocumentId: () => 'foo',
|
||||
getCurrentDocValue: () => {},
|
||||
openDoc: sinon.stub(),
|
||||
},
|
||||
userSettings = {},
|
||||
providers = {},
|
||||
}) {
|
||||
@@ -99,7 +85,7 @@ export function EditorProviders({
|
||||
merge({}, defaultUserSettings, userSettings)
|
||||
)
|
||||
|
||||
const $scope = merge(
|
||||
const scope = merge(
|
||||
{
|
||||
user,
|
||||
editor: {
|
||||
@@ -123,25 +109,11 @@ export function EditorProviders({
|
||||
compiler,
|
||||
},
|
||||
ui,
|
||||
$watch: (path, callback) => {
|
||||
callback(get($scope, path))
|
||||
return () => null
|
||||
},
|
||||
$on: sinon.stub(),
|
||||
$applyAsync: sinon.stub(),
|
||||
permissionsLevel,
|
||||
},
|
||||
scope
|
||||
defaultScope
|
||||
)
|
||||
|
||||
window._ide = {
|
||||
$scope,
|
||||
socket,
|
||||
clsiServerId,
|
||||
editorManager,
|
||||
fileTreeManager,
|
||||
}
|
||||
|
||||
// Add details for useUserContext
|
||||
window.metaAttributesCache.set('ol-user', { ...user, features })
|
||||
window.metaAttributesCache.set('ol-project_id', projectId)
|
||||
@@ -149,8 +121,8 @@ export function EditorProviders({
|
||||
return (
|
||||
<ReactContextRoot
|
||||
providers={{
|
||||
ConnectionProvider,
|
||||
IdeReactProvider,
|
||||
ConnectionProvider: makeConnectionProvider(socket),
|
||||
IdeReactProvider: makeIdeReactProvider(scope, socket),
|
||||
...providers,
|
||||
}}
|
||||
>
|
||||
@@ -159,79 +131,85 @@ export function EditorProviders({
|
||||
)
|
||||
}
|
||||
|
||||
const ConnectionProvider = ({ children }) => {
|
||||
const [value] = useState(() => ({
|
||||
socket: window._ide.socket,
|
||||
connectionState: {
|
||||
readyState: WebSocket.OPEN,
|
||||
forceDisconnected: false,
|
||||
inactiveDisconnect: false,
|
||||
reconnectAt: null,
|
||||
forcedDisconnectDelay: 0,
|
||||
lastConnectionAttempt: 0,
|
||||
error: '',
|
||||
},
|
||||
isConnected: true,
|
||||
isStillReconnecting: false,
|
||||
secondsUntilReconnect: () => 0,
|
||||
tryReconnectNow: () => {},
|
||||
registerUserActivity: () => {},
|
||||
disconnect: () => {},
|
||||
}))
|
||||
|
||||
return (
|
||||
<ConnectionContext.Provider value={value}>
|
||||
{children}
|
||||
</ConnectionContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
const IdeReactProvider = ({ children }) => {
|
||||
const [startedFreeTrial, setStartedFreeTrial] = useState(false)
|
||||
|
||||
const [ideReactContextValue] = useState(() => ({
|
||||
projectId: PROJECT_ID,
|
||||
eventEmitter: new IdeEventEmitter(),
|
||||
startedFreeTrial,
|
||||
setStartedFreeTrial,
|
||||
reportError: () => {},
|
||||
projectJoined: true,
|
||||
}))
|
||||
|
||||
const [ideContextValue] = useState(() => {
|
||||
const ide = window._ide
|
||||
|
||||
const scopeStore = createReactScopeValueStore(PROJECT_ID)
|
||||
for (const [key, value] of Object.entries(ide.$scope)) {
|
||||
// TODO: path for nested entries
|
||||
scopeStore.set(key, value)
|
||||
}
|
||||
scopeStore.set('editor.sharejs_doc', ide.$scope.editor.sharejs_doc)
|
||||
scopeStore.set('ui.chatOpen', ide.$scope.ui.chatOpen)
|
||||
const scopeEventEmitter = new ReactScopeEventEmitter(new IdeEventEmitter())
|
||||
|
||||
return {
|
||||
...ide,
|
||||
scopeStore,
|
||||
scopeEventEmitter,
|
||||
}
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
window.overleaf = {
|
||||
...window.overleaf,
|
||||
unstable: {
|
||||
...window.overleaf?.unstable,
|
||||
store: ideContextValue.scopeStore,
|
||||
const makeConnectionProvider = socket => {
|
||||
const ConnectionProvider = ({ children }) => {
|
||||
const [value] = useState(() => ({
|
||||
socket,
|
||||
connectionState: {
|
||||
readyState: WebSocket.OPEN,
|
||||
forceDisconnected: false,
|
||||
inactiveDisconnect: false,
|
||||
reconnectAt: null,
|
||||
forcedDisconnectDelay: 0,
|
||||
lastConnectionAttempt: 0,
|
||||
error: '',
|
||||
},
|
||||
}
|
||||
}, [ideContextValue.scopeStore])
|
||||
isConnected: true,
|
||||
isStillReconnecting: false,
|
||||
secondsUntilReconnect: () => 0,
|
||||
tryReconnectNow: () => {},
|
||||
registerUserActivity: () => {},
|
||||
disconnect: () => {},
|
||||
}))
|
||||
|
||||
return (
|
||||
<IdeReactContext.Provider value={ideReactContextValue}>
|
||||
<IdeContext.Provider value={ideContextValue}>
|
||||
return (
|
||||
<ConnectionContext.Provider value={value}>
|
||||
{children}
|
||||
</IdeContext.Provider>
|
||||
</IdeReactContext.Provider>
|
||||
)
|
||||
</ConnectionContext.Provider>
|
||||
)
|
||||
}
|
||||
return ConnectionProvider
|
||||
}
|
||||
|
||||
const makeIdeReactProvider = (scope, socket) => {
|
||||
const IdeReactProvider = ({ children }) => {
|
||||
const [startedFreeTrial, setStartedFreeTrial] = useState(false)
|
||||
|
||||
const [ideReactContextValue] = useState(() => ({
|
||||
projectId: PROJECT_ID,
|
||||
eventEmitter: new IdeEventEmitter(),
|
||||
startedFreeTrial,
|
||||
setStartedFreeTrial,
|
||||
reportError: () => {},
|
||||
projectJoined: true,
|
||||
}))
|
||||
|
||||
const [ideContextValue] = useState(() => {
|
||||
const scopeStore = createReactScopeValueStore(PROJECT_ID)
|
||||
for (const [key, value] of Object.entries(scope)) {
|
||||
// TODO: path for nested entries
|
||||
scopeStore.set(key, value)
|
||||
}
|
||||
scopeStore.set('editor.sharejs_doc', scope.editor.sharejs_doc)
|
||||
scopeStore.set('ui.chatOpen', scope.ui.chatOpen)
|
||||
const scopeEventEmitter = new ReactScopeEventEmitter(
|
||||
new IdeEventEmitter()
|
||||
)
|
||||
|
||||
return {
|
||||
socket,
|
||||
scopeStore,
|
||||
scopeEventEmitter,
|
||||
}
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
window.overleaf = {
|
||||
...window.overleaf,
|
||||
unstable: {
|
||||
...window.overleaf?.unstable,
|
||||
store: ideContextValue.scopeStore,
|
||||
},
|
||||
}
|
||||
}, [ideContextValue.scopeStore])
|
||||
|
||||
return (
|
||||
<IdeReactContext.Provider value={ideReactContextValue}>
|
||||
<IdeContext.Provider value={ideContextValue}>
|
||||
{children}
|
||||
</IdeContext.Provider>
|
||||
</IdeReactContext.Provider>
|
||||
)
|
||||
}
|
||||
return IdeReactProvider
|
||||
}
|
||||
|
||||
@@ -18,7 +18,3 @@ export function renderWithEditorContext(
|
||||
...renderOptions,
|
||||
})
|
||||
}
|
||||
|
||||
export function cleanUpContext() {
|
||||
delete window._ide
|
||||
}
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
import 'recurly__recurly-js'
|
||||
import { ScopeValueStore } from './ide/scope-value-store'
|
||||
import { MetaAttributesCache } from '@/utils/meta'
|
||||
import { Socket } from '@/features/ide-react/connection/types/socket'
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
interface Window {
|
||||
metaAttributesCache: MetaAttributesCache
|
||||
_ide: Record<string, unknown> & {
|
||||
$scope: Record<string, unknown> & {
|
||||
pdf?: {
|
||||
logEntryAnnotations: Record<string, unknown>
|
||||
}
|
||||
}
|
||||
socket: Socket
|
||||
}
|
||||
MathJax: Record<string, any>
|
||||
// For react-google-recaptcha
|
||||
recaptchaOptions?: {
|
||||
|
||||
Reference in New Issue
Block a user