Skip to content

Commit

Permalink
Support collaboration feature
Browse files Browse the repository at this point in the history
  • Loading branch information
msujew committed May 14, 2024
1 parent 38eb319 commit 4a746ed
Show file tree
Hide file tree
Showing 32 changed files with 1,887 additions and 35 deletions.
1 change: 1 addition & 0 deletions examples/browser-only/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@theia/api-samples": "1.49.0",
"@theia/bulk-edit": "1.49.0",
"@theia/callhierarchy": "1.49.0",
"@theia/collaboration": "1.49.0",
"@theia/console": "1.49.0",
"@theia/core": "1.49.0",
"@theia/debug": "1.49.0",
Expand Down
3 changes: 3 additions & 0 deletions examples/browser-only/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
{
"path": "../../packages/callhierarchy"
},
{
"path": "../../packages/collaboration"
},
{
"path": "../../packages/console"
},
Expand Down
1 change: 1 addition & 0 deletions examples/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@theia/api-samples": "1.49.0",
"@theia/bulk-edit": "1.49.0",
"@theia/callhierarchy": "1.49.0",
"@theia/collaboration": "1.49.0",
"@theia/console": "1.49.0",
"@theia/core": "1.49.0",
"@theia/debug": "1.49.0",
Expand Down
3 changes: 3 additions & 0 deletions examples/browser/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
{
"path": "../../packages/callhierarchy"
},
{
"path": "../../packages/collaboration"
},
{
"path": "../../packages/console"
},
Expand Down
1 change: 1 addition & 0 deletions examples/electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@theia/api-samples": "1.49.0",
"@theia/bulk-edit": "1.49.0",
"@theia/callhierarchy": "1.49.0",
"@theia/collaboration": "1.49.0",
"@theia/console": "1.49.0",
"@theia/core": "1.49.0",
"@theia/debug": "1.49.0",
Expand Down
3 changes: 3 additions & 0 deletions examples/electron/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
{
"path": "../../packages/callhierarchy"
},
{
"path": "../../packages/collaboration"
},
{
"path": "../../packages/console"
},
Expand Down
10 changes: 10 additions & 0 deletions packages/collaboration/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/** @type {import('eslint').Linter.Config} */
module.exports = {
extends: [
'../../configs/build.eslintrc.json'
],
parserOptions: {
tsconfigRootDir: __dirname,
project: 'tsconfig.json'
}
};
30 changes: 30 additions & 0 deletions packages/collaboration/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<div align='center'>

<br />

<img src='https://raw.githubusercontent.com/eclipse-theia/theia/master/logo/theia.svg?sanitize=true' alt='theia-ext-logo' width='100px' />

<h2>ECLIPSE THEIA - COLLABORATION EXTENSION</h2>

<hr />

</div>

## Description

The `@theia/collaboration` extension features to enable collaboration between multiple peers using Theia.

## Additional Information

- [API documentation for `@theia/collaboration`](https://eclipse-theia.github.io/theia/docs/next/modules/collaboration.html)
- [Theia - GitHub](https://github.com/eclipse-theia/theia)
- [Theia - Website](https://theia-ide.org/)

## License

- [Eclipse Public License 2.0](http://www.eclipse.org/legal/epl-2.0/)
- [一 (Secondary) GNU General Public License, version 2 with the GNU Classpath Exception](https://projects.eclipse.org/license/secondary-gpl-2.0-cp)

## Trademark
"Theia" is a trademark of the Eclipse Foundation
https://www.eclipse.org/theia
57 changes: 57 additions & 0 deletions packages/collaboration/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"name": "@theia/collaboration",
"version": "1.49.0",
"description": "Theia - Collaboration Extension",
"dependencies": {
"@theia/core": "1.49.0",
"@theia/editor": "1.49.0",
"@theia/filesystem": "1.49.0",
"@theia/monaco": "1.49.0",
"@theia/monaco-editor-core": "1.83.101",
"@theia/workspace": "1.49.0",
"open-collaboration-protocol": "0.0.7",
"open-collaboration-rpc": "0.0.6",
"socket.io-client": "^4.5.3",
"yjs": "^13.6.7",
"lib0": "^0.2.52",
"y-protocols": "^1.0.6"
},
"publishConfig": {
"access": "public"
},
"theiaExtensions": [
{
"frontend": "lib/browser/collaboration-frontend-module"
}
],
"keywords": [
"theia-extension"
],
"license": "EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0",
"repository": {
"type": "git",
"url": "https://github.com/eclipse-theia/theia.git"
},
"bugs": {
"url": "https://github.com/eclipse-theia/theia/issues"
},
"homepage": "https://github.com/eclipse-theia/theia",
"files": [
"lib",
"src"
],
"scripts": {
"build": "theiaext build",
"clean": "theiaext clean",
"compile": "theiaext compile",
"lint": "theiaext lint",
"test": "theiaext test",
"watch": "theiaext watch"
},
"devDependencies": {
"@theia/ext-scripts": "1.49.0"
},
"nyc": {
"extends": "../../configs/nyc.json"
}
}
76 changes: 76 additions & 0 deletions packages/collaboration/src/browser/collaboration-color-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// *****************************************************************************
// Copyright (C) 2024 TypeFox and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************

import { injectable } from '@theia/core/shared/inversify';

export interface CollaborationColor {
r: number;
g: number;
b: number;
}

export namespace CollaborationColor {
export function fromString(code: string): CollaborationColor {
if (code.startsWith('#')) {
code = code.substring(1);
}
const r = parseInt(code.substring(0, 2), 16);
const g = parseInt(code.substring(2, 4), 16);
const b = parseInt(code.substring(4, 6), 16);
return { r, g, b };
}

export const Gold = fromString('#FFD700');
export const Tomato = fromString('#FF6347');
export const Aquamarine = fromString('#7FFFD4');
export const Beige = fromString('#F5F5DC');
export const Coral = fromString('#FF7F50');
export const DarkOrange = fromString('#FF8C00');
export const VioletRed = fromString('#C71585');
export const DodgerBlue = fromString('#1E90FF');
export const Chocolate = fromString('#D2691E');
export const LightGreen = fromString('#90EE90');
export const MediumOrchid = fromString('#BA55D3');
export const Orange = fromString('#FFA500');
}

@injectable()
export class CollaborationColorService {

light = 'white';
dark = 'black';

getColors(): CollaborationColor[] {
return [
CollaborationColor.Gold,
CollaborationColor.Aquamarine,
CollaborationColor.Tomato,
CollaborationColor.MediumOrchid,
CollaborationColor.LightGreen,
CollaborationColor.Orange,
CollaborationColor.Beige,
CollaborationColor.Chocolate,
CollaborationColor.VioletRed,
CollaborationColor.Coral,
CollaborationColor.DodgerBlue,
CollaborationColor.DarkOrange
];
}

requiresDarkFont(color: CollaborationColor): boolean {
return ((color.r * 0.299) + (color.g * 0.587) + (color.b * 0.114)) > 186;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// *****************************************************************************
// Copyright (C) 2024 TypeFox and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************

import { Disposable, Emitter, Event, URI } from '@theia/core';
import { injectable } from '@theia/core/shared/inversify';
import {
FileChange, FileDeleteOptions,
FileOverwriteOptions, FileSystemProviderCapabilities, FileType, Stat, WatchOptions, FileSystemProviderWithFileReadWriteCapability, FileWriteOptions
} from '@theia/filesystem/lib/common/files';
import { ProtocolBroadcastConnection, Workspace } from 'open-collaboration-protocol';

export namespace CollaborationURI {

export const scheme = 'collaboration';

export function create(workspace: Workspace, path?: string): URI {
return new URI(`${scheme}:///${workspace.name}${path ? '/' + path : ''}`);
}
}

@injectable()
export class CollaborationFileSystemProvider implements FileSystemProviderWithFileReadWriteCapability {

capabilities = FileSystemProviderCapabilities.FileReadWrite;

protected _readonly: boolean;

get readonly(): boolean {
return this._readonly;
}

set readonly(value: boolean) {
if (this._readonly !== value) {
this._readonly = value;
if (value) {
this.capabilities |= FileSystemProviderCapabilities.Readonly;
} else {
this.capabilities &= ~FileSystemProviderCapabilities.Readonly;
}
this.onDidChangeCapabilitiesEmitter.fire();
}
}

constructor(readonly connection: ProtocolBroadcastConnection) {

}

protected encoder = new TextEncoder();
protected decoder = new TextDecoder();
protected onDidChangeCapabilitiesEmitter = new Emitter<void>();
protected onDidChangeFileEmitter = new Emitter<readonly FileChange[]>();
protected onFileWatchErrorEmitter = new Emitter<void>();

get onDidChangeCapabilities(): Event<void> {
return this.onDidChangeCapabilitiesEmitter.event;
}
get onDidChangeFile(): Event<readonly FileChange[]> {
return this.onDidChangeFileEmitter.event;
}
get onFileWatchError(): Event<void> {
return this.onFileWatchErrorEmitter.event;
}
async readFile(resource: URI): Promise<Uint8Array> {
const stringValue = await this.connection.fs.readFile('', this.getHostPath(resource));
return this.encoder.encode(stringValue);
}
async writeFile(resource: URI, content: Uint8Array, opts: FileWriteOptions): Promise<void> {
const stringValue = this.decoder.decode(content);
await this.connection.fs.writeFile('', this.getHostPath(resource), stringValue);
}
watch(resource: URI, opts: WatchOptions): Disposable {
return Disposable.NULL;
}
stat(resource: URI): Promise<Stat> {
return this.connection.fs.stat('', this.getHostPath(resource));
}
mkdir(resource: URI): Promise<void> {
return this.connection.fs.mkdir('', this.getHostPath(resource));
}
async readdir(resource: URI): Promise<[string, FileType][]> {
const record = await this.connection.fs.readdir('', this.getHostPath(resource));
return Object.entries(record);
}
delete(resource: URI, opts: FileDeleteOptions): Promise<void> {
return this.connection.fs.delete('', this.getHostPath(resource));
}
rename(from: URI, to: URI, opts: FileOverwriteOptions): Promise<void> {
return this.connection.fs.rename('', this.getHostPath(from), this.getHostPath(to));
}

protected getHostPath(uri: URI): string {
const path = uri.path.toString().substring(1).split('/');
return path.slice(1).join('/');
}

triggerEvent(changes: FileChange[]): void {
this.onDidChangeFileEmitter.fire(changes);
}

}
Loading

0 comments on commit 4a746ed

Please sign in to comment.