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

[DRAFT] Demo: store the settings in the url hash #1349

Open
wants to merge 20 commits into
base: dev
Choose a base branch
from

Conversation

Florent-Bouisset
Copy link
Collaborator

@Florent-Bouisset Florent-Bouisset commented Jan 5, 2024

Storing the player settings in the url hash let us refresh the demo page while keeping all the settings previously set.
It's more efficient and comfortable when debugging to not have to reset them manually after each page refresh.

To Do:

  • Add a switch/checkbox to disable/enable the storing in url OR let the RxPlayer logo be a tag with href with an empty hash allowing to reset.
  • Reloading a preset content will display it as a custom content, we can eventually improve that

@peaBerberian
Copy link
Collaborator

Add a switch/checkbox to disable/enable the storing in url OR let the RxPlayer logo be a tag with href with an empty hash allowing to reset.

I would advocate for both:

  • the switch would stop the URL from updating but keep it where it was. This would be useful when debugging settings you know are problematic, then playing with them, while being able to reset to the problematic scenario by just refreshing the page
  • the link would just reset to the default

const loadContent = React.useCallback((content: IPlayableContent) => {
getLoadVideoOptions(content).then(
(loadVideoOptions) => {
loadVideo(loadVideoOptions);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I didn't look too much into it yet but have you verified that this code is not sensible to race conditions?

For example, if loadContent is called multiple consecutive times, are we sure that the last call will lead to playback in the end?

Will look more into it, but that's a question I was asking myself reading this

Copy link
Collaborator

Choose a reason for hiding this comment

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

(the issue may already have been there before)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I tried to provoke a race condition but didn't succeed in doing so.
I still have added the code to prevent any race condition, let me know what you think of that because I'm not 100% sure that this is the correct way of doing so.

@peaBerberian peaBerberian changed the base branch from next-v4 to dev January 25, 2024 11:38
@peaBerberian peaBerberian added Demo Relative to the RxPlayer's demo page Priority: 2 (Medium) This issue or PR has a medium priority. labels Feb 5, 2024
@peaBerberian peaBerberian added this to the 4.1.0 milestone Feb 5, 2024
const { loadVideoConfig, playerConfig, disableReactiveURL } = parsedHash;
if (typeof loadVideoConfig === "string") {
// maybe we want to check the shape of the object to
// be error prone instead of casting?
Copy link
Collaborator

Choose a reason for hiding this comment

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

🤷‍♂️

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I have made some changes here, JSON.parse() is not safe if the string is not convertible to a JS object. Therefore I wrapped it in a try/catch.
I have added some checks on the shape of the parsed object, there are quite simple as they only check the "typeof", that would be enough. I didn't went as deep as checking if values are respecting the typescript intersection (maybe it's preferable to use a validating library like Yup or Joi if we want to make such checks?)

I have also handled the case where we stringify/Parse "Infinity'

if (!isAlreadyLoading) {
setIsAlreadyLoading(true);
try {
const loadVideoOptions = await getLoadVideoOptions(content);
Copy link
Collaborator

Choose a reason for hiding this comment

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

To be honest I still feel a race condition is technically possible here.

Perhaps we should have a mechanism (useRef?) to check that he content is still the last one wanted?

Copy link
Collaborator

Choose a reason for hiding this comment

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

To reproduce a race condition, you would have a first getLoadVideoOptions responding very slowly (e.g. server certificate behind a slow CDN) and try to load another content without this issue.

Here we might play the second content, then play the first

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh my bad I didn't see isAlreadyLoading is here to fix this. Though I don't think this is the right solution. We want to play the last content, not the initial one.


const { useCallback, useEffect, useRef, useState } = React;

// time in ms while seeking/loading/buffering after which the spinner is shown
const SPINNER_TIMEOUT = 300;

const isShapeOfLoadVideoConfig = (arg: any): arg is ILoadVideoSettings => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why the need to do that? Is it for type casting?

It looks very dependent of what we expose through the demo's options.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If a user reach the demo page with an URL with a pre-establish config:
http://player.com/#config={foo:bar} if at some point we change the demo, and the expected url is now
http://player.com/#config={toto:tata} then we could have errors.

In others words, the URL cannot be trusted and we have to check if the data in it is coherent when parsing it

Copy link
Collaborator

Choose a reason for hiding this comment

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

OK I get it.

But the downside would be that we have to make sure to update that code each time the shape is changed... And I don't think we'll think to do that.

Maybe we could type arg as ILoadVideoConfig or whatever so that TypeScript warn us if we're exploiting inexistant properties? Even with that I don't know...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Demo Relative to the RxPlayer's demo page Priority: 2 (Medium) This issue or PR has a medium priority.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants