Skip to content
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

Layout for avoiding overlapping of voice/text chat, screenshare, plugins #625

Merged
merged 8 commits into from
Feb 14, 2023

Conversation

dmitry-yudakov
Copy link
Contributor

@dmitry-yudakov dmitry-yudakov commented Feb 2, 2023

https://momentum.nifty.pm/l/QohwTQejaMJ

Some long description for reference:

We support several screen elements that need to be aligned together: maximized elements on top-left (like video/screenshare/plugins), top-right elements (voice and text chats) and previews on bottom-right (video/plugins/screencast). Video/screencast/plugins can also move between top-left and bottom-right - the important thing here is to not make them detach from parent when moving between screen sections - and it's pretty challenging to satisfy all this.

Current solution uses flexbox for SectionedScreen component and SectionedScreenPortal elements (used as Portal for all abovementioned). SectionedScreenPortal appends a child to SectionedScreen using proper class based on target section.

Different sections' classes have slightly different styles/order and additional logic is applied to force the flexbox break into 2 rows if both top-right and bottom-right elements are detected. We use ":has" selector that currently has relatively limited support - it currently works on Chrome/Brave, but on Firefox you still need to activate it with config. There's a fallback option allowing almost same functionality without the ability to use full height of the screen when only top-left and/or top-right elements are present - they're at 60% height then.

Using flexbox is a working though not perfect solution as it's not really intended for such layout.

I tried display:grid but it becomes even more complex to manipulate it in flexible enough manner based on content.

My original approach was with 2 nested containers - one for top/bottom row and one left/right for each row - it was working nicely as a layout but moving between sections triggers child detach, which causes interruptions with iframe videos, etc. It's probably possibly to use shadow DOM for translating screen element into different sections but I doubt it's possible using only css.

Another planned approach was having React Context used by SectionedScreen and SectionedScreenPortals for sharing info between them and applying different styles and helper elements based on that, but it seems css with :has selector allows to satisfy all our current requirements.

Some relatively new css selectors like :only-child, :only-of-type, :nth-of-type could also be of use in future.

Some useful links:
https://ishadeed.com/article/conditional-css/
https://tobiasahlin.com/blog/flexbox-break-to-new-row/

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Aligning_Items_in_a_Flex_Container

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout

Shadow DOM:
whatwg/html#5484 (comment) - nice and simple example
https://stackoverflow.com/questions/42274721/shadow-dom-and-reactjs
https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow

We support several screen elements that need to be aligned together: maximized elements on top-left (like video/screenshare/plugins), top-right elements (voice and text chats) and previews on bottom-right (video/plugins/screencast). Video/screencast/plugins can also move between top-left and bottom-right - the important thing here is to not make them detach from parent when moving between screen sections - and it's pretty challenging to satisfy all this.

Current solution uses flexbox for SectionedScreen component and SectionedScreenPortal elements (used as Portal for all abovementioned). SectionedScreenPortal appends a child to SectionedScreen using proper class based on target section.

Different sections' classes have slightly different styles/order and additional logic is applied to force the flexbox break into 2 rows if both top-right and bottom-right elements are detected. We use ":has" selector that currently has relatively limited support - it currently works on Chrome/Brave, but on Firefox you still need to activate it with config. There's a fallback option allowing almost same functionality without the ability to use full height of the screen when only top-left and/or top-right elements are present - they're at 60% height then.

Using flexbox is a working though not perfect solution as it's not really intended for such layout.

I tried display:grid but it becomes even more complex to manipulate it in flexible enough manner based on content.

My original approach was with 2 nested containers - one for top/bottom row and one left/right for each row - it was working nicely as a layout but moving between sections triggers child detach, which causes interruptions with iframe videos, etc. It's probably possibly to use shadow DOM for translating screen element into different sections but I doubt it's possible using only css.

Another planned approach was having React Context used by SectionedScreen and SectionedScreenPortals for sharing info between them and applying different styles and helper elements based on that, but it seems css with :has selector allows to satisfy all our current requirements.

Some relatively new css selectors like :only-child, :only-of-type, :nth-of-type could also be of use in future.

Some useful links:
https://ishadeed.com/article/conditional-css/
https://tobiasahlin.com/blog/flexbox-break-to-new-row/

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Aligning_Items_in_a_Flex_Container

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout

Shadow DOM:
whatwg/html#5484 (comment) - nice and simple example
https://stackoverflow.com/questions/42274721/shadow-dom-and-reactjs
https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow
@dmitry-yudakov dmitry-yudakov marked this pull request as ready for review February 13, 2023 15:59
@@ -27,6 +28,9 @@ const AppLayers: FC<PropsInterface> = (props) => {
<div data-testid="AppLayers-test">
<ToastMessage position={toast.POSITION.BOTTOM_RIGHT} theme={theme} />
<UnityControlContextProvider value={unityStore.unityInstanceStore.unityControlInst}>
<div id="sectioned-screen-container">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is temporary solution. It should be designed properly.

@dmitry-yudakov dmitry-yudakov merged commit 8643a08 into develop Feb 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants