♻️(frontend) get collaboration server url from config endpoint

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.
This commit is contained in:
Anthony LC
2024-11-21 10:43:01 +01:00
committed by Anthony LC
parent 7d64c82987
commit 42f809f6d4
12 changed files with 56 additions and 24 deletions

View File

@@ -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}

View File

@@ -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/');
});
});

View File

@@ -1,3 +1,2 @@
NEXT_PUBLIC_API_ORIGIN=
NEXT_PUBLIC_Y_PROVIDER_URL=
NEXT_PUBLIC_SW_DEACTIVATED=

View File

@@ -1,3 +1,2 @@
NEXT_PUBLIC_API_ORIGIN=http://localhost:8071
NEXT_PUBLIC_Y_PROVIDER_URL=ws://localhost:4444
NEXT_PUBLIC_SW_DEACTIVATED=true

View File

@@ -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}`;
};

View File

@@ -1 +1,2 @@
export * from './useMediaUrl';
export * from './useCollaborationUrl';

View File

@@ -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}`;
};

View File

@@ -1,3 +1,4 @@
export * from './AppProvider';
export * from './auth';
export * from './conf';
export * from './config';

View File

@@ -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;
}
}

View File

@@ -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) {

View File

@@ -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<UseDocStore>((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<UseDocStore>((set, get) => ({
}
const provider = new HocuspocusProvider({
url: providerUrl(storeId),
url: providerUrl,
name: storeId,
document: doc,
});

View File

@@ -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