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 #606 from SuperViz/lab
Browse files Browse the repository at this point in the history
New Version - Mouse pointers animations 🎉
  • Loading branch information
carlossantos74 authored Mar 18, 2024
2 parents 00f573c + 525df2d commit b1f5919
Show file tree
Hide file tree
Showing 33 changed files with 1,435 additions and 1,226 deletions.
66 changes: 26 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,33 @@
</p>

<p align="center">
<img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/superviz/sdk/Publish%20SDK">
<img alt="GitHub issues" src="https://img.shields.io/github/issues-raw/superviz/sdk">
<img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/superviz/sdk">
<img alt="GitHub" src="https://img.shields.io/github/license/superviz/sdk">
<img alt="npm type definitions" src="https://img.shields.io/npm/types/@superviz/sdk">
<img alt="npm" src="https://img.shields.io/npm/dw/@superviz/sdk">
<img alt="Discord" src="https://img.shields.io/discord/1171797567223378002">
<img alt="GitHub Release" src="https://img.shields.io/github/v/release/superviz/sdk">
<img alt="GitHub issues" src="https://img.shields.io/github/issues-raw/superviz/sdk">
<img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/superviz/sdk">
<img alt="License" src="https://img.shields.io/github/license/superviz/sdk">
<img alt="npm type definitions" src="https://img.shields.io/npm/types/@superviz/sdk">
<img alt="Downloads" src="https://img.shields.io/npm/dw/@superviz/sdk">
</p>

SuperViz provides a suite of programmable low-code Collaboration and Communication components, all synchronized with an advanced Real-time Data Engine, enabling real-time and asynchronous collaboration and communication within any JavaScript based application.

SuperViz offers a comprehensive suite of components, all synchronized with an advanced Real-time Data Engine, facilitating real-time collaboration in JavaScript-based applications. SuperViz SDK enables you to use one of our components:

- [Contextual Comments](https://docs.superviz.com/components/contextual-comments/)
- [Contextual Comments for Autodesk](https://docs.superviz.com/components/contextual-comments/contextual-comments-for-autodesk)
- [Contextual Comments for Matterport](https://docs.superviz.com/components/contextual-comments/contextual-comments-for-matterport)
- [Contextual Comments for ThreeJS](https://docs.superviz.com/components/contextual-comments/contextual-comments-for-threejs)
- Contextual Comments
- [Contextual Comments for HTML](https://docs.superviz.com/sdk/comments/html-adapter)
- [Contextual Comments for Canvas element](https://docs.superviz.com/sdk/comments/canvas-adapter)
- [Contextual Comments for Autodesk](https://docs.superviz.com/sdk/comments/autodesk-adpater)
- [Contextual Comments for Matterport](https://docs.superviz.com/sdk/comments/matterport-adapter)
- [Contextual Comments for ThreeJS](https://docs.superviz.com/sdk/comments/threejs-adapter)
- Presence
- [Presence in Autodesk](https://docs.superviz.com/components/presence/presence3d/AutodeskPresence)
- [Presence in Matterport](https://docs.superviz.com/components/presence/presence3d/MatterportPresence)
- [Presence in ThreeJS](https://docs.superviz.com/components/presence/presence3d/ThreeJsPresence)
- [Real-time Mouse Pointers](https://docs.superviz.com/components/presence/mouse-pointers)
- [Real-time Data Engine](https://docs.superviz.com/components/presence/real-time-data-engine)
- [Who-is-Online](https://docs.superviz.com/components/presence/who-is-online)
- [Video Conference](https://docs.superviz.com/components/video/video-conference)
- [Real-time Mouse Pointers](https://docs.superviz.com/sdk/presence/mouse-pointers)
- [Real-time Data Engine](https://docs.superviz.com/sdk/presence/real-time-data-engine)
- [Who-is-Online](https://docs.superviz.com/sdk/presence/who-is-online)
- [Presence in Autodesk](https://docs.superviz.com/sdk/presence/AutodeskPresence)
- [Presence in Matterport](https://docs.superviz.com/sdk/presence/MatterportPresence)
- [Presence in ThreeJS](https://docs.superviz.com/sdk/presence/ThreeJsPresence)
- [Video Conference](https://docs.superviz.com/sdk/video/video-conference)

You can also combine components to create a custom solution for your application.

Expand Down Expand Up @@ -80,34 +83,17 @@ async function initializeSuperVizSdk() {
}
```

### Documentation
If you are implementing the SuperViz SDK in a React application, check our [React SDK package](https://docs.superviz.com/react-sdk/initialization), which provides a set of hooks and components to make it easier to integrate SuperViz SDK into your React application.

You can find the complete documentation for every component and how to initialize them on the [SuperViz SDK Documentation page](https://docs.superviz.com/).

## Contributing

### Issues

To report a new bug, request a new feature, or if you need any help, you can [file an issue on GitHub](https://github.com/SuperViz/sdk/issues/new/choose). We have a few templates to help you out.
## Documentation

### Run locally

Add file .remote-config.js with the following content:
You can find the complete documentation for every component and how to initialize them on the [SuperViz SDK Documentation page](https://docs.superviz.com/).

```javascript
module.exports = {
remoteConfig: {
apiUrl: 'https://api.example.com',
conferenceLayerUrl: 'https://conference-url.example.com',
},
};
```
You can also find the complete changelog on the [Release Notes page](https://docs.superviz.com/releases).

And add into initialization of SDK
## Contributing

```javascript
environment: 'local';
```
If you are interested in contributing to SuperViz SDK, the best place to get involved with the community is through the [Discord server](https://discord.gg/weZ3Bfv6WZ), there you can find the latest news, ask questions, and share your experiences with SuperViz SDK.

## License

Expand Down
20 changes: 10 additions & 10 deletions src/common/styles/global.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
@import url('https://unpkg.com/@superviz/sv-icons@0.8.10/css/style.css');
@import url('https://unpkg.com/@superviz/sv-icons@0.8.12/css/style.css');
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;700&family=Roboto:wght@400;500;700&display=swap');

:root {
--sv-primary: 98, 16, 204;
}

html, body {
html, body {
width: 100%;
height: 100%;
overflow: hidden;
Expand All @@ -14,35 +14,35 @@ html, body {
#sv-video-wrapper iframe {
position: fixed;
border: none;
margin: 0;
padding: 0;
margin: 0;
padding: 0;
overflow: hidden;
z-index: 5;
}

#sv-video-wrapper iframe.sv-video-frame--right {
#sv-video-wrapper iframe.sv-video-frame--right {
top: var(--superviz-offset-top);
right: var(--superviz-offset-right);
}

#sv-video-wrapper iframe.sv-video-frame--left {
#sv-video-wrapper iframe.sv-video-frame--left {
top: var(--superviz-offset-top);
left: var(--superviz-offset-left);
}

#sv-video-wrapper iframe.sv-video-frame--bottom {
#sv-video-wrapper iframe.sv-video-frame--bottom {
bottom: var(--superviz-offset-bottom);
right: var(--superviz-offset-right);
width: 100%;
}

#sv-video-wrapper iframe.sv-video-frame--top {
#sv-video-wrapper iframe.sv-video-frame--top {
top: var(--superviz-offset-top);
right: var(--superviz-offset-right);
width: 100%;
}

#sv-video-wrapper iframe.sv-video-frame--no-overlay {
#sv-video-wrapper iframe.sv-video-frame--no-overlay {
display: none;
}

Expand All @@ -58,7 +58,7 @@ html, body {

.mouse-user-name {
display: block;
position: absolute;
position: absolute;
border-radius: 30px;
padding: 2px 8px;
font-weight: 700;
Expand Down
1 change: 0 additions & 1 deletion src/components/base/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export abstract class BaseComponent extends Observable {
}

const { realtime, localParticipant, group, config: globalConfig, eventBus } = params;

if (!realtime.isDomainWhitelisted) {
const message = `Component ${this.name} can't be used because this website's domain is not whitelisted. Please add your domain in https://dashboard.superviz.com/developer`;
this.logger.log(message);
Expand Down
7 changes: 6 additions & 1 deletion src/components/comments/canvas-pin-adapter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -390,9 +390,14 @@ export class CanvasPin implements PinAdapter {
* @param {CustomEvent} event
* @returns {void}
*/
private annotationSelected = ({ detail: { uuid, haltGoToPin } }: CustomEvent): void => {
private annotationSelected = ({ detail: { uuid, haltGoToPin, newPin } }: CustomEvent): void => {
if (!uuid) return;

if (newPin) {
const pin = this.pins.get(uuid);
pin.setAttribute('newPin', '');
}

const annotation = JSON.parse(this.selectedPin?.getAttribute('annotation') ?? '{}');

this.resetPins();
Expand Down
8 changes: 6 additions & 2 deletions src/components/comments/html-pin-adapter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -723,9 +723,14 @@ export class HTMLPin implements PinAdapter {
* @param {CustomEvent} event the emitted event object with the uuid of the selected annotation
* @returns {void}
*/
private annotationSelected = ({ detail: { uuid } }: CustomEvent): void => {
private annotationSelected = ({ detail: { uuid, newPin } }: CustomEvent): void => {
if (!uuid) return;

if (newPin) {
const pin = this.pins.get(uuid);
pin.setAttribute('newPin', '');
}

const annotation = this.annotations.find(
(annotation) => annotation.uuid === this.selectedPin?.id,
);
Expand Down Expand Up @@ -766,7 +771,6 @@ export class HTMLPin implements PinAdapter {
if (!wrapper) return;

wrapper.appendChild(pin);
wrapper.parentElement.appendChild(wrapper);
}

// ------- helper functions -------
Expand Down
33 changes: 20 additions & 13 deletions src/components/comments/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import ApiService from '../../services/api';
import { CommentsFloatButton } from '../../web-components';
import { ComponentNames } from '../types';

import { PinAdapter, CommentsSide, Annotation, PinCoordinates } from "./types";
import { PinAdapter, CommentsSide, Annotation, PinCoordinates } from './types';

import { Comments } from './index';

Expand Down Expand Up @@ -46,7 +46,10 @@ jest.mock('../../services/api', () => ({
resolveAnnotation: jest.fn().mockImplementation(() => []),
deleteComment: jest.fn().mockImplementation(() => []),
deleteAnnotation: jest.fn().mockImplementation(() => []),
fetchParticipantsByGroup: jest.fn().mockImplementation((): ParticipantByGroupApi[] => MOCK_PARTICIPANTS),}));
fetchParticipantsByGroup: jest
.fn()
.mockImplementation((): ParticipantByGroupApi[] => MOCK_PARTICIPANTS),
}));

const DummiePinAdapter: PinAdapter = {
destroy: jest.fn(),
Expand Down Expand Up @@ -241,7 +244,7 @@ describe('Comments', () => {

comments['positionComments']();

expect(comments['element'].side).toBe('left: 0;');
expect(comments['element'].side).toBe('left');
});

test('should set the left side style if the position is "left"', () => {
Expand All @@ -250,7 +253,7 @@ describe('Comments', () => {
comments['layoutOptions'].position = CommentsSide.LEFT;
comments['positionComments']();

expect(comments['element'].side).toBe('left: 0;');
expect(comments['element'].side).toBe('left');
});

test('should set the right side style if the position is "right"', () => {
Expand All @@ -259,7 +262,7 @@ describe('Comments', () => {
comments['layoutOptions'].position = CommentsSide.RIGHT;
comments['positionComments']();

expect(comments['element'].side).toBe('right: 0;');
expect(comments['element'].side).toBe('right');
});

test('should have position "left" if no position is passed', () => {
Expand All @@ -270,15 +273,15 @@ describe('Comments', () => {

comments['positionComments']();

expect(comments['element'].side).toBe('left: 0;');
expect(comments['element'].side).toBe('left');
});

test('should have position "left" if invalid position is passed', () => {
const comments = new Comments(DummiePinAdapter);
comments['layoutOptions'].position = 'invalid-position' as any;
comments['positionComments']();

expect(comments['element'].side).toBe('left: 0;');
expect(comments['element'].side).toBe('left');
});

test('should call apiService when resolve annotation', async () => {
Expand Down Expand Up @@ -741,23 +744,27 @@ describe('Comments', () => {
commentsComponent['element'].participantsListed = jest.fn();
await commentsComponent['element'].participantsListed(MOCK_PARTICIPANTS);

expect(commentsComponent['element'].participantsListed).toHaveBeenCalledWith(MOCK_PARTICIPANTS);
expect(commentsComponent['element'].participantsListed).toHaveBeenCalledWith(
MOCK_PARTICIPANTS,
);
});
});

describe('Mentions', () => {
test('should create a mention', async () => {
const response = await ApiService.createMentions({
commentsId: 'any_comment_id',
participants: [{
id: 'any_mention_userId',
readed: 0,
}]
participants: [
{
id: 'any_mention_userId',
readed: 0,
},
],
});

expect(response).toEqual([]);
});
})
});

describe('openThreads', () => {
afterEach(() => {
Expand Down
17 changes: 9 additions & 8 deletions src/components/comments/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
Comment,
CommentsOptions,
CommentsSide,
Offset,
PinAdapter,
} from './types';

Expand All @@ -31,6 +32,7 @@ export class Comments extends BaseComponent {
private coordinates: AnnotationPositionInfo;
private hideDefaultButton: boolean;
private pinActive: boolean;
private offset: Offset;

constructor(pinAdapter: PinAdapter, options?: CommentsOptions) {
super();
Expand All @@ -45,6 +47,7 @@ export class Comments extends BaseComponent {
this.hideDefaultButton = options?.hideDefaultButton ?? false;

this.setStyles(options?.styles);
this.offset = options?.offset;

setTimeout(() => {
pinAdapter.setCommentsMetadata(
Expand Down Expand Up @@ -363,19 +366,17 @@ export class Comments extends BaseComponent {
private positionComments = (): void => {
this.element = document.createElement('superviz-comments') as CommentElement;
this.element.setAttribute('comments', JSON.stringify([]));
this.element.side = 'left: 0;';
this.element.side = CommentsSide.LEFT;
this.element.offset = this.offset;
document.body.appendChild(this.element);

const position = this.layoutOptions?.position;
if (!position) return;

const sidesOptions = Object.values(CommentsSide);
const parsedPosition = position.toLocaleLowerCase() as CommentsSide;
const parsedPosition = position.toUpperCase() as CommentsSide;
if (!CommentsSide[parsedPosition]) return;

if (!sidesOptions.includes(parsedPosition)) return;

const style = position === CommentsSide.LEFT ? 'left: 0;' : 'right: 0;';
this.element.side = style;
this.element.side = CommentsSide[parsedPosition];
};

/**
Expand Down Expand Up @@ -412,7 +413,7 @@ export class Comments extends BaseComponent {

document.body.dispatchEvent(
new CustomEvent('select-annotation', {
detail: { uuid: annotation.uuid, haltGoToPin: true },
detail: { uuid: annotation.uuid, haltGoToPin: true, newPin: true },
composed: true,
bubbles: true,
}),
Expand Down
8 changes: 8 additions & 0 deletions src/components/comments/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,17 @@ export enum ButtonLocation {
BOTTOM_RIGHT = 'bottom-right',
}

export interface Offset {
top?: number;
bottom?: number;
left?: number;
right?: number;
}

export interface CommentsOptions {
position?: CommentsSide | `${CommentsSide}`;
buttonLocation?: ButtonLocation | `${ButtonLocation}` | string;
hideDefaultButton?: boolean;
styles?: string;
offset?: Offset;
}
Loading

0 comments on commit b1f5919

Please sign in to comment.