Skip to content

Commit

Permalink
Merge pull request #37 from SuperViz/lab
Browse files Browse the repository at this point in the history
Lab
  • Loading branch information
carlossantos74 authored Oct 3, 2024
2 parents 9a3f9ab + 1fc233e commit 269180a
Show file tree
Hide file tree
Showing 75 changed files with 3,695 additions and 9,093 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,14 @@ jobs:
env:
NPM_CONFIG_USERCONFIG: .npmrc.ci
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Create a .version.js file
run: |
touch packages/realtime/.version.js && echo "echo \"export const version = 'test'\" > packages/realtime/.version.js" | bash -
touch packages/sdk/.version.js && echo "echo \"export const version = 'test'\" > packages/sdk/.version.js" | bash -
- name: Create a .remote-config.js file
run: |
touch packages/realtime/.remote-config.js && echo "echo \"module.exports = { remoteConfig: { apiUrl: 'https://dev.nodeapi.superviz.com' }};\" > packages/realtime/.remote-config.js" | bash -
touch packages/sdk/.remote-config.js && echo "echo \"module.exports = { remoteConfig: { apiUrl: 'https://dev.nodeapi.superviz.com', conferenceLayerUrl: 'https://video-frame.superviz.com/lab/index.html'}};\" > .remote-config.js" | bash -
- name: Run tests
run: pnpm run test:unit:ci --filter=@superviz/yjs
- name: Post PR Comment
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/playground.ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ on:
- 'packages/matterport/**'
- 'packages/autodesk/**'
- 'packages/three/**'
- 'packages/yjs/**'
- '.github/workflows/playground.ci.yml'
jobs:
package:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/socket-client.ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ on:
- beta
- main
paths:
- 'packages/socket-client/**'
- '.github/workflows/socket-client.ci.yml'
- "packages/socket-client/**"
- ".github/workflows/socket-client.ci.yml"
jobs:
package:
runs-on: ubuntu-latest
Expand All @@ -24,7 +24,7 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'
cache: "pnpm"
- name: Install dependencies
run: pnpm install --no-frozen-lockfile
env:
Expand All @@ -50,4 +50,4 @@ jobs:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_ICON: https://avatars.slack-edge.com/2020-11-18/1496892993975_af721d1c045bea2d5a46_48.png
MSG_MINIMAL: true
SLACK_USERNAME: Deploy socket client version ${{ github.ref_name }}
SLACK_USERNAME: Deploy socket client version ${{ github.ref_name }}
54 changes: 54 additions & 0 deletions .github/workflows/yjs.ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Yjs Provider - Publish Package
on:
push:
branches:
- lab
- beta
- main
paths:
- "packages/yjs/**"
- "packages/semantic-release-version-file/**"
- ".github/workflows/yjs.ci.yml"
jobs:
package:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20]
steps:
- uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 9.10.0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: "pnpm"
- name: Install dependencies
run: pnpm install --no-frozen-lockfile
env:
NPM_CONFIG_USERCONFIG: .npmrc.ci
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- run: git config --global user.name SuperViz
- run: git config --global user.email ci@superviz.com
- name: Publish npm package
run: npm whoami && pnpm run semantic-release --filter=@superviz/yjs
env:
NPM_CONFIG_USERCONFIG: .npmrc.ci
GITHUB_TOKEN: ${{ secrets.TOKEN_GITHUB }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
slack:
needs: package
name: Slack Notification
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Slack Notification
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_ICON: https://avatars.slack-edge.com/2020-11-18/1496892993975_af721d1c045bea2d5a46_48.png
MSG_MINIMAL: true
SLACK_USERNAME: Deploy yjs provider version ${{ github.ref_name }}
9 changes: 9 additions & 0 deletions apps/playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,30 @@
"preview": "vite preview"
},
"dependencies": {
"@monaco-editor/react": "^4.6.0",
"@superviz/autodesk-viewer-plugin": "workspace:*",
"@superviz/matterport-plugin": "workspace:*",
"@superviz/realtime": "workspace:*",
"@superviz/sdk": "workspace:*",
"@superviz/threejs-plugin": "workspace:*",
"@superviz/yjs": "workspace:*",
"@types/three": "^0.167.1",
"lib0": "^0.2.97",
"lodash": "^4.17.21",
"monaco-editor": "^0.51.0",
"quill-cursors": "^4.0.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-helmet-async": "^2.0.5",
"react-quill-new": "^3.3.2",
"react-router-dom": "^6.26.1",
"three": "0.167.1",
"three-mesh-bvh": "^0.7.8",
"uuid": "^10.0.0",
"y-monaco": "^0.1.6",
"y-protocols": "^1.0.6",
"y-quill": "^1.0.0",
"yjs": "^13.3.1",
"zod": "^3.23.8"
},
"devDependencies": {
Expand Down
1 change: 1 addition & 0 deletions apps/playground/src/lib/sdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export {
MousePointers,
ParticipantType,
type LauncherFacade,
type Participant,
} from "@superviz/sdk";
207 changes: 207 additions & 0 deletions apps/playground/src/pages/yjs-monaco-wio.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { v4 as generateId } from "uuid";

import { getConfig } from "../config";

import * as Y from "yjs";
import { SuperVizYjsProvider } from "@superviz/yjs";

import { MonacoBinding } from "y-monaco";
import "../styles/yjs.css";
import {
Room,
type LauncherFacade,
type Participant,
WhoIsOnline,
} from "../lib/sdk";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import Editor from "@monaco-editor/react";

const SUPERVIZ_KEY = getConfig<string>("keys.superviz");
const SUPERVIZ_ROOM_PREFIX = getConfig<string>("roomPrefix");

const componentName = "yjs-monaco-wio";

function setStyles(
states: Map<number, Record<string, any>>,
ids: Set<number>
): number[] {
const stylesheet = document.getElementById("sv-yjs-monaco");
let styles = "";

const idsList = [];
for (const [id, state] of states) {
if (ids.has(id) || !state.participant) continue;
idsList.push(id);

styles += `
.yRemoteSelection-${id},
.yRemoteSelectionHead-${id} {
--presence-color: ${state.participant.slot.color};
}
.yRemoteSelectionHead-${id}:after {
content: "${state.participant.name}";
--sv-text-color: ${state.participant.slot.textColor};
}
`;
}

stylesheet!.innerText = styles;

return idsList;
}

export function YjsMonacoWio() {
const ydoc = useMemo(() => new Y.Doc(), []);

const [editor, setEditor] = useState<any>(null);
const [localParticipant, setLocalParticipant] =
useState<Partial<Participant>>();
const [ids, setIds] = useState(new Set<number>());
const [joinedRoom, setJoinedRoom] = useState(false);

const room = useRef<LauncherFacade>();
const provider = useMemo<SuperVizYjsProvider>(
() => new SuperVizYjsProvider(ydoc),
[ydoc]
);
const wio = useRef<WhoIsOnline>();
const loaded = useRef(false);

const initializeSuperViz = useCallback(async () => {
if (loaded.current) return;
loaded.current = true;

const uuid = generateId();

room.current = await Room(SUPERVIZ_KEY, {
roomId: `${SUPERVIZ_ROOM_PREFIX}-${componentName}`,
participant: {
name: "Participant",
id: uuid,
},
group: {
name: SUPERVIZ_ROOM_PREFIX,
id: SUPERVIZ_ROOM_PREFIX,
},
environment: "dev",
debug: true,
});

wio.current = new WhoIsOnline();

room.current.subscribe("participant.updated", (data) => {
if (!data.slot?.index) return;

provider.awareness?.setLocalStateField("participant", {
id: data.id,
slot: data.slot,
name: data.name,
});

setLocalParticipant({
id: data.id,
slot: data.slot,
name: data.name,
});
});

const style = document.createElement("style");
style.id = "sv-yjs-monaco";
document.head.appendChild(style);
}, [provider.awareness]);

useEffect(() => {
initializeSuperViz();

return () => {
room.current?.removeComponent(wio.current);
room.current?.removeComponent(provider);
room.current?.destroy();
};
}, []);

const joinRoom = useCallback(() => {
if (joinedRoom || !room.current) return;
setJoinedRoom(true);

if (localParticipant) {
provider.awareness?.setLocalStateField("participant", localParticipant);
}

const updateStyles = () => {
const states = provider.awareness?.getStates();
const idsList = setStyles(states, ids);

setIds(new Set(idsList));
};

provider.on("connect", updateStyles);
provider.awareness?.on("update", updateStyles);
provider.awareness?.once("change", updateStyles);

room.current.addComponent(provider);
room.current.addComponent(wio.current);
}, [room, joinedRoom, setIds, ids, localParticipant, provider]);

const leaveRoom = useCallback(() => {
if (!joinedRoom || !room.current) return;
setJoinedRoom(false);

setIds(new Set());
room.current.removeComponent(wio.current);
room.current.removeComponent(provider);
}, [room, joinedRoom, provider]);

useEffect(() => {
if (!provider || editor == null) return;

const binding = new MonacoBinding(
ydoc.getText("monaco"),
editor.getModel()!,
new Set([editor]),
provider.awareness
);
return () => {
binding.destroy();
};
}, [ydoc, provider, editor]);

return (
<div className="p-5 h-full bg-gray-200 flex flex-col gap-5">
<div className="flex items-center w-full justify-center gap-10">
<button
onClick={joinRoom}
disabled={joinedRoom || !room}
className="bg-sv-purple text-white h-10 px-4 rounded-md hover:bg-sv-primary-900 transition-all duration-300 disabled:bg-sv-primary-200 disabled:cursor-not-allowed"
>
Join room
</button>
<button
onClick={leaveRoom}
disabled={!joinedRoom || !room}
className="text-sv-gray-400 border-sv-gray-400 border h-10 px-4 rounded-md hover:bg-sv-gray-400 hover:text-white transition-all duration-300 cursor-pointer disabled:bg-sv-gray-100 disabled:cursor-not-allowed disabled:text-sv-gray-400"
>
Leave room
</button>
</div>
<div className="bg-[#1e1e1e] shadow-none h-[90%] overflow-auto rounded-sm">
<div className="yRemoteSelectionHead"></div>
<Editor
defaultValue="// Connect to the room to start collaborating"
defaultLanguage="typescript"
onMount={(editor) => {
setEditor(editor);
}}
options={{
padding: {
top: 32,
},
}}
theme="vs-dark"
/>
</div>
</div>
);
}
Loading

0 comments on commit 269180a

Please sign in to comment.