♻️(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:
@@ -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}
|
||||
|
||||
|
||||
@@ -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/');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
NEXT_PUBLIC_API_ORIGIN=
|
||||
NEXT_PUBLIC_Y_PROVIDER_URL=
|
||||
NEXT_PUBLIC_SW_DEACTIVATED=
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
NEXT_PUBLIC_API_ORIGIN=http://localhost:8071
|
||||
NEXT_PUBLIC_Y_PROVIDER_URL=ws://localhost:4444
|
||||
NEXT_PUBLIC_SW_DEACTIVATED=true
|
||||
|
||||
@@ -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}`;
|
||||
};
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export * from './useMediaUrl';
|
||||
export * from './useCollaborationUrl';
|
||||
|
||||
@@ -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}`;
|
||||
};
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './AppProvider';
|
||||
export * from './auth';
|
||||
export * from './conf';
|
||||
export * from './config';
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user