Skip to content

Commit

Permalink
Always keep session member view up-to-date
Browse files Browse the repository at this point in the history
  • Loading branch information
msujew committed Oct 21, 2024
1 parent 86f2afd commit a5d941b
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class CollaborationConnectionProvider {
if (serverUrl) {
return new ConnectionProvider({
url: serverUrl,
client: 'OCT-VSCode@' + version,
client: 'OCT-VSCode@' + packageVersion,
opener: (url) => vscode.env.openExternal(vscode.Uri.parse(url)),
transports: [SocketIoTransportProvider],
userToken,
Expand Down
27 changes: 18 additions & 9 deletions packages/open-collaboration-vscode/src/collaboration-instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ import { inject, injectable, postConstruct } from 'inversify';
import { removeWorkspaceFolders } from './utils/workspace';
import { Mutex } from 'async-mutex';
import { CollaborationUri } from './utils/uri';
import { userColors } from "./utils/package";

export interface PeerWithColor extends types.Peer {
color?: [number, number, number] | string;
}

export class DisposablePeer implements vscode.Disposable {

Expand Down Expand Up @@ -111,12 +116,7 @@ export class DisposablePeer implements vscode.Disposable {

let colorIndex = 0;
const defaultColors: ([number, number, number] | string)[] = [
'oct.user.yellow', // Yellow
'oct.user.green', // Green
'oct.user.magenta', // Magenta
'oct.user.lightGreen', // Light green
'oct.user.lightOrange', // Light orange
'oct.user.lightMagenta', // Light magenta
...userColors,
[92, 45, 145], // Purple
[0, 178, 148], // Light teal
[255, 241, 0], // Light yellow
Expand Down Expand Up @@ -205,8 +205,15 @@ export class CollaborationInstance implements vscode.Disposable {
private readonly onDidDisposeEmitter: vscode.EventEmitter<void> = new vscode.EventEmitter<void>();
readonly onDidDispose: vscode.Event<void> = this.onDidDisposeEmitter.event;

get connectedUsers(): DisposablePeer[] {
return Array.from(this.peers.values());
get connectedUsers(): Promise<PeerWithColor[]> {
return this.ownUserData.then(own => {
const all = Array.from(this.peers.values()).map(e => ({
...e.peer,
color: e.decoration.color
}) as PeerWithColor);
all.push(own);
return Array.from(all);
});
}

get ownUserData(): Promise<types.Peer> {
Expand Down Expand Up @@ -277,7 +284,6 @@ export class CollaborationInstance implements vscode.Disposable {
await this.initialize(initData);
});
connection.room.onJoin(async (_, peer) => {
this.peers.set(peer.id, new DisposablePeer(this.yjsAwareness, peer));
if (this.host) {
// Only initialize the user if we are the host
const roots = vscode.workspace.workspaceFolders ?? [];
Expand All @@ -294,6 +300,7 @@ export class CollaborationInstance implements vscode.Disposable {
};
connection.peer.init(peer.id, initData);
}
this.peers.set(peer.id, new DisposablePeer(this.yjsAwareness, peer));
this.onDidUsersChangeEmitter.fire();
});
connection.room.onLeave(async (_, peer) => {
Expand All @@ -315,6 +322,7 @@ export class CollaborationInstance implements vscode.Disposable {
connection.peer.onInfo((_, peer) => {
this.yjsAwareness.setLocalStateField('peer', peer.id);
this.identity.resolve(peer);
this.onDidUsersChangeEmitter.fire();
});

this.registerFileEvents();
Expand Down Expand Up @@ -863,5 +871,6 @@ export class CollaborationInstance implements vscode.Disposable {
}
this.fileSystem = new CollaborationFileSystemProvider(this.options.connection, this.yjs, data.host);
this.toDispose.push(vscode.workspace.registerFileSystemProvider('oct', this.fileSystem));
this.onDidUsersChangeEmitter.fire();
}
}
38 changes: 23 additions & 15 deletions packages/open-collaboration-vscode/src/collaboration-status-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,51 +5,59 @@
// ******************************************************************************

import * as vscode from 'vscode';
import { CollaborationInstance, DisposablePeer } from './collaboration-instance';
import { CollaborationInstance, PeerWithColor } from './collaboration-instance';
import { injectable } from 'inversify';

@injectable()
export class CollaborationStatusViewDataProvider implements vscode.TreeDataProvider<DisposablePeer> {
export class CollaborationStatusViewDataProvider implements vscode.TreeDataProvider<PeerWithColor> {

private onDidChangeTreeDataEmitter = new vscode.EventEmitter<DisposablePeer[] | undefined>();
private onDidChangeTreeDataEmitter = new vscode.EventEmitter<void>();
onDidChangeTreeData = this.onDidChangeTreeDataEmitter.event;

private instance: CollaborationInstance | undefined;

onConnection(instance: CollaborationInstance) {
this.instance = instance;
instance.onDidUsersChange(() => {
this.onDidChangeTreeDataEmitter.fire(undefined);
this.onDidChangeTreeDataEmitter.fire();
});
instance.onDidDispose(() => {
this.instance = undefined;
this.onDidChangeTreeDataEmitter.fire(undefined);
this.onDidChangeTreeDataEmitter.fire();
});
this.onDidChangeTreeDataEmitter.fire(undefined);
this.onDidChangeTreeDataEmitter.fire();
}

async getTreeItem(element: DisposablePeer): Promise<vscode.TreeItem> {
async getTreeItem(peer: PeerWithColor): Promise<vscode.TreeItem> {
const self = await this.instance?.ownUserData;
const you = vscode.l10n.t('You');
const treeItem = new vscode.TreeItem(element.peer.id === self?.id ? `${element.peer.name} (${you})` : element.peer.name);
treeItem.id = element.peer.id;
const treeItem = new vscode.TreeItem(peer.name);
const tags: string[] = [];
if (peer.id === self?.id) {
tags.push(vscode.l10n.t('You'));
}
if (peer.host) {
tags.push(vscode.l10n.t('Host'));
}
treeItem.description = tags.length ? ('(' + tags.join(' • ') + ')') : undefined;
treeItem.id = peer.id;
treeItem.contextValue = 'self';
if (self?.id !== element.peer.id) {
treeItem.iconPath = new vscode.ThemeIcon('circle-filled', element.decoration.getThemeColor());
treeItem.contextValue = this.instance?.following === treeItem.id ? 'followedPeer' : 'peer';
if (self?.id !== peer.id) {
const themeColor = typeof peer.color === 'string' ? new vscode.ThemeColor(peer.color) : undefined;
treeItem.iconPath = new vscode.ThemeIcon('circle-filled', themeColor);
treeItem.contextValue = this.instance?.following === peer.id ? 'followedPeer' : 'peer';
}
return treeItem;
}

getChildren(element?: DisposablePeer): vscode.ProviderResult<DisposablePeer[]> {
getChildren(element?: PeerWithColor): vscode.ProviderResult<PeerWithColor[]> {
if (!element && this.instance) {
return this.instance.connectedUsers;
}
return [];
}

update() {
this.onDidChangeTreeDataEmitter.fire(undefined);
this.onDidChangeTreeDataEmitter.fire();
}

}
4 changes: 2 additions & 2 deletions packages/open-collaboration-vscode/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import * as vscode from 'vscode';
import { inject, injectable } from 'inversify';
import { FollowService } from './follow-service';
import { CollaborationInstance, DisposablePeer } from './collaboration-instance';
import { CollaborationInstance, PeerWithColor } from './collaboration-instance';
import { ExtensionContext } from './inversify';
import { CollaborationConnectionProvider, OCT_USER_TOKEN } from './collaboration-connection-provider';
import { QuickPickItem, showQuickPick } from './utils/quick-pick';
Expand Down Expand Up @@ -40,7 +40,7 @@ export class Commands {

initialize(): void {
this.context.subscriptions.push(
vscode.commands.registerCommand('oct.followPeer', (peer?: DisposablePeer) => this.followService.followPeer(peer)),
vscode.commands.registerCommand('oct.followPeer', (peer?: PeerWithColor) => this.followService.followPeer(peer?.id)),
vscode.commands.registerCommand('oct.stopFollowPeer', () => this.followService.unfollowPeer()),
vscode.commands.registerCommand('oct.enter', async () => {
this.withConnectionProvider(async connectionProvider => {
Expand Down
12 changes: 7 additions & 5 deletions packages/open-collaboration-vscode/src/follow-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// terms of the MIT License, which is available in the project root.
// ******************************************************************************

import * as vscode from 'vscode';
import { inject, injectable } from 'inversify';
import { CollaborationInstance, DisposablePeer } from './collaboration-instance';
import { showQuickPick } from './utils/quick-pick';
Expand All @@ -19,22 +20,23 @@ export class FollowService {
@inject(ContextKeyService)
private contextKeyService: ContextKeyService;

async followPeer(peer?: DisposablePeer): Promise<void> {
async followPeer(peer?: string): Promise<void> {
if (!CollaborationInstance.Current) {
return;
}

if (!peer) {
const users = CollaborationInstance.Current.connectedUsers;
const items = users.map(user => ({ key: user, label: user.peer.name, detail: user.peer.id }));
peer = await showQuickPick(items);
const quickPick = vscode.window.createQuickPick();
const users = await CollaborationInstance.Current.connectedUsers;
quickPick.items = users.map(user => ({ label: user.name, detail: user.id }));
peer = users[(await showQuickPick(quickPick))]?.id;
}

if (!peer) {
return;
}

CollaborationInstance.Current.followUser(peer.peer.id);
CollaborationInstance.Current.followUser(peer);
this.viewDataProvider.update();
this.contextKeyService.setFollowing(true);
}
Expand Down
5 changes: 5 additions & 0 deletions packages/open-collaboration-vscode/src/utils/package.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const packageJson = require('../../package.json');
export const packageVersion: string = packageJson.version;
export const userColors: string[] = packageJson.contributes.colors
.map((color: any) => color.id)
.filter((id: string) => id.startsWith('oct.user.'));

0 comments on commit a5d941b

Please sign in to comment.