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

Commit

Permalink
feat: presence mouse
Browse files Browse the repository at this point in the history
  • Loading branch information
afonsovinicius committed Aug 4, 2023
1 parent 89fac9a commit 6f0a6d4
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/web-components/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { HelloWorld } from './hello-world';
export { Mouses } from './presence-mouses';
51 changes: 51 additions & 0 deletions src/web-components/presence-mouses/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import sleep from '../../common/utils/sleep';

import '.';

const element = document.createElement('superviz-mouses');
document.body.appendChild(element);

describe('Mouses web component', () => {
test('should have a div id with attendee id and a attendee name in innerHTML', async () => {
const renderedElement = document.getElementsByTagName('superviz-mouses')[0];
const attendeeId = 'Attendee1';
const name = 'Attendee Name';
const mouseFollower = document.createElement('div');
mouseFollower.setAttribute('id', `${attendeeId}`);
mouseFollower.setAttribute('class', 'mouse-follower');
renderedElement.appendChild(mouseFollower);

const mouseUserName = document.createElement('div');
mouseUserName.setAttribute('class', 'mouse-user-name');
mouseUserName.innerHTML = name;

renderedElement.appendChild(mouseUserName);

await sleep();

const attendeeElement = renderedElement.shadowRoot?.querySelector('#Attendee1');
expect(attendeeElement).toBeTruthy();

const mouseUserNameElement = renderedElement.shadowRoot?.querySelector('.mouse-user-name');
expect(mouseUserNameElement).toBeTruthy();
expect(mouseUserNameElement?.textContent).toEqual(name);
});

it('should add event listeners on resize window and mouse move', async () => {
// mock
const resizeHandler = jest.fn();
const moveHandler = jest.fn();

// listeners
element.addEventListener('resize', resizeHandler);
element.addEventListener('mousemove', moveHandler);

// simulate events
element.dispatchEvent(new Event('resize'));
element.dispatchEvent(new MouseEvent('mousemove'));

// events called
expect(resizeHandler).toHaveBeenCalled();
expect(moveHandler).toHaveBeenCalled();
});
});
98 changes: 98 additions & 0 deletions src/web-components/presence-mouses/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';

import { styles as customMouseStyles } from './styles';

@customElement('superviz-mouses')
export class Mouses extends LitElement {
declare name: string;
declare attendeeId: string;
declare pointerMouse: string;

static properties = {
name: { type: String },
attendeeId: { type: String },
pointerMouse: { type: String },

};

static styles = [customMouseStyles];

constructor() {
super();

this.name = 'Attendee Name';
this.attendeeId = 'Attendee1';
}

connectedCallback() {
super.connectedCallback();
window.addEventListener('resize', this._handleResize);
window.addEventListener('mousemove', this._handleMove);

// if use Iframe on mouse move
// document.addEventListener('DOMContentLoaded', this._onParentDOMContentLoaded);
}

disconnectedCallback() {
super.disconnectedCallback();
window.removeEventListener('resize', this._handleResize);
window.removeEventListener('mousemove', this._handleMove);

// if use Iframe on mouse move
// document.removeEventListener('DOMContentLoaded', this._onParentDOMContentLoaded);
}

_onParentDOMContentLoaded = () => {
this._trackMouseInIframes();
};

// if use Iframe on mouse move
private _trackMouseInIframes() {
const iframes = document.getElementsByTagName('iframe');
const iframeArray: HTMLIFrameElement[] = Array.from(iframes);

iframeArray.forEach((iframe) => {
const iframeWindow = iframe.contentWindow;
if (iframeWindow) {
iframeWindow.addEventListener('mousemove', (event) => {
const x = event.clientX;
const y = event.clientY;
// console.log(`IFRAME (${iframe.src}) - X: ${x}, Y: ${y}`);
});
}
});
}

private _handleMove = (e) => {
const x = e.clientX;
const y = e.clientY;

const divMouseFollower = this.shadowRoot.getElementById(this.attendeeId);
if (!divMouseFollower) {
return;
}
divMouseFollower.style.left = `${x.toString()}px`;
divMouseFollower.style.top = `${y.toString()}px`;
// console.log(`DOM - X: ${x}, Y: ${y}`);
};

private _handleResize = (e) => {
// console.log('RESIZE: ', e.currentTarget.innerWidth, e.currentTarget.innerHeight);
};

protected render() {
return html`
<div id="mouse-container" class="mouse-board">
<div id="mouse-sync">
<div id="${this.attendeeId}" class="mouse-follower">
<div class="pointer-mouse"></div>
<div class="mouse-user-name">${this.name}</div>
</div>
</div>
</div>
`;
}
}

document.body.appendChild(document.createElement('superviz-mouses'));
46 changes: 46 additions & 0 deletions src/web-components/presence-mouses/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { css } from 'lit';
// import { customElement } from 'lit/decorators.js';
export const styles = css`
#mouse-container {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
}
#mouse-sync {
position: absolute;
}
.mouse-board {
background: transparent;
position: absolute;
top: 0;
cursor: none !important;
}
.mouse-follower {
position: absolute;
display: block;
transition: all 0.4s;
}
.pointer-mouse {
display: flex;
height: 17px;
width: 17px;
background-image: url(https://production.cdn.superviz.com/static/pointers/0.svg);
}
.mouse-user-name {
border-radius: 30px;
padding: 2px 8px;
font-weight: 700;
font-size: 14px;
line-height: 22px;
margin-left: 10px;
margin-top: -6px;
background: yellow;
white-space: nowrap;
}
`;

0 comments on commit 6f0a6d4

Please sign in to comment.