Skip to content
This repository has been archived by the owner on Oct 18, 2024. It is now read-only.

Commit

Permalink
Merge pull request #644 from SuperViz/lab
Browse files Browse the repository at this point in the history
New 2D presence controls and form input component
  • Loading branch information
carlossantos74 authored Apr 22, 2024
2 parents 13b07c3 + f029d72 commit 97a7e72
Show file tree
Hide file tree
Showing 30 changed files with 2,168 additions and 126 deletions.
1 change: 0 additions & 1 deletion .releaserc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"plugins": [
"@semantic-release/commit-analyzer",
"semantic-release-version-file",
"@semantic-release/release-notes-generator",
"@semantic-release/github",
"@semantic-release/npm"
]
Expand Down
22 changes: 14 additions & 8 deletions __mocks__/io.mock.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
import { jest } from '@jest/globals';
import * as Socket from '@superviz/socket-client';

export const MOCK_IO = {
PresenceEvents: {
JOINED_ROOM: 'presence.joined-room',
LEAVE: 'presence.leave',
ERROR: 'presence.error',
UPDATE: 'presence.update',
},
Realtime: class {
public connection: {
on: (state: string) => void;
off: () => void;
};
connection;

constructor(apiKey: string, environment: string, participant: any) {
constructor(apiKey, environment, participant) {
this.connection = {
on: jest.fn(),
off: jest.fn(),
};
}

public connect() {
connect() {
return {
on: jest.fn(),
off: jest.fn(),
emit: jest.fn(),
disconnect: jest.fn(),
history: jest.fn(),
presence: {
on: jest.fn(),
off: jest.fn(),
get: jest.fn(),
update: jest.fn(),
},
};
}

public destroy() {}
destroy() {}
},
};
5 changes: 5 additions & 0 deletions jest.setup.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/* eslint-disable no-undef */
const fs = require('fs');
require('jest-canvas-mock');

const { MOCK_CONFIG } = require('./__mocks__/config.mock');
const { MOCK_IO } = require('./__mocks__/io.mock');
const config = require('./src/services/config');

config.default.setConfig(MOCK_CONFIG);
Expand Down Expand Up @@ -32,3 +35,5 @@ global.DOMPoint = class {
return this;
}
};

jest.mock('@superviz/socket-client', () => MOCK_IO);
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"husky": "^8.0.3",
"jest": "^29.7.0",
"jest-browser-globals": "^25.1.0-beta",
"jest-canvas-mock": "^2.5.2",
"jest-environment-jsdom": "^29.7.0",
"jest-fetch-mock": "^3.0.3",
"rimraf": "^5.0.5",
Expand Down
2 changes: 2 additions & 0 deletions src/common/types/cdn.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Realtime,
VideoConference,
WhoIsOnline,
FormElements,
} from '../../components';
import { RealtimeComponentEvent, RealtimeComponentState } from '../../components/realtime/types';
import { LauncherFacade } from '../../core/launcher/types';
Expand Down Expand Up @@ -55,6 +56,7 @@ export interface SuperVizCdn {
CanvasPin: typeof CanvasPin;
HTMLPin: typeof HTMLPin;
WhoIsOnline: typeof WhoIsOnline;
FormElements: typeof FormElements;
RealtimeComponentState: typeof RealtimeComponentState;
RealtimeComponentEvent: typeof RealtimeComponentEvent;
}
17 changes: 11 additions & 6 deletions src/common/types/stores.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ export enum StoreType {
WHO_IS_ONLINE = 'who-is-online-store',
}

type StoreApi<T extends (...args: any[]) => any> = {
type Subject<T extends (...args: any[]) => any, K extends keyof ReturnType<T>> = ReturnType<T>[K]

type StoreApiWithoutDestroy<T extends (...args: any[]) => any> = {
[K in keyof ReturnType<T>]: {
subscribe(callback?: (value: keyof T) => void): void;
subject: PublicSubject<keyof T>;
publish<T>(value: T): void;
value: any;
subscribe(callback?: (value: Subject<T, K>['value']) => void): void;
subject: Subject<T, K>;
publish(value: Subject<T, K>['value']): void;
value: Subject<T, K>['value'];
};
};
}

type StoreApi<T extends (...args: any[]) => any> = Omit<StoreApiWithoutDestroy<T>, 'destroy'> & { destroy(): void };


// When creating new Stores, expand the ternary with the new Store. For example:
// ...T extends StoreType.GLOBAL ? StoreApi<typeof useGlobalStore> : T extends StoreType.WHO_IS_ONLINE ? StoreApi<typeof useWhoIsOnlineStore> : never;
Expand Down
11 changes: 6 additions & 5 deletions src/common/utils/use-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,22 @@ function subscribeTo<T>(
* @description Returns a proxy of the global store data and a subscribe function to be used in the components
*/
export function useStore<T extends StoreType>(name: T): Store<T> {
// @TODO - Improve types to get better sugestions when writing code
const storeData = stores[name as StoreType]();
const bindedSubscribeTo = subscribeTo.bind(this);

const proxy = new Proxy(storeData, {
get(store: Store<T>, valueName: string) {
get(store, valueName: string) {
if (valueName === 'destroy') return store.destroy;

return {
subscribe<K extends Store<T>>(callback?: (value: K) => void) {
subscribe(callback?) {
bindedSubscribeTo(valueName, store[valueName], callback);
},
subject: store[valueName] as typeof storeData,
subject: store[valueName],
get value() {
return this.subject.value;
},
publish(newValue: keyof Store<T>) {
publish(newValue) {
this.subject.value = newValue;
},
};
Expand Down
3 changes: 3 additions & 0 deletions src/components/base/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { AblyRealtimeService } from '../../services/realtime';
import { ComponentNames } from '../types';

import { DefaultAttachComponentOptions } from './types';
import { useGlobalStore } from '../../services/stores';

export abstract class BaseComponent extends Observable {
public abstract name: ComponentNames;
Expand Down Expand Up @@ -85,6 +86,8 @@ export abstract class BaseComponent extends Observable {
this.logger.log('detached');
this.publish(ComponentLifeCycleEvent.UNMOUNT);
this.destroy();
this.room.disconnect();

this.unsubscribeFrom.forEach((unsubscribe) => unsubscribe(this));

Object.values(this.observers).forEach((observer) => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/comments/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class Comments extends BaseComponent {
const { group, localParticipant } = this.useStore(StoreType.GLOBAL);
group.subscribe();

localParticipant.subscribe((participant: Participant) => {
localParticipant.subscribe((participant) => {
this.localParticipantId = participant.id;
});
}
Expand Down
Loading

0 comments on commit 97a7e72

Please sign in to comment.