Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[Player-54] refacto modal position #124

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

jparez
Copy link
Contributor

@jparez jparez commented Feb 10, 2025

Description

  • Add an option to display the toolbar on the left or right side of the screen
  • Calculate the position of the modal when opening for the first time
  • Make the widget modal draggable inside the video wrapper
  • Add a magnetic feature when the modal is dragged near its starting position
  • Small refactor and fixes (icons, color theme, etc.)

Demo

PLAYER-54-modal-draggable.mp4

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

@jparez jparez force-pushed the dev/player-54-refacto-modal-position branch 3 times, most recently from 439b5ad to 189adeb Compare February 10, 2025 16:26
@jparez jparez requested a review from pgivel February 10, 2025 16:38
@jparez jparez force-pushed the dev/player-54-refacto-modal-position branch from 189adeb to 67eacec Compare February 11, 2025 07:59
@jparez jparez force-pushed the dev/player-42-customize-toolbar-order branch 2 times, most recently from eebd8f3 to 7d02725 Compare February 11, 2025 08:26
Base automatically changed from dev/player-42-customize-toolbar-order to main February 11, 2025 08:27
@jparez jparez force-pushed the dev/player-54-refacto-modal-position branch from 67eacec to 3b43091 Compare February 11, 2025 08:28

/**
* Creates modal header element with title and close button
* @param {?string} title - Header title content
Copy link
Contributor

Choose a reason for hiding this comment

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

What's preferable ? ?string or string|null?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

string|null is clearer

* @returns {HTMLElement} Configured header element
*/
createModalHeader(title) {
const header = document.createElement('div');
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not use a semantic element like header? Is it out of scope for this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Like you said, it's a semantic element used for SEO purposes. The

tag can help improve code understanding for a main header, but I'm not sure it's useful for the readability of a modal. Personally, I prefer using
elements.

Copy link
Contributor

@caarmen caarmen Feb 20, 2025

Choose a reason for hiding this comment

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

It's for SEO but also accessibility (used by screen readers for the visually impaired).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, but the app isn't ARIA-compliant, so this alone isn't really relevant.

* @returns {HTMLElement} Configured modal element
*/
createModalElement(classes, width, height) {
const modal = document.createElement('div');
Copy link
Contributor

Choose a reason for hiding this comment

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

<dialog> wouldn't be relevant?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It could be, since the element comes with a built-in API for opening and closing. However, given the legacy code, I'm not sure it's worth the effort to refactor. For a new project, though, it would definitely be a better choice.

}

/**
* Initializes drag-and-drop and positioning for the modal
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this "drag and drop"? Or just dragging (positioning/moving)?

Is there an action done upon dropping?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's just dragging, but in my confused mind, 'drag' always comes with 'drop'! >_<

Comment on lines +460 to +466
this.video.addEventListener(
'loadedmetadata',
() => {
this.videoWrapper.style.aspectRatio = this.video.videoWidth + '/' + this.video.videoHeight;
},
{once: true},
);
Copy link
Contributor

Choose a reason for hiding this comment

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

We should check that this doesn't break anything in SiB cc @dpilarsk

];
}
this.instance.root.focus();
this.keyboardCallbacks.forEach((item, index, array) => {
array[index].removeListener = this.instance.addListener(this.instance.root, item.event, item.handler);
array[index].removeListener = this.instance.addListener(this.instance.video, item.event, item.handler);
Copy link
Contributor

Choose a reason for hiding this comment

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

I fear this may break everything on Shadow In Browser? cc @dpilarsk

Copy link
Contributor

Choose a reason for hiding this comment

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

@jparez After discussing a bit with Dimitri, there is no issue with breaking SiB compatibility, we just have to list the breaking changes in the release changelog. (I think changing the html element that listens for the events is probably a breaking change)

Comment on lines +136 to +143
if (state.overlay.widgetsOpened.length === 0) {
state.overlay.isOpen = false;
}
if (overlayID) {
state.overlay.widgetsOpened = state.overlay.widgetsOpened.filter((id) => id !== overlayID);
} else {
state.overlay.widgetsOpened = [];
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if (state.overlay.widgetsOpened.length === 0) {
state.overlay.isOpen = false;
}
if (overlayID) {
state.overlay.widgetsOpened = state.overlay.widgetsOpened.filter((id) => id !== overlayID);
} else {
state.overlay.widgetsOpened = [];
}
if (overlayID) {
state.overlay.widgetsOpened = state.overlay.widgetsOpened.filter((id) => id !== overlayID);
} else {
state.overlay.widgetsOpened = [];
}
if (state.overlay.widgetsOpened.length === 0) {
state.overlay.isOpen = false;
}

Shouldn't the widgetsOpened be cleared before we check if it's empty?

@@ -191,7 +186,7 @@ module.exports = class IOThrottling extends OverlayPlugin {
this.container.appendChild(clearCacheDiv);

// Render into document
this.instance.root.appendChild(this.widget);
this.instance.root.appendChild(modal);
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand why for some widgets you kept this line while removing it for others but honestly I trust you for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

for IoThrottling is a mistake :$

@@ -199,7 +199,7 @@ module.exports = class MouseEvents {

this.mouseCallbacks.forEach((item, index, array) => {
array[index].removeListener = this.instance.addListener(
this.instance.videoWrapper,
this.instance.video,
Copy link
Contributor

Choose a reason for hiding this comment

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

(ShadowInBrowser overrides this function and doesn't call the super function, so no worries here)

Comment on lines +276 to +277
const modalWidth = this.widget.offsetWidth || 200;
const modalHeight = this.widget.offsetHeight || 100;
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe these values could be extracted to a CONST at the begining of this file. Similar comment for the +/- 10 values in the next lines of this function

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants