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

Media Controller Refactor #517

Merged
merged 14 commits into from
Apr 17, 2023
Merged

Media Controller Refactor #517

merged 14 commits into from
Apr 17, 2023

Conversation

heff
Copy link
Collaborator

@heff heff commented Apr 2, 2023

No functional changes, just reorganizing and moving things out of the file to make it easier to split out controller logic from the custom element.

The commits are intentional steps in the process (so far).

  • Moved util and platform tests to util files
  • Refactored _mediaStatePropagators, delegates, and some floating functions into one MediaUIStates object with a clear mapping between the state name, the getter, and related events.
  • Moved UI event handlers to its own MediaUIRequestHandlers object outside of MediaCotroller
  • Reapplied state & request objects back to the controller

@heff heff requested a review from a team as a code owner April 2, 2023 22:18
@vercel
Copy link

vercel bot commented Apr 2, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
media-chrome ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 17, 2023 4:50pm
media-chrome-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 17, 2023 4:50pm

@codecov
Copy link

codecov bot commented Apr 2, 2023

Codecov Report

Merging #517 (5ca7686) into main (33cd238) will increase coverage by 1.01%.
The diff coverage is 69.60%.

@@            Coverage Diff             @@
##             main     #517      +/-   ##
==========================================
+ Coverage   75.50%   76.52%   +1.01%     
==========================================
  Files          41       43       +2     
  Lines        7009     7045      +36     
==========================================
+ Hits         5292     5391      +99     
+ Misses       1717     1654      -63     
Impacted Files Coverage Δ
src/js/utils/time.js 84.21% <61.11%> (-8.58%) ⬇️
src/js/controller.js 64.46% <64.46%> (ø)
src/js/media-controller.js 74.69% <97.40%> (+5.89%) ⬆️
src/js/utils/platform-tests.js 100.00% <100.00%> (ø)
src/js/utils/utils.js 79.06% <100.00%> (+4.06%) ⬆️

... and 4 files with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@heff heff requested a review from cjpillsbury April 4, 2023 16:53
get: function(controller){
const { media } = controller;

return (media) ? media.paused : true;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit (non-b): unneeded parentheses

@luwes
Copy link
Contributor

luwes commented Apr 5, 2023

LGTM so far 👍

@heff
Copy link
Collaborator Author

heff commented Apr 11, 2023

At a decent merge point now, with other 1.0 work looming.

Followup steps:

  • Wrap up controller/container decision to guide next move here
  • Build the MediaController object on its own, then reapply based on the previous bullet.

Also Codecov really wants more tests. I don't think that should be a blocker to merging this since there wasn't added functionality.

src/js/media-controller.js Outdated Show resolved Hide resolved
@@ -629,36 +836,33 @@ class MediaController extends MediaContainer {
mediaSetCallback(media) {
super.mediaSetCallback(media);

// TODO: What does this do? At least add comment, maybe move to media-container
Copy link
Collaborator Author

@heff heff Apr 11, 2023

Choose a reason for hiding this comment

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

@gkatsev what does this do? (I'll add a comment)

Copy link
Contributor

Choose a reason for hiding this comment

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

This makes the media element focusable if a user didn't specify a tabindex already. -1 means that it'll be focusable via a mouse click or programmatically, but not be part of the tab order.

I believe it's necessary to keep focus inside the player for things like keyboard shortcuts.

propagateMediaState(this.mediaStateReceivers, stateName, state);
// TODO: I don't think we want these events to bubble? Video element states don't. (heff)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@cjpillsbury confirming it's ok to turn off bubbling here. I don't have a strong defense but it feels wrong to bubble these state change events

Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe I added this to account for nested component use cases so we wouldn't need to know if some other bit of code happened to add an event handler on e.g. a theme, or a wrapping component, etc (similar to considerations for composed: true). Since I can't easily confirm if anything would break and this would be a breaking change, I'd recommend keeping it for this iteration of the refactor and we can determine if we can remove it for simplicity during the v1.0 effort.

src/js/media-controller.js Outdated Show resolved Hide resolved
* @param {number} ms
* @return {Promise}
*/
export const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
Copy link
Collaborator

Choose a reason for hiding this comment

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

nitpick(blocking): missing EOF newline

Copy link
Collaborator

@cjpillsbury cjpillsbury left a comment

Choose a reason for hiding this comment

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

question(non-blocking): any concerns with taking the code you split out and moving it into its own JS module? Even if we plan on doing non-trivial refactors to it during our v1.0 effort, this would likely make merge conflicts less of an issue.

@cjpillsbury
Copy link
Collaborator

Aside from us banging on this for smoke testing around the edges (particularly in non-desktop & streaming cases), this looks great as an initial step to create some architecture seams!

src/js/media-controller.js Outdated Show resolved Hide resolved
static get observedAttributes() {
return super.observedAttributes.concat('nohotkeys', 'hotkeys', 'default-stream-type');
}
const MediaUIStates = {
Copy link
Contributor

Choose a reason for hiding this comment

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

One thing that we're losing in the Delegates->MediaUIStates transition is the concept of a default delegate. A lot of the these just need to do a property or attribute reference on the media element, and now they all need to be included explicitly.

static get observedAttributes() {
return super.observedAttributes.concat('nohotkeys', 'hotkeys', 'default-stream-type');
}
const MediaUIStates = {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be good to move this into a separate file. It'll help clean up the diff for this file (media-controller) as well.

Comment on lines 165 to 166
// TODO: Returns undefined and a string, consider a better type
// not tied to attribute strings
Copy link
Contributor

Choose a reason for hiding this comment

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

a couple of questions/thoughts (non-blocking):

  • should this return an empty string for the empty case?
  • instead of a string, should this be a tuple (an array in the meantime) that contains the start and end? [start, end], then consumers can stringify as they want. The default case would be an empty array.
  • in addition, should this account for multiple seekable ranges?

},
MEDIA_CAPTIONS_LIST: {
get: function(controller) {
// TODO: Move to non attr specific values
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be fine to leave as is for now. These would get updated when we combine captions and subtitles lists.

@gkatsev
Copy link
Contributor

gkatsev commented Apr 12, 2023

Looks like there are conflicts now. Hopefully, they're easy to resolve.

Copy link
Collaborator

@cjpillsbury cjpillsbury left a comment

Choose a reason for hiding this comment

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

issue(blocker): We should move the "abstracted, javascript only" parts of the state management into its own module to mitigate merge conflict issues going forward (particularly on our Media Chrome v1.0 push).

} from './utils/captions.js';

let volumeSupported;
export const volumeSupportPromise = hasVolumeSupportAsync().then((supported) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

NOTE: Currently exporting this based on our status quo impl of checking/propagating volume support in MediaController.

Copy link
Contributor

@luwes luwes left a comment

Choose a reason for hiding this comment

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

LGTM 👍

@cjpillsbury cjpillsbury merged commit 462bd03 into main Apr 17, 2023
@luwes luwes deleted the controller-refactor branch April 17, 2023 20:49
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.

4 participants