-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
VIDCS-3340: Add pinning feature #41
base: develop
Are you sure you want to change the base?
Conversation
This reverts commit 6a5bbfd.
c37e048
to
a620a98
Compare
|
||
# Option to skip the waiting room. Useful when doing development work on the meeting room | ||
VITE_BYPASS_WAITING_ROOM= |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this to help speed up development testing. Let me know if you think it's ok to add this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm okay with adding this option in. Looks like you added it to the file twice so maybe remove one of them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me! Should we give it an initial value?
@@ -126,6 +131,8 @@ export type SessionProviderProps = { | |||
children: ReactNode; | |||
}; | |||
|
|||
const MAX_PIN_COUNT = isMobile() ? 1 : 3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we talked about using small viewport instead of mobile for this stuff, but the number of subscribers we display is currently governed by isMobile
too. I would say let's change this in both places in a follow-up PR if that's what we decide to do.
!isMobile() && ( | ||
<div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ignore this, it's to make tests pass after I loaded tailwind into the setup test and it realised the tests were wrong.
Anyway, @cpettet's PR changes this component so when that PR is merged in I'll deal with the conflicts and this will probably not be changed by my PR at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was just about to say, wait I remember lots of changes around here in a different PR 😆
return `Pin ${participantName}'s video`; | ||
}; | ||
|
||
const onClick = (clickEvent: MouseEvent<HTMLButtonElement>) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll see this here and in the Subscriber component. Trust me when I say I tried everything to avoid adding this hack. In the end it was innevitable, even though we could use tailwind hover states to avoid some of this, the MUI toolbar open logic is not css based. Also tailwind struggled when the tooltip itself was hovered and de-applied the hover css to the area underneath.
At least I can say that this approach works.
const pinSubscriber = useCallback( | ||
(id: string) => { | ||
setSubscriberWrappers((previousSubscriberWrappers) => { | ||
const subscribers = previousSubscriberWrappers | ||
.map((subscriberWrapper) => { | ||
if (subscriberWrapper.id === id) { | ||
return { | ||
...subscriberWrapper, | ||
isPinned: !subscriberWrapper.isPinned, | ||
}; | ||
} | ||
return subscriberWrapper; | ||
}) | ||
.sort(sortByDisplayPriority(activeSpeakerId)); // Sorting by display priority will place this pinned participant above the rest | ||
return subscribers; | ||
}); | ||
}, | ||
[activeSpeakerId] | ||
); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic is untested right now (other than the integration test).
We plan to refactor this context provider in a way that will allow us to better test this internal logic.
const bypass = searchParams.get('bypass'); | ||
const canEnter = !hasAccess && bypass !== 'true'; | ||
return canEnter ? ( | ||
const bypass = | ||
searchParams.get('bypass') === 'true' || import.meta.env.VITE_BYPASS_WAITING_ROOM === 'true'; | ||
const mustEnterWaitingRoom = !hasAccess && !bypass; | ||
return mustEnterWaitingRoom ? ( | ||
<Navigate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added the env var but also refactored slightly. I found canEnter
confusing as it means canEnterWaiting room, whereas can enter IMO makes more sense to be about the room.
!isMobile() && ( | ||
<div> | ||
<Tooltip title={title} aria-label="add"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment here as for LayoutButton - tests were not working once tailwind was enabled and this will all be overwritten when the mobile menu bar PR is merged and I pull in those changes. Don't worry about this for now.
@@ -61,13 +66,30 @@ const Subscriber = ({ | |||
} | |||
}, [subscriberWrapper, isScreenShare]); | |||
|
|||
const handlePinClick = (clickEvent: MouseEvent<HTMLButtonElement>) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, nothing I could do to avoid this unfortunately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since this is repeated in two components, could it be broken out to a separate hook? 🤔
@@ -1,3 +1,4 @@ | |||
import '../index.css'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes vitest understand at least some of the tailwind rules, like className="hidden"
means toBeVisible()
is false.
It cannot do stuff like hover states though, probably more due to JSDOM not implementing CSS
sessionHasScreenshare: boolean, | ||
layoutMode: LayoutMode, | ||
activeSpeakerId: string | undefined, | ||
index: number | ||
) => { | ||
// We display subscriber as large if it is screenshare or active speaker given that layout mode is active speaker and | ||
// screenshare is not being displayed | ||
return ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't attempt to simplify this at all, I think it's better to keep it readable and obvious as to which cases do what.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
impressive job 👏 I left two comments for now, I might take another look again since the PR is just massive 😱
|
||
const getTooltipText = () => { | ||
if (isDisabled) { | ||
return `You can't pin any more tiles`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: maybe instead of a current message, we could say the Current ${MAX_PIN} pin limit has been reached
or something like that?
@@ -61,13 +66,30 @@ const Subscriber = ({ | |||
} | |||
}, [subscriberWrapper, isScreenShare]); | |||
|
|||
const handlePinClick = (clickEvent: MouseEvent<HTMLButtonElement>) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since this is repeated in two components, could it be broken out to a separate hook? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good so far! Just have a few comments/questions. Let me know what you think!
|
||
# Option to skip the waiting room. Useful when doing development work on the meeting room | ||
VITE_BYPASS_WAITING_ROOM= |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me! Should we give it an initial value?
}, [subscriberWrappers]); | ||
|
||
/** | ||
* Marks a subscriber as pinned, and moves it to the top of the display order. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit, doesn't this function work for unpinning, too? Could we update the jsdoc?
@@ -17,6 +17,12 @@ const sortByDisplayPriority = | |||
if (wrapperB.isScreenshare) { | |||
return 1; | |||
} | |||
if (wrapperA.isPinned) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add onto the jsdoc that we want pinned users to have priority? Since we have several prioritized subscribers, we should delineate the order, too.
handleClick: (clickEvent: MouseEvent<HTMLButtonElement>) => void; | ||
}; | ||
|
||
const PinButton = ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we get some jsdoc for this component?
@@ -8,4 +8,5 @@ export type SubscriberWrapper = { | |||
subscriber: Subscriber; | |||
isScreenshare: boolean; | |||
id: string; | |||
isPinned: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add to the jsdoc, too?
const subscribers = previousSubscriberWrappers | ||
.map((subscriberWrapper) => { | ||
if (subscriberWrapper.id === id) { | ||
return { | ||
...subscriberWrapper, | ||
isPinned: !subscriberWrapper.isPinned, | ||
}; | ||
} | ||
return subscriberWrapper; | ||
}) | ||
.sort(sortByDisplayPriority(activeSpeakerId)); // Sorting by display priority will place this pinned participant above the rest | ||
return subscribers; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we break the state function into a helper? I know we plan on refactoring later, but it might make sense to separate this logic so we can add the test now. Hopefully, the tests we write for this helper, could still be reused.
const hasVideo = subscriberWrapper.subscriber?.stream?.hasVideo; | ||
const initials = subscriberWrapper.subscriber?.stream?.initials; | ||
const username = subscriberWrapper.subscriber?.stream?.name ?? ''; | ||
const hasAudio = subscriberWrapper.subscriber.stream?.hasAudio; | ||
const audioIndicatorStyle = | ||
'rounded-xl absolute top-3 right-3 bg-darkGray-55 h-6 w-6 items-center justify-center flex m-auto'; | ||
|
||
const pinStyle = `flex rounded-xl absolute top-3 left-3 h-6 w-6 items-center justify-center m-auto`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we move this into the PinButton
component?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's forward-thinking for the participant list changes, feel free to resolve this and my other comments.
> | ||
{!isScreenShare && ( | ||
<PinButton | ||
color="white" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we move this to the PinButton
directly?
What is this PR doing?
Add part 1 of pinning feature.
What this PR includes:
NOT INCLUDED IN THIS PR:
How should this be manually tested?
What are the relevant tickets?
Resolves VIDCS-3340