-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Refactor client canvas #52431
base: master
Are you sure you want to change the base?
Refactor client canvas #52431
Conversation
Also, we no longer need to set the canvas size manually; it is now handled by `objectFit: scale-down`.
We get the canvas resolution from the server, there doesn't seem to be a need to calculate it from the browser window size.
It didn't work because it happened too early, before we even showed the MFA dialog which stole focus. This is a temporary fix, I will do it more elegantly in the future.
Remove component memoization, it didn't work anyway and doesn't seem needed. We don't have anything particularly expensive to render here from React's perspective.
@@ -179,35 +207,11 @@ const useDesktopPlayer = ({ clusterId, sid }) => { | |||
setStatusText(info); | |||
}, []); | |||
|
|||
const clientOnClientScreenSpec = useCallback( |
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 is no longer needed thanks to the CSS property object-fit: 'scale-down'
. Please note that the scaling behavior has changed a bit. Previously, if the browser window was larger than the recording, we scaled the recording up. I'm not sure if it's the right thing to do, it could result in a low quality, pixelated image in some scenarios.
Instead, now the physical size of a recording won't exceed its resolution. I don't know if the previous behavior was a bug or a feature, but I can bring it back with a different value of object-fit
:)
Also, a quick preview of a bug that we had before, caused by manual scaling:
before.mov
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'll have to double check, but I think there is also a usecase where we don't want the canvas to change resolution at all in order to preserve some special aspect ratio on the remote device. however, since that wasn't a thing on the client side before (i think) then its still probably handled on the server side.
i could also be misremembering anyway, so I'll look for it
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 believe the new implementation should be no worse than the previous one at handling it, but maybe I'm missing something. If you will have more details about it please let me know!
} | ||
}, [client, clientOnTdpInfo]); | ||
|
||
useEffect(() => { |
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.
All these effects are really verbose. In a separate PR I will refactor them to something like:
useListener(
client.onWsClose,
useCallback(message => {
setTdpConnection({ status: 'closed', statusText: message });
}, [])
);
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 now it's a canvas that can render anything, I will rename it to CanvasRenderer
in the future.
it works really well for my locally. most the code refactor is good so far (and similar to the direction I was going) but I didn't finish the review. will continue tomorrow morning. |
in |
The main issue with the current architecture was that
TdpClientCanvas
had too many responsibilities. It subscribed to all event listeners, including those unrelated to rendering. Additionally, because event subscription happened withinTdpClientCanvas
, any work needed at the parent level required passing even more callbacks down to the component.To address this, I extracted a new component dedicated solely to rendering frames. This component no longer subscribes to event listeners from the parent. Instead, it exposes an imperative API that the parent can interact with. In React, this is achieved using
useImperativeHandle
combined withforwardRef
. Thanks to it, places that use the canvas have much more flexibility.The exposed API looks like below:
While refactoring the component, I shipped some improvements:
object-fix: 'scale-down
). This frees us from calculating the canvas size in the player and fixes a bug where the recording could have lost its proportions.Please review the PR commit by commit.
changelog: Resolved an issue where desktop session recordings could have incorrect proportions