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

New version 🎉 #581

Merged
merged 26 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e8c3507
refactor: change video callbacks names
carlossantos74 Feb 20, 2024
897561c
Merge pull request #571 from SuperViz/refactor/change-callbacks-names
carlossantos74 Feb 20, 2024
cade90a
fix: define better z-index order between components
Raspincel Feb 23, 2024
a72814a
fix: validade if slot is assigned when is finding my slot
carlossantos74 Feb 23, 2024
f946bc2
Merge pull request #573 from SuperViz/fix/slots-assingment
carlossantos74 Feb 23, 2024
d600fc3
fix: validade if slot is assigned when is finding my slot
carlossantos74 Feb 23, 2024
b51d8da
fix: slot assignment
carlossantos74 Feb 23, 2024
3b4a622
Merge pull request #574 from SuperViz/fix/slots-assingment
carlossantos74 Feb 23, 2024
fd33006
refactor: move the close button to the left by 8px
Feb 23, 2024
a575458
refactor: hover color close button
Feb 23, 2024
c7d7c03
refactor: increase username font to 14px, change color to sv-gray-700
Feb 23, 2024
73890b3
refactor: center the arrow with 'all comments'
Feb 23, 2024
cef92bd
fix: improve calculation of when to hide comments button, to account …
Raspincel Feb 23, 2024
9add264
Merge pull request #575 from SuperViz/refactor/ui-improvements
carlossantos74 Feb 26, 2024
a2f832a
fix: remove logs
Raspincel Feb 26, 2024
ab34712
Merge pull request #572 from SuperViz/fix/z-index-order
carlossantos74 Feb 26, 2024
b2c58cd
fix: disable keyboard interaction when typing comment
Raspincel Feb 26, 2024
0005bb8
fix: call focus on comments textarea input when clicking on it
Raspincel Feb 26, 2024
38b3e5b
refactor: add hover effect on mention button
Feb 26, 2024
8938090
Merge pull request #577 from SuperViz/fix/doesnt-focus-input
vitorvargasdev Feb 26, 2024
56756ba
refactor: adjust the line height
Feb 26, 2024
a648e63
fix: comment input test
Feb 26, 2024
1a2fe3e
Merge pull request #579 from SuperViz/refactor/adjust-the-line-height
carlossantos74 Feb 26, 2024
3e8a673
Merge pull request #578 from SuperViz/refactor/add-hover-effect-on-me…
carlossantos74 Feb 26, 2024
b382499
Merge pull request #576 from SuperViz/fix/disable-keyboard-interactions
carlossantos74 Feb 26, 2024
00f573c
Merge pull request #580 from SuperViz/lab
carlossantos74 Feb 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
435 changes: 175 additions & 260 deletions src/services/realtime/ably/index.test.ts

Large diffs are not rendered by default.

81 changes: 45 additions & 36 deletions src/services/realtime/ably/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -835,44 +835,60 @@ export default class AblyRealtimeService extends RealtimeService implements Ably
* @description Finds an available slot index for the participant and confirms it.
* @returns {void}
*/
private findSlotIndex = (): void => {
let slots = new Array(16).fill(null).map((_, i) => ({ slotIndex: i, clientId: null }));
private findSlotIndex = async (): Promise<void> => {
const slot = Math.floor(Math.random() * 16);

this.supervizChannel.presence.get((error, presences) => {
if (error) {
slots = [];
return;
}
const hasAnyOneUsingMySlot = await new Promise((resolve) => {
this.supervizChannel.presence.get((error, presences) => {
if (error) {
resolve(true);
return;
}

presences.forEach((presence) => {
if (presence.clientId === this.myParticipant.clientId) return;
presences.forEach((presence) => {
if (presence.clientId === this.myParticipant.clientId) return;

if (presence.data.slotIndex !== undefined && presence.data.slotIndex !== null) {
slots[presence.data.slotIndex].clientId = presence.clientId;
}
if (presence.data.slotIndex === slot) resolve(true);
});

resolve(false);
});
});

const slotToUse = slots.find((slot) => slot.clientId === null);

if (!slotToUse) return;
if (hasAnyOneUsingMySlot) {
this.logger.log(
'slot already taken by someone else, trying again',
this.myParticipant.clientId,
);
this.findSlotIndex();
return;
}

this.myParticipant.data.slotIndex = slotToUse.slotIndex;
this.updateMyProperties({ slotIndex: slotToUse.slotIndex });
this.updateMyProperties({ slotIndex: slot });
};

private validateSlots() {
/**
* @function validateSlots
* @description Validates the slot index of all participants and resolves conflicts.
* @returns {void}
*/
private async validateSlots(): Promise<void> {
const slots = [];

this.supervizChannel.presence.get((_, presences) => {
presences.forEach((presence) => {
if (presence.data.slotIndex !== undefined && presence.data.slotIndex !== null) {
slots.push({
slotIndex: presence.data.slotIndex,
clientId: presence.clientId,
timestamp: presence.timestamp,
});
}
await new Promise((resolve) => {
this.supervizChannel.presence.get((_, presences) => {
presences.forEach((presence) => {
const hasValidSlot =
presence.data.slotIndex !== undefined && presence.data.slotIndex !== null;

if (hasValidSlot) {
slots.push({
slotIndex: presence.data.slotIndex,
clientId: presence.clientId,
timestamp: presence.timestamp,
});
}
});
resolve(true);
});
});

Expand All @@ -885,9 +901,7 @@ export default class AblyRealtimeService extends RealtimeService implements Ably
}[]
> = {};

slots.forEach((a, index) => {
if (slots.findIndex((b) => b.slotIndex === a.slotIndex) === index) return;

slots.forEach((a) => {
if (!duplicatesMap[a.slotIndex]) {
duplicatesMap[a.slotIndex] = [];
}
Expand All @@ -896,11 +910,6 @@ export default class AblyRealtimeService extends RealtimeService implements Ably
});

Object.values(duplicatesMap).forEach((arr) => {
if (arr.length === 1 && arr[0].clientId === this.myParticipant.clientId) {
this.findSlotIndex();
return;
}

const ordered = arr.sort((a, b) => a.timestamp - b.timestamp);
ordered.shift();

Expand Down
12 changes: 6 additions & 6 deletions src/services/video-conference-manager/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,12 +283,12 @@ describe('VideoConferenceManager', () => {
test('should set callbacks if callbacks are defined', () => {
const callbacks = {
onToggleMicrophone: jest.fn(),
onToggleCamera: jest.fn(),
onToggleCam: jest.fn(),
onToggleTranscript: jest.fn(),
onToggleChat: jest.fn(),
onToggleScreenShare: jest.fn(),
onLeaveMeeting: jest.fn(),
onClickSettings: jest.fn(),
onClickHangup: jest.fn(),
onToggleMeetingSetup: jest.fn(),
};

VideoConferenceManagerInstance['onFrameLoad']();
Expand All @@ -303,12 +303,12 @@ describe('VideoConferenceManager', () => {
FrameEvent.FRAME_CALLBACKS_UPDATE,
JSON.stringify({
onToggleMicrophone: true,
onToggleCamera: true,
onToggleCam: true,
onToggleTranscript: true,
onToggleChat: true,
onToggleScreenShare: true,
onLeaveMeeting: true,
onClickSettings: true,
onClickHangup: true,
onToggleMeetingSetup: true,
}),
);
});
Expand Down
6 changes: 3 additions & 3 deletions src/services/video-conference-manager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,12 +321,12 @@ export default class VideoConfereceManager {

const callbacks = {
onToggleMicrophone: !!this.callbacks.onToggleMicrophone,
onToggleCamera: !!this.callbacks.onToggleCamera,
onToggleCam: !!this.callbacks.onToggleCam,
onToggleTranscript: !!this.callbacks.onToggleTranscript,
onToggleChat: !!this.callbacks.onToggleChat,
onToggleScreenShare: !!this.callbacks.onToggleScreenShare,
onLeaveMeeting: !!this.callbacks.onLeaveMeeting,
onClickSettings: !!this.callbacks.onClickSettings,
onClickHangup: !!this.callbacks.onClickHangup,
onToggleMeetingSetup: !!this.callbacks.onToggleMeetingSetup,
};

this.messageBridge.listen(MeetingControlsEvent.CALLBACK_CALLED, (callback: string) => {
Expand Down
6 changes: 3 additions & 3 deletions src/services/video-conference-manager/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ export interface VideoManagerOptions {
layoutMode?: LayoutMode;
callbacks?: {
onToggleMicrophone?: () => void;
onToggleCamera?: () => void;
onToggleCam?: () => void;
onToggleTranscript?: () => void;
onToggleChat?: () => void;
onToggleScreenShare?: () => void;
onLeaveMeeting?: () => void;
onClickSettings?: () => void;
onClickHangup?: () => void;
onToggleMeetingSetup?: () => void;
};
}

Expand Down
4 changes: 3 additions & 1 deletion src/web-components/base/styles/icon-button.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@ export const iconButtonStyle = css`

.icon-button--clickable:hover:not(.icon-button--no-hover) {
background: rgb(var(--sv-gray-300));
transition: 0.25s background-color ease-in;
}

.icon-button--clickable:focus:not(.icon-button--no-hover) {
transition: 0.25s background-color ease-in;
background: rgb(var(--sv-gray-300));
}
`;
4 changes: 3 additions & 1 deletion src/web-components/comments/components/annotation-filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ export class CommentsAnnotationFilter extends WebComponentsBaseElement {
>
<div class="comments__filter__toggle-button" slot="dropdown">
<span class=${classMap(textClasses)}>${selectedLabel}</span>
<superviz-icon name=${this.caret} size="xs"></superviz-icon>
<div class="comments__filter__icon">
<superviz-icon name=${this.caret} size="xs"></superviz-icon>
</div>
</div>
</superviz-dropdown>
</div>
Expand Down
11 changes: 10 additions & 1 deletion src/web-components/comments/components/comment-input.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ describe('CommentsCommentInput', () => {

element['updateHeight']();

expect(textarea.style.height).toBe('41px');
expect(textarea.style.height).toBe('43px');
});

describe('addAtSymbolInCaretPosition', () => {
Expand Down Expand Up @@ -378,4 +378,13 @@ describe('CommentsCommentInput', () => {
expect(mockCancelComment).toHaveBeenCalled();
});
});

describe('focusInput', () => {
test('should focus keyboard cursor on input when clicking on it', () => {
element['getCommentInput']().focus = jest.fn();
element['focusInput']();

expect(element['getCommentInput']().focus).toHaveBeenCalled();
});
});
});
19 changes: 14 additions & 5 deletions src/web-components/comments/components/comment-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,12 @@ export class CommentsCommentInput extends WebComponentsBaseElement {
disconnectedCallback(): void {
super.disconnectedCallback();
if (!['create-annotation', 'create-comment'].includes(this.eventType)) return;
const textarea = this.getCommentInput();

this.removeEventListener('keyup', this.sendEnter);
const textarea = this.getCommentInput();
textarea.removeEventListener('keydown', this.sendEnter);
textarea.removeEventListener('click', this.focusInput);
textarea.addEventListener('input', this.handleInput);
}

protected firstUpdated(
Expand All @@ -115,9 +117,8 @@ export class CommentsCommentInput extends WebComponentsBaseElement {

if (commentTextarea) {
commentTextarea.addEventListener('input', this.handleInput);

const textarea = this.getCommentInput();
textarea.addEventListener('keydown', this.sendEnter);
commentTextarea.addEventListener('click', this.focusInput);
commentTextarea.addEventListener('keydown', this.sendEnter);
}

if (this.text.length > 0) {
Expand Down Expand Up @@ -171,6 +172,10 @@ export class CommentsCommentInput extends WebComponentsBaseElement {
return { searchText, position };
};

private focusInput = () => {
this.getCommentInput().focus();
};

private handleInput = (e: InputEvent) => {
if (this.commentInput?.value.length === 0) this.btnActive = false;
else this.btnActive = true;
Expand Down Expand Up @@ -249,6 +254,10 @@ export class CommentsCommentInput extends WebComponentsBaseElement {
}

private sendEnter = (e: KeyboardEvent) => {
if (e.key !== 'Escape') {
e.stopImmediatePropagation();
}

if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
}
Expand Down Expand Up @@ -419,7 +428,7 @@ export class CommentsCommentInput extends WebComponentsBaseElement {
></superviz-comments-mention-list>
<div class="sv-hr"></div>
<div class="comments__input__options">
<button class="icon-button comments__input__mention-button">
<button class="icon-button icon-button--medium icon-button--clickable">
<superviz-icon
name="mention"
@click=${this.addAtSymbolInCaretPosition}
Expand Down
2 changes: 1 addition & 1 deletion src/web-components/comments/components/comment-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ export class CommentsCommentItem extends WebComponentsBaseElement {
<div class=${this.getClasses('header')}>
<div class=${this.getClasses('metadata')}>
${this.getAvatar()}
<span class="text text-bold sv-gray-600 ${this.getClasses('username')}"
<span class="text text-big text-bold sv-gray-700 ${this.getClasses('username')}"
>${this.username}</span
>
<span class="text text-small sv-gray-500 ${this.getClasses('date')}"
Expand Down
44 changes: 33 additions & 11 deletions src/web-components/comments/components/float-button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,21 +83,43 @@ export class CommentsFloatButton extends WebComponentsBaseElement {
if (!floatButton) return;

floatButton.setAttribute('style', this.positionStyles);

const windowSize = window.document.body.getBoundingClientRect().width;
const buttonPosition = floatButton.getBoundingClientRect();
const sideBarWidth = 320;

if (!this.commentsPosition || this.commentsPosition === 'left') {
this.shouldHide = buttonPosition.x < sideBarWidth;
return;
}

this.shouldHide = windowSize - buttonPosition.right < sideBarWidth;
});
}

private calculateIfShouldHide() {
const sidebar = document
.getElementsByTagName('superviz-comments')[0]
?.shadowRoot.querySelector('.superviz-comments');

const floatButton = this.shadowRoot.querySelector('.comments__floating-button');

if (!sidebar || !floatButton) return;

const {
left: sbLeft,
right: sbRight,
top: sbTop,
bottom: sbBottom,
} = sidebar.getBoundingClientRect();
const {
left: fbLeft,
right: fbRight,
top: fbTop,
bottom: fbBottom,
} = floatButton.getBoundingClientRect();

const sidebarHidesTop = sbBottom > fbTop && fbBottom > sbTop;
const sidebarHidesBottom = sbTop < fbBottom && fbTop < sbBottom;
const sidebarHidesLeft = sbRight > fbLeft && fbRight > sbLeft;
const sidebarHidesRight = sbLeft < fbRight && fbLeft < sbRight;

this.shouldHide =
(sidebarHidesBottom || sidebarHidesTop) && (sidebarHidesLeft || sidebarHidesRight);
}

protected render() {
this.calculateIfShouldHide();

const floatButtonClasses = {
'comments__floating-button': true,
'hide-button': !this.isHidden && this.shouldHide,
Expand Down
10 changes: 10 additions & 0 deletions src/web-components/comments/css/annotation-filter.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,14 @@ export const annotationFilterStyle = css`
align-items: center;
gap: 6px;
}

.comments__filter__toggle-button {
display: flex;
flex-direction: row;
gap: 4px;
}

.comments__filter__icon {
margin-top: -2px;
}
`;
14 changes: 1 addition & 13 deletions src/web-components/comments/css/comment-input.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const commentInputStyle = css`
white-space: pre-wrap;
word-wrap: break-word;
resize: none;
line-height: 1rem;
line-height: 1.15rem;
max-height: 5rem;
appearance: none;
height: 40px;
Expand Down Expand Up @@ -99,18 +99,6 @@ export const commentInputStyle = css`
visibility: visible;
}

.comments__input__mention-button {
display: flex;
align-items: center;
justify-content: center;
height: 32px;
width: 32px;
border-radius: 100%;
color: rgb(var(--sv-gray-600));
cursor: pointer;
transition: 0.25s background-color ease-in;
}

.mention:hover {
background-color: rgb(var(--sv-gray-200));
}
Expand Down
4 changes: 0 additions & 4 deletions src/web-components/comments/css/comment-item.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,4 @@ export const commentItemStyle = css`
.mentioned {
display: inline-block;
}

.comments__comment-item__username {
font-size: 14px;
}
`;
Loading
Loading