From 42f809f6d4d50b3db0a5f44bff7c0e79ea04c32d Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Thu, 21 Nov 2024 10:43:01 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F(frontend)=20get=20collaborat?= =?UTF-8?q?ion=20server=20url=20from=20config=20endpoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We centralized the configuration on the backend side, it is easier to manage and we can change the configuration without having to rebuild the frontend. We now use the config endpoint to get the collaboration server url, we refacto to remove the frontend env occurences and to adapt with the new way to get the collaboration server url. --- src/frontend/Dockerfile | 3 --- .../e2e/__tests__/app-impress/config.spec.ts | 22 +++++++++++++++++++ src/frontend/apps/impress/.env | 1 - src/frontend/apps/impress/.env.development | 1 - src/frontend/apps/impress/src/core/conf.ts | 8 ------- .../impress/src/core/config/hooks/index.ts | 1 + .../core/config/hooks/useCollaborationUrl.tsx | 15 +++++++++++++ src/frontend/apps/impress/src/core/index.ts | 1 + .../apps/impress/src/custom-next.d.ts | 1 - .../docs/doc-editor/components/DocEditor.tsx | 8 ++++--- .../doc-management/stores/useDocStore.tsx | 11 ++++++---- .../impress/src/pages/docs/[id]/index.tsx | 8 ++++--- 12 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 src/frontend/apps/impress/src/core/config/hooks/useCollaborationUrl.tsx diff --git a/src/frontend/Dockerfile b/src/frontend/Dockerfile index 972c7160..8a179a9a 100644 --- a/src/frontend/Dockerfile +++ b/src/frontend/Dockerfile @@ -61,9 +61,6 @@ FROM impress AS impress-builder WORKDIR /home/frontend/apps/impress -ARG Y_PROVIDER_URL -ENV NEXT_PUBLIC_Y_PROVIDER_URL=${Y_PROVIDER_URL} - ARG API_ORIGIN ENV NEXT_PUBLIC_API_ORIGIN=${API_ORIGIN} diff --git a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts index 5e63d5a2..2ae8746f 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts @@ -110,4 +110,26 @@ test.describe('Config', () => { /http:\/\/localhost:8083\/media\/.*\/attachments\/.*.png/, ); }); + + test('it checks that collaboration server is configured from config endpoint', async ({ + page, + browserName, + }) => { + const webSocketPromise = page.waitForEvent('websocket', (webSocket) => { + return webSocket.url().includes('ws://localhost:4444/'); + }); + + await page.goto('/'); + + const randomDoc = await createDoc( + page, + 'doc-collaboration', + browserName, + 1, + ); + await expect(page.locator('h2').getByText(randomDoc[0])).toBeVisible(); + + const webSocket = await webSocketPromise; + expect(webSocket.url()).toContain('ws://localhost:4444/'); + }); }); diff --git a/src/frontend/apps/impress/.env b/src/frontend/apps/impress/.env index afe20085..3cf0e897 100644 --- a/src/frontend/apps/impress/.env +++ b/src/frontend/apps/impress/.env @@ -1,3 +1,2 @@ NEXT_PUBLIC_API_ORIGIN= -NEXT_PUBLIC_Y_PROVIDER_URL= NEXT_PUBLIC_SW_DEACTIVATED= diff --git a/src/frontend/apps/impress/.env.development b/src/frontend/apps/impress/.env.development index e174f537..f26afb11 100644 --- a/src/frontend/apps/impress/.env.development +++ b/src/frontend/apps/impress/.env.development @@ -1,3 +1,2 @@ NEXT_PUBLIC_API_ORIGIN=http://localhost:8071 -NEXT_PUBLIC_Y_PROVIDER_URL=ws://localhost:4444 NEXT_PUBLIC_SW_DEACTIVATED=true diff --git a/src/frontend/apps/impress/src/core/conf.ts b/src/frontend/apps/impress/src/core/conf.ts index 1424dfa6..118f5814 100644 --- a/src/frontend/apps/impress/src/core/conf.ts +++ b/src/frontend/apps/impress/src/core/conf.ts @@ -4,11 +4,3 @@ export const backendUrl = () => export const baseApiUrl = (apiVersion: string = '1.0') => `${backendUrl()}/api/v${apiVersion}/`; - -export const providerUrl = (docId: string) => { - const base = - process.env.NEXT_PUBLIC_Y_PROVIDER_URL || - (typeof window !== 'undefined' ? `wss://${window.location.host}/ws` : ''); - - return `${base}/${docId}`; -}; diff --git a/src/frontend/apps/impress/src/core/config/hooks/index.ts b/src/frontend/apps/impress/src/core/config/hooks/index.ts index 41d6d8de..e1b2dff2 100644 --- a/src/frontend/apps/impress/src/core/config/hooks/index.ts +++ b/src/frontend/apps/impress/src/core/config/hooks/index.ts @@ -1 +1,2 @@ export * from './useMediaUrl'; +export * from './useCollaborationUrl'; diff --git a/src/frontend/apps/impress/src/core/config/hooks/useCollaborationUrl.tsx b/src/frontend/apps/impress/src/core/config/hooks/useCollaborationUrl.tsx new file mode 100644 index 00000000..d945cb23 --- /dev/null +++ b/src/frontend/apps/impress/src/core/config/hooks/useCollaborationUrl.tsx @@ -0,0 +1,15 @@ +import { useConfig } from '../api'; + +export const useCollaborationUrl = (room?: string) => { + const { data: conf } = useConfig(); + + if (!room) { + return; + } + + const base = + conf?.COLLABORATION_SERVER_URL || + (typeof window !== 'undefined' ? `wss://${window.location.host}/ws` : ''); + + return `${base}/${room}`; +}; diff --git a/src/frontend/apps/impress/src/core/index.ts b/src/frontend/apps/impress/src/core/index.ts index 97ec4897..99176076 100644 --- a/src/frontend/apps/impress/src/core/index.ts +++ b/src/frontend/apps/impress/src/core/index.ts @@ -1,3 +1,4 @@ export * from './AppProvider'; export * from './auth'; export * from './conf'; +export * from './config'; diff --git a/src/frontend/apps/impress/src/custom-next.d.ts b/src/frontend/apps/impress/src/custom-next.d.ts index 9dadec0c..2f5af638 100644 --- a/src/frontend/apps/impress/src/custom-next.d.ts +++ b/src/frontend/apps/impress/src/custom-next.d.ts @@ -20,7 +20,6 @@ declare module '*.svg?url' { namespace NodeJS { interface ProcessEnv { NEXT_PUBLIC_API_ORIGIN?: string; - NEXT_PUBLIC_Y_PROVIDER_URL?: string; NEXT_PUBLIC_SW_DEACTIVATED?: string; } } diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx index a664eb35..50b2b73a 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/DocEditor.tsx @@ -4,6 +4,7 @@ import React, { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { Box, Card, Text, TextErrors } from '@/components'; +import { useCollaborationUrl } from '@/core'; import { useCunninghamTheme } from '@/cunningham'; import { DocHeader } from '@/features/docs/doc-header'; import { Doc, useDocStore } from '@/features/docs/doc-management'; @@ -98,19 +99,20 @@ export const DocVersionEditor = ({ doc, versionId }: DocVersionEditorProps) => { versionId, }); const { createProvider, providers } = useDocStore(); + const collaborationUrl = useCollaborationUrl(versionId); const { replace } = useRouter(); useEffect(() => { - if (!version?.id) { + if (!version?.id || !collaborationUrl) { return; } const provider = providers?.[version.id]; if (!provider || provider.document.guid !== version.id) { - createProvider(version.id, version.content); + createProvider(collaborationUrl, version.id, version.content); } - }, [createProvider, providers, version]); + }, [createProvider, providers, version, collaborationUrl]); if (isError && error) { if (error.status === 404) { diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/stores/useDocStore.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/stores/useDocStore.tsx index 3bc2a95c..3b01ecc0 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-management/stores/useDocStore.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/stores/useDocStore.tsx @@ -2,7 +2,6 @@ import { HocuspocusProvider } from '@hocuspocus/provider'; import * as Y from 'yjs'; import { create } from 'zustand'; -import { providerUrl } from '@/core'; import { Base64, Doc, blocksToYDoc } from '@/features/docs/doc-management'; export interface UseDocStore { @@ -10,7 +9,11 @@ export interface UseDocStore { providers: { [storeId: string]: HocuspocusProvider; }; - createProvider: (storeId: string, initialDoc: Base64) => HocuspocusProvider; + createProvider: ( + providerUrl: string, + storeId: string, + initialDoc: Base64, + ) => HocuspocusProvider; setProviders: (storeId: string, providers: HocuspocusProvider) => void; setCurrentDoc: (doc: Doc | undefined) => void; } @@ -18,7 +21,7 @@ export interface UseDocStore { export const useDocStore = create((set, get) => ({ currentDoc: undefined, providers: {}, - createProvider: (storeId: string, initialDoc: Base64) => { + createProvider: (providerUrl, storeId, initialDoc) => { const doc = new Y.Doc({ guid: storeId, }); @@ -37,7 +40,7 @@ export const useDocStore = create((set, get) => ({ } const provider = new HocuspocusProvider({ - url: providerUrl(storeId), + url: providerUrl, name: storeId, document: doc, }); diff --git a/src/frontend/apps/impress/src/pages/docs/[id]/index.tsx b/src/frontend/apps/impress/src/pages/docs/[id]/index.tsx index 7ea5fd50..92410f8e 100644 --- a/src/frontend/apps/impress/src/pages/docs/[id]/index.tsx +++ b/src/frontend/apps/impress/src/pages/docs/[id]/index.tsx @@ -6,6 +6,7 @@ import { useEffect, useState } from 'react'; import { Box, Text } from '@/components'; import { TextErrors } from '@/components/TextErrors'; +import { useCollaborationUrl } from '@/core'; import { useAuthStore } from '@/core/auth'; import { DocEditor } from '@/features/docs/doc-editor'; import { KEY_DOC, useDoc, useDocStore } from '@/features/docs/doc-management'; @@ -47,6 +48,7 @@ const DocPage = ({ id }: DocProps) => { const queryClient = useQueryClient(); const { replace } = useRouter(); const provider = providers?.[id]; + const collaborationUrl = useCollaborationUrl(doc?.id); useEffect(() => { if (doc?.title) { @@ -70,17 +72,17 @@ const DocPage = ({ id }: DocProps) => { }, [docQuery, setCurrentDoc]); useEffect(() => { - if (!doc?.id) { + if (!doc?.id || !collaborationUrl) { return; } let newProvider = provider; if (!provider || provider.document.guid !== doc.id) { - newProvider = createProvider(doc.id, doc.content); + newProvider = createProvider(collaborationUrl, doc.id, doc.content); } setBroadcastProvider(newProvider); - }, [createProvider, doc, provider, setBroadcastProvider]); + }, [createProvider, doc, provider, setBroadcastProvider, collaborationUrl]); /** * We add a broadcast task to reset the query cache