Skip to content

Commit

Permalink
T
Browse files Browse the repository at this point in the history
  • Loading branch information
SebastianStehle committed Sep 28, 2023
1 parent c80dd68 commit 73c188a
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 146 deletions.
110 changes: 97 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"@ant-design/icons": "^4.7.0",
"@hocuspocus/provider": "^2.5.0",
"@marker.io/browser": "^0.18.0",
"@reduxjs/toolkit": "^1.7.1",
"@svgdotjs/svg.js": "^3.1.1",
Expand Down Expand Up @@ -31,8 +32,9 @@
"redux-thunk": "2.4.1",
"reselect": "4.1.5",
"tslib": "2.3.1",
"y-protocols": "^1.0.6",
"y-webrtc": "^10.2.5",
"yjs-redux": "^0.7.0"
"yjs-redux": "^0.9.0"
},
"scripts": {
"start": "node --max_old_space_size=6096 node_modules/webpack/bin/webpack.js serve --config config/webpack.config.js --port 3002 --hot --server-type https --server-options-pfx dev/squidex-dev.pfx --server-options-passphrase password",
Expand Down
4 changes: 4 additions & 0 deletions src/style/_common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ ul {
.share {
padding: 10px;

&.ant-menu {
line-height: 1rem;
}

.ant-input-group {
display: flex;
line-height: 1rem;
Expand Down
20 changes: 0 additions & 20 deletions src/wireframes/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,8 @@
* Copyright (c) Sebastian Stehle. All rights reserved.
*/

import { ClientToken } from '@y-sweet/sdk';

const API_URL = process.env.NODE_ENV === 'test_development' ? 'http://localhost:4000' : 'https://api.mydraft.cc';

export async function postCollaborationToken(id: string) {
const response = await fetch(`${API_URL}/session/${id}`, {
method: 'POST',
headers: {
ContentType: 'text/json',
},
body: JSON.stringify({}),
});

if (!response.ok) {
throw Error('Failed to fetch token');
}

const stored = await response.json();

return stored as ClientToken;
}

export async function getDiagram(readToken: string) {
const response = await fetch(`${API_URL}/${readToken}`);

Expand Down
41 changes: 14 additions & 27 deletions src/wireframes/collaboration/components/Provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
* Copyright (c) Sebastian Stehle. All rights reserved.
*/

import { createYjsProvider } from '@y-sweet/client';
import { TiptapCollabProvider } from '@hocuspocus/provider';
import * as React from 'react';
import * as Y from 'yjs';
import { useYjsReduxBinder } from 'yjs-redux';
import { useAsyncEffect } from '@app/core';
import { postCollaborationToken } from '@app/wireframes/api';
import { useStore } from '@app/wireframes/model';
import { CollaborationContext, CollaborationState } from './../hooks';

Expand All @@ -21,51 +20,39 @@ export const CollaborationProvider = (props: { children: React.ReactNode }) => {
const editorId = editor.id;

useAsyncEffect(async cancellation => {
const clientDoc = new Y.Doc();
const clientToken = await postCollaborationToken(editorId);

if (cancellation?.isCancelled) {
return undefined;
}

const provider = createYjsProvider(clientDoc, clientToken, {
disableBc: true,
});
const provider = new TiptapCollabProvider({ appId: '7ME5ZQMY', name: editorId });

provider.connect();

await new Promise(resolve => {
const handler = () => {
if (provider.wsconnected) {
if (!provider.hasUnsyncedChanges && provider.isConnected) {
resolve(true);
}
};

provider.on('status', handler);
provider.on('unsyncedChanges', handler);
});

if (cancellation?.isCancelled) {
return undefined;
}

const unbind = binder.connectSlice(clientDoc, 'editor',
root => {
setState(state => ({
...state,
undoManager: new Y.UndoManager(root),
}));
},
);
const synchronizer = binder.connectSlice(provider.document, 'editor');

setState({ document: clientDoc, provider });
synchronizer.on('connected', ({ root }) => {
setState(state => ({
...state,
undoManager: new Y.UndoManager(root),
}));
});

return () => {
clientDoc.destroy();
setState({ document: provider.document, provider });

return () => {
synchronizer.destroy();
provider.disconnect();
provider.destroy();

unbind();
};
}, [editorId, binder]);

Expand Down
22 changes: 8 additions & 14 deletions src/wireframes/collaboration/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface CollaborationState {
document?: Y.Doc;

// The actual provider.
provider?: { awareness: awarenessProtocol.Awareness; destroy: () => void };
provider?: { awareness: awarenessProtocol.Awareness | null; destroy: () => void };

// The undo managher
undoManager?: Y.UndoManager;
Expand Down Expand Up @@ -59,24 +59,18 @@ export const useUndoManager = () => {
};

export function usePresence(): Record<string, User> {
const provider = React.useContext(CollaborationContext).provider;
const awareness = React.useContext(CollaborationContext).provider?.awareness;
const [presence, setPresence] = React.useState<Record<string, User>>({});

React.useEffect(() => {
if (!provider?.awareness) {
if (!awareness) {
return () => {};
}

const roomName = provider['roomName'];

if (roomName) {
console.log(`Connecting presence to room name '${roomName}'.`);
}

const handler = () => {
const map: Record<string, User> = {};

provider.awareness.getStates().forEach(state => {
awareness.getStates().forEach(state => {
if (Object.keys(state).length > 0) {
const user = state as User;

Expand All @@ -87,13 +81,13 @@ export function usePresence(): Record<string, User> {
setPresence(map);
};

provider.awareness.on('change', handler);
provider.awareness.setLocalState(user);
awareness.on('change', handler);
awareness.setLocalState(user);

return () => {
provider.awareness.off('change', handler);
awareness.off('change', handler);
};
}, [provider]);
}, [awareness]);

return presence;
}
Loading

0 comments on commit 73c188a

Please sign in to comment.