From 5121b7cc3d11a48f8afeb7c1f76641df62264c98 Mon Sep 17 00:00:00 2001 From: saasfreelancer Date: Thu, 1 Dec 2022 15:19:34 +0500 Subject: [PATCH 01/36] feat(cxl-ui): rename jw player component Co-authored-by: Andrew Noblet --- .../scss/{jw-player => cxl-jw-player}/chapter.scss | 0 .../cxl-jw-player.scss} | 0 .../{jw-player => cxl-jw-player}/README.md | 6 +++--- .../{jw-player => cxl-jw-player}/index.html.js | 0 .../components/{jw-player => cxl-jw-player}/index.js | 6 +++--- .../{jw-player => cxl-jw-player}/mixins/BaseMixin.js | 0 .../mixins/CaptionMixin.js | 0 .../mixins/SavePositionMixin.js | 0 .../mixins/chapter/index.html.js | 0 .../mixins/chapter/index.js | 2 +- .../{jw-player => cxl-jw-player}/mixins/index.js | 0 .../{jw-player => cxl-jw-player}/utility.js | 0 packages/cxl-ui/src/index-jwplayer.js | 2 +- packages/cxl-ui/src/index-storybook.js | 2 +- packages/cxl-ui/src/styles/jw-player/.gitignore | 1 - .../{jw-player => cxl-jw-player}/index.stories.js | 12 ++++++------ .../{jw-player => cxl-jw-player}/playlist.stories.js | 12 ++++++------ 17 files changed, 21 insertions(+), 22 deletions(-) rename packages/cxl-ui/scss/{jw-player => cxl-jw-player}/chapter.scss (100%) rename packages/cxl-ui/scss/{jw-player/jw-player.scss => cxl-jw-player/cxl-jw-player.scss} (100%) rename packages/cxl-ui/src/components/{jw-player => cxl-jw-player}/README.md (98%) rename packages/cxl-ui/src/components/{jw-player => cxl-jw-player}/index.html.js (100%) rename packages/cxl-ui/src/components/{jw-player => cxl-jw-player}/index.js (81%) rename packages/cxl-ui/src/components/{jw-player => cxl-jw-player}/mixins/BaseMixin.js (100%) rename packages/cxl-ui/src/components/{jw-player => cxl-jw-player}/mixins/CaptionMixin.js (100%) rename packages/cxl-ui/src/components/{jw-player => cxl-jw-player}/mixins/SavePositionMixin.js (100%) rename packages/cxl-ui/src/components/{jw-player => cxl-jw-player}/mixins/chapter/index.html.js (100%) rename packages/cxl-ui/src/components/{jw-player => cxl-jw-player}/mixins/chapter/index.js (95%) rename packages/cxl-ui/src/components/{jw-player => cxl-jw-player}/mixins/index.js (100%) rename packages/cxl-ui/src/components/{jw-player => cxl-jw-player}/utility.js (100%) delete mode 100644 packages/cxl-ui/src/styles/jw-player/.gitignore rename packages/storybook/cxl-ui/{jw-player => cxl-jw-player}/index.stories.js (81%) rename packages/storybook/cxl-ui/{jw-player => cxl-jw-player}/playlist.stories.js (80%) diff --git a/packages/cxl-ui/scss/jw-player/chapter.scss b/packages/cxl-ui/scss/cxl-jw-player/chapter.scss similarity index 100% rename from packages/cxl-ui/scss/jw-player/chapter.scss rename to packages/cxl-ui/scss/cxl-jw-player/chapter.scss diff --git a/packages/cxl-ui/scss/jw-player/jw-player.scss b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player.scss similarity index 100% rename from packages/cxl-ui/scss/jw-player/jw-player.scss rename to packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player.scss diff --git a/packages/cxl-ui/src/components/jw-player/README.md b/packages/cxl-ui/src/components/cxl-jw-player/README.md similarity index 98% rename from packages/cxl-ui/src/components/jw-player/README.md rename to packages/cxl-ui/src/components/cxl-jw-player/README.md index d8d40eb94..33202d041 100644 --- a/packages/cxl-ui/src/components/jw-player/README.md +++ b/packages/cxl-ui/src/components/cxl-jw-player/README.md @@ -1,15 +1,15 @@ -# JW Player +# CXL JW Player ## Usage ``` - + > ``` ## Features: diff --git a/packages/cxl-ui/src/components/jw-player/index.html.js b/packages/cxl-ui/src/components/cxl-jw-player/index.html.js similarity index 100% rename from packages/cxl-ui/src/components/jw-player/index.html.js rename to packages/cxl-ui/src/components/cxl-jw-player/index.html.js diff --git a/packages/cxl-ui/src/components/jw-player/index.js b/packages/cxl-ui/src/components/cxl-jw-player/index.js similarity index 81% rename from packages/cxl-ui/src/components/jw-player/index.js rename to packages/cxl-ui/src/components/cxl-jw-player/index.js index c0a80cb51..8572ffc89 100644 --- a/packages/cxl-ui/src/components/jw-player/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/index.js @@ -1,12 +1,12 @@ import { LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; import { BaseMixin, CaptionMixin, ChapterMixin, SavePositionMixin } from './mixins'; -import style from '../../styles/jw-player/jw-player-css'; +import style from '../../styles/cxl-jw-player/cxl-jw-player-css'; import { mixin } from './utility'; import { template } from './index.html'; -@customElement('jw-player') -export class JWPlayerElement extends mixin(LitElement, [ +@customElement('cxl-jw-player') +export class CXLJWPlayerElement extends mixin(LitElement, [ BaseMixin, CaptionMixin, ChapterMixin, diff --git a/packages/cxl-ui/src/components/jw-player/mixins/BaseMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js similarity index 100% rename from packages/cxl-ui/src/components/jw-player/mixins/BaseMixin.js rename to packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js diff --git a/packages/cxl-ui/src/components/jw-player/mixins/CaptionMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/CaptionMixin.js similarity index 100% rename from packages/cxl-ui/src/components/jw-player/mixins/CaptionMixin.js rename to packages/cxl-ui/src/components/cxl-jw-player/mixins/CaptionMixin.js diff --git a/packages/cxl-ui/src/components/jw-player/mixins/SavePositionMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js similarity index 100% rename from packages/cxl-ui/src/components/jw-player/mixins/SavePositionMixin.js rename to packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js diff --git a/packages/cxl-ui/src/components/jw-player/mixins/chapter/index.html.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter/index.html.js similarity index 100% rename from packages/cxl-ui/src/components/jw-player/mixins/chapter/index.html.js rename to packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter/index.html.js diff --git a/packages/cxl-ui/src/components/jw-player/mixins/chapter/index.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter/index.js similarity index 95% rename from packages/cxl-ui/src/components/jw-player/mixins/chapter/index.js rename to packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter/index.js index aa386cd9e..a4b6e0bf6 100644 --- a/packages/cxl-ui/src/components/jw-player/mixins/chapter/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter/index.js @@ -1,6 +1,6 @@ import { render } from 'lit'; import { property } from 'lit/decorators.js'; -import style from '../../../../styles/jw-player/chapter-css'; +import style from '../../../../styles/cxl-jw-player/chapter-css'; import { chapterNavigationTemplate } from './index.html'; export function ChapterMixin(BaseClass) { diff --git a/packages/cxl-ui/src/components/jw-player/mixins/index.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js similarity index 100% rename from packages/cxl-ui/src/components/jw-player/mixins/index.js rename to packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js diff --git a/packages/cxl-ui/src/components/jw-player/utility.js b/packages/cxl-ui/src/components/cxl-jw-player/utility.js similarity index 100% rename from packages/cxl-ui/src/components/jw-player/utility.js rename to packages/cxl-ui/src/components/cxl-jw-player/utility.js diff --git a/packages/cxl-ui/src/index-jwplayer.js b/packages/cxl-ui/src/index-jwplayer.js index 6106a8c1f..557a5aaa7 100644 --- a/packages/cxl-ui/src/index-jwplayer.js +++ b/packages/cxl-ui/src/index-jwplayer.js @@ -1 +1 @@ -export { JWPlayerElement } from './components/jw-player/index.js'; +export { CXLJWPlayerElement } from './components/cxl-jw-player/index.js'; diff --git a/packages/cxl-ui/src/index-storybook.js b/packages/cxl-ui/src/index-storybook.js index 58042c9c5..5371d6ba3 100644 --- a/packages/cxl-ui/src/index-storybook.js +++ b/packages/cxl-ui/src/index-storybook.js @@ -17,7 +17,7 @@ export { CXLSaveFavoriteElement } from './components/cxl-save-favorite.js'; export { CXLStarRatingElement } from './components/cxl-star-rating.js'; export { CXLLikeOrDislikeElement } from './components/cxl-like-or-dislike.js'; export { CXLPaywallElement } from './components/cxl-paywall.js'; -export { JWPlayerElement } from './components/jw-player/index.js'; +export { CXLJWPlayerElement } from './components/cxl-jw-player/index.js'; // @todo maybe https://github.com/tc39/proposal-export-default-from export { Headroom }; diff --git a/packages/cxl-ui/src/styles/jw-player/.gitignore b/packages/cxl-ui/src/styles/jw-player/.gitignore deleted file mode 100644 index f935021a8..000000000 --- a/packages/cxl-ui/src/styles/jw-player/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/packages/storybook/cxl-ui/jw-player/index.stories.js b/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js similarity index 81% rename from packages/storybook/cxl-ui/jw-player/index.stories.js rename to packages/storybook/cxl-ui/cxl-jw-player/index.stories.js index 17bf14379..9a14d5fc4 100644 --- a/packages/storybook/cxl-ui/jw-player/index.stories.js +++ b/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js @@ -1,8 +1,8 @@ import { html } from 'lit'; -import '@conversionxl/cxl-ui/src/components/jw-player/index.js'; +import '@conversionxl/cxl-ui/src/components/cxl-jw-player/index.js'; export default { - title: 'JW Player/JW Player', + title: 'CXL UI/cxl-jw-player', }; const Template = ({ captions, mediaId, minimumSearchLength, playerId, playlistId, pluginPath }) => @@ -12,23 +12,23 @@ const Template = ({ captions, mediaId, minimumSearchLength, playerId, playlistId height: 100vh; } - jw-player { + cxl-jw-player { display: block; height: 100%; } - jw-player * { + cxl-jw-player * { box-sizing: border-box; } - + > `; export const Default = Template.bind({}); diff --git a/packages/storybook/cxl-ui/jw-player/playlist.stories.js b/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js similarity index 80% rename from packages/storybook/cxl-ui/jw-player/playlist.stories.js rename to packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js index 752c77387..e6ef72773 100644 --- a/packages/storybook/cxl-ui/jw-player/playlist.stories.js +++ b/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js @@ -1,8 +1,8 @@ import { html } from 'lit'; -import '@conversionxl/cxl-ui/src/components/jw-player/index.js'; +import '@conversionxl/cxl-ui/src/components/cxl-jw-player/index.js'; export default { - title: 'JW Player/JW Player', + title: 'CXL UI/cxl-jw-player', }; const Template = ({ captions, mediaId, playerId, playlistId, pluginPath }) => @@ -12,16 +12,16 @@ const Template = ({ captions, mediaId, playerId, playlistId, pluginPath }) => height: 100vh; } - jw-player { + cxl-jw-player { display: block; height: 100%; } - jw-player * { + cxl-jw-player * { box-sizing: border-box; } - playlist-id=${playlistId} plugin-path="${pluginPath}" type="playlist" - > + > `; export const Playlist = Template.bind({}); From 6bd1eb3872cff183eac25bc2db00dcba6905d14d Mon Sep 17 00:00:00 2001 From: saasfreelancer Date: Thu, 1 Dec 2022 17:13:27 +0500 Subject: [PATCH 02/36] feat(cxl-ui): tweak jw player component Co-authored-by: Andrew Noblet --- .../cxl-jw-player/cxl-jw-player-shadow.scss | 107 +++++++++++++++++ .../scss/cxl-jw-player/cxl-jw-player.scss | 109 +----------------- .../src/components/cxl-jw-player/index.js | 9 +- .../cxl-jw-player/mixins/BaseMixin.js | 7 ++ .../cxl-ui/cxl-jw-player/index.stories.js | 2 +- .../cxl-ui/cxl-jw-player/playlist.stories.js | 2 +- 6 files changed, 129 insertions(+), 107 deletions(-) create mode 100644 packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss new file mode 100644 index 000000000..5868a2c64 --- /dev/null +++ b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss @@ -0,0 +1,107 @@ +@use "~@conversionxl/cxl-lumo-styles/scss/mixins"; + +:host { + box-sizing: border-box; + + [active] { + background-color: var(--lumo-shade-10pct); + } +} + +:host([captions]) #container { + grid-template-rows: 1fr max-content 1fr; +} + +.captions { + h2, + span { + &:hover { + color: var(--lumo-primary-color); + } + + cursor: var(--captions-cursor, pointer); + } + + mark { + color: #fff; + background-color: var(--lumo-primary-color); + } + + span { + padding: var(--lumo-space-xs) calc(var(--lumo-space-xs) / 2); + border-radius: var(--lumo-space-xs); + } +} + +.center { + display: flex; + align-items: center; + justify-content: center; +} + +.flex { + display: flex; + height: 100%; +} + +.flex.column { + flex-direction: column; +} + +.flex.grow { + flex-grow: 1; +} + +.gap { + gap: var(--lumo-space-m); +} + +.grid { + display: grid; +} + +.height-50 { + height: 50%; +} + +.height-100 { + height: 100%; +} + +.overflow-hidden { + overflow: hidden; +} + +.padding { + padding: var(--lumo-space-s); +} + +.scroll { + @include mixins.better-webkit-scrollbars(); + + overflow: auto; +} + +.search { + color: #fff; + background-color: #000; + + vaadin-checkbox { + --lumo-body-text-color: #fff; + } + + vaadin-checkbox:not([checked])::part(checkbox) { + background-color: #fff; + } + + vaadin-text-field { + width: 50%; + padding: 0; + background-color: #fff; + border-radius: var(--lumo-space-xs); + + &::part(input-field) { + background-color: initial; + } + } +} diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player.scss b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player.scss index 5868a2c64..3a387c1c1 100644 --- a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player.scss +++ b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player.scss @@ -1,107 +1,8 @@ -@use "~@conversionxl/cxl-lumo-styles/scss/mixins"; +.jw-player-button { + width: 32px; + fill: rgba(255, 255, 255, 0.8); -:host { - box-sizing: border-box; - - [active] { - background-color: var(--lumo-shade-10pct); - } -} - -:host([captions]) #container { - grid-template-rows: 1fr max-content 1fr; -} - -.captions { - h2, - span { - &:hover { - color: var(--lumo-primary-color); - } - - cursor: var(--captions-cursor, pointer); - } - - mark { - color: #fff; - background-color: var(--lumo-primary-color); - } - - span { - padding: var(--lumo-space-xs) calc(var(--lumo-space-xs) / 2); - border-radius: var(--lumo-space-xs); - } -} - -.center { - display: flex; - align-items: center; - justify-content: center; -} - -.flex { - display: flex; - height: 100%; -} - -.flex.column { - flex-direction: column; -} - -.flex.grow { - flex-grow: 1; -} - -.gap { - gap: var(--lumo-space-m); -} - -.grid { - display: grid; -} - -.height-50 { - height: 50%; -} - -.height-100 { - height: 100%; -} - -.overflow-hidden { - overflow: hidden; -} - -.padding { - padding: var(--lumo-space-s); -} - -.scroll { - @include mixins.better-webkit-scrollbars(); - - overflow: auto; -} - -.search { - color: #fff; - background-color: #000; - - vaadin-checkbox { - --lumo-body-text-color: #fff; - } - - vaadin-checkbox:not([checked])::part(checkbox) { - background-color: #fff; - } - - vaadin-text-field { - width: 50%; - padding: 0; - background-color: #fff; - border-radius: var(--lumo-space-xs); - - &::part(input-field) { - background-color: initial; - } + &:hover { + fill: rgba(255, 255, 255, 1); } } diff --git a/packages/cxl-ui/src/components/cxl-jw-player/index.js b/packages/cxl-ui/src/components/cxl-jw-player/index.js index 8572ffc89..f6d26fd32 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/index.js @@ -2,6 +2,7 @@ import { LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; import { BaseMixin, CaptionMixin, ChapterMixin, SavePositionMixin } from './mixins'; import style from '../../styles/cxl-jw-player/cxl-jw-player-css'; +import shadowStyle from '../../styles/cxl-jw-player/cxl-jw-player-shadow-css'; import { mixin } from './utility'; import { template } from './index.html'; @@ -25,10 +26,16 @@ export class CXLJWPlayerElement extends mixin(LitElement, [ }; static get styles() { - return [style]; + return [shadowStyle]; } render() { return template.bind(this)(); } + + async __setup() { + await super.__setup(); + + this.__addStyle(style); + } } diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js index 5f49c5e83..986147623 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js @@ -1,3 +1,4 @@ +import { render } from 'lit'; import { property } from 'lit/decorators.js'; import { throttle } from 'lodash-es'; import { parseSync } from 'subtitle'; @@ -37,6 +38,12 @@ export function BaseMixin(BaseClass) { return `https://content.jwplatform.com/libraries/${this.playerId}.js`; } + __addStyle(style) { + const el = document.createElement('style'); + render(style, el); + this.appendChild(el); + } + async __getChapters() { const playlistItem = this.__jwPlayer.getPlaylistItem(); const { file } = playlistItem.tracks.filter((track) => track.kind === 'chapters')[0]; diff --git a/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js b/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js index 9a14d5fc4..a87cd4ad1 100644 --- a/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js +++ b/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js @@ -35,7 +35,7 @@ export const Default = Template.bind({}); Object.assign(Default, { args: { - captions: true, + captions: false, mediaId: 'fZ0XiGdb', minimumSearchLength: 3, playerId: '5CFJNXKb', diff --git a/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js b/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js index e6ef72773..3a55354aa 100644 --- a/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js +++ b/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js @@ -36,7 +36,7 @@ export const Playlist = Template.bind({}); Object.assign(Playlist, { args: { - captions: true, + captions: false, mediaId: '', playerId: '5CFJNXKb', playlistId: 'tAxwbNsA', From 4ff8d2244d0f2e7bcda625f9a9ebdd98f8baac78 Mon Sep 17 00:00:00 2001 From: saasfreelancer Date: Thu, 1 Dec 2022 16:30:25 +0500 Subject: [PATCH 03/36] feat(cxl-ui): rename caption mixin to transcript mixin Co-authored-by: Andrew Noblet --- packages/cxl-ui/src/components/cxl-jw-player/index.js | 4 ++-- .../mixins/{CaptionMixin.js => TranscriptMixin.js} | 2 +- packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename packages/cxl-ui/src/components/cxl-jw-player/mixins/{CaptionMixin.js => TranscriptMixin.js} (98%) diff --git a/packages/cxl-ui/src/components/cxl-jw-player/index.js b/packages/cxl-ui/src/components/cxl-jw-player/index.js index f6d26fd32..617b377cc 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/index.js @@ -1,6 +1,6 @@ import { LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; -import { BaseMixin, CaptionMixin, ChapterMixin, SavePositionMixin } from './mixins'; +import { BaseMixin, TranscriptMixin, ChapterMixin, SavePositionMixin } from './mixins'; import style from '../../styles/cxl-jw-player/cxl-jw-player-css'; import shadowStyle from '../../styles/cxl-jw-player/cxl-jw-player-shadow-css'; import { mixin } from './utility'; @@ -9,7 +9,7 @@ import { template } from './index.html'; @customElement('cxl-jw-player') export class CXLJWPlayerElement extends mixin(LitElement, [ BaseMixin, - CaptionMixin, + TranscriptMixin, ChapterMixin, SavePositionMixin, ]) { diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/CaptionMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js similarity index 98% rename from packages/cxl-ui/src/components/cxl-jw-player/mixins/CaptionMixin.js rename to packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js index fbeb3f765..4df8e35a7 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/CaptionMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js @@ -3,7 +3,7 @@ import { debounce } from 'lodash-es'; import Mark from 'mark.js'; import { parseSync } from 'subtitle'; -export function CaptionMixin(BaseClass) { +export function TranscriptMixin(BaseClass) { class Mixin extends BaseClass { __debouncedSearch; diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js index ca56fdb7c..7d909dfc5 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js @@ -1,4 +1,4 @@ export { BaseMixin } from './BaseMixin'; -export { CaptionMixin } from './CaptionMixin'; +export { TranscriptMixin } from './TranscriptMixin'; export { ChapterMixin } from './chapter'; export { SavePositionMixin } from './SavePositionMixin'; From 6b74e4375f7ca7ab1720b5906a90fd1038303e3f Mon Sep 17 00:00:00 2001 From: saasfreelancer Date: Thu, 1 Dec 2022 17:10:39 +0500 Subject: [PATCH 04/36] feat(cxl-ui): tweak transcript mixin Co-authored-by: Andrew Noblet --- .../cxl-jw-player/mixins/TranscriptMixin.js | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js index 4df8e35a7..9ee8d35f2 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js @@ -9,7 +9,7 @@ export function TranscriptMixin(BaseClass) { __mark; - @property({ type: Boolean }) captions = false; + @property({ reflect: true, type: Boolean }) captions = false; @state() __currentCue = 0; @@ -117,12 +117,19 @@ export function TranscriptMixin(BaseClass) { async __setup() { await super.__setup(); - this.__setupCaptions(); + this.__setupTranscript(); } - async __setupCaptions() { + async __setupTranscript() { if (!this.__jwPlayer) return; + this.__jwPlayer.addButton( + ``, + 'Transcript', + this.__toggleTranscript.bind(this), + 'toggle-transcript' + ); + if (this.captions) { this.__tracks = await this.__getTracks(); @@ -138,16 +145,26 @@ export function TranscriptMixin(BaseClass) { if (changedProperties.has('captions')) { if (this.captions) { - this.__setupCaptions(); + this.__setupTranscript(); } else if (this.mark) { this.__mark.unmark(); } } } + __attachListeners() { + super.__attachListeners(); + } + __toggleShouldScroll() { this.shouldScroll = !this.shouldScroll; } + + __toggleTranscript() { + // this.dispatchEvent(new CustomEvent('toggle-transcript')); + + this.captions = !this.captions; + } } return Mixin; From 7391356d21db8bb7c8fb28a02265d5954ce69b07 Mon Sep 17 00:00:00 2001 From: saasfreelancer Date: Thu, 1 Dec 2022 17:17:48 +0500 Subject: [PATCH 05/36] feat(cxl-ui): rename chapter mixin to chapter navigation mixin Co-authored-by: Andrew Noblet --- .../{chapter.scss => cxl-jw-player-chapter-navigation.scss} | 0 packages/cxl-ui/src/components/cxl-jw-player/index.js | 4 ++-- .../mixins/{chapter => chapter-navigation}/index.html.js | 0 .../mixins/{chapter => chapter-navigation}/index.js | 4 ++-- packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename packages/cxl-ui/scss/cxl-jw-player/{chapter.scss => cxl-jw-player-chapter-navigation.scss} (100%) rename packages/cxl-ui/src/components/cxl-jw-player/mixins/{chapter => chapter-navigation}/index.html.js (100%) rename packages/cxl-ui/src/components/cxl-jw-player/mixins/{chapter => chapter-navigation}/index.js (90%) diff --git a/packages/cxl-ui/scss/cxl-jw-player/chapter.scss b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-chapter-navigation.scss similarity index 100% rename from packages/cxl-ui/scss/cxl-jw-player/chapter.scss rename to packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-chapter-navigation.scss diff --git a/packages/cxl-ui/src/components/cxl-jw-player/index.js b/packages/cxl-ui/src/components/cxl-jw-player/index.js index 617b377cc..9d245c651 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/index.js @@ -1,6 +1,6 @@ import { LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; -import { BaseMixin, TranscriptMixin, ChapterMixin, SavePositionMixin } from './mixins'; +import { BaseMixin, TranscriptMixin, ChapterNavigationMixin, SavePositionMixin } from './mixins'; import style from '../../styles/cxl-jw-player/cxl-jw-player-css'; import shadowStyle from '../../styles/cxl-jw-player/cxl-jw-player-shadow-css'; import { mixin } from './utility'; @@ -10,7 +10,7 @@ import { template } from './index.html'; export class CXLJWPlayerElement extends mixin(LitElement, [ BaseMixin, TranscriptMixin, - ChapterMixin, + ChapterNavigationMixin, SavePositionMixin, ]) { config = { diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter/index.html.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.html.js similarity index 100% rename from packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter/index.html.js rename to packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.html.js diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter/index.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js similarity index 90% rename from packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter/index.js rename to packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js index a4b6e0bf6..051c4dca9 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js @@ -1,9 +1,9 @@ import { render } from 'lit'; import { property } from 'lit/decorators.js'; -import style from '../../../../styles/cxl-jw-player/chapter-css'; +import style from '../../../../styles/cxl-jw-player/cxl-jw-player-chapter-navigation-css'; import { chapterNavigationTemplate } from './index.html'; -export function ChapterMixin(BaseClass) { +export function ChapterNavigationMixin(BaseClass) { class Mixin extends BaseClass { @property({ attribute: 'plugin-path', type: String }) pluginPath; diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js index 7d909dfc5..280a40e71 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js @@ -1,4 +1,4 @@ export { BaseMixin } from './BaseMixin'; export { TranscriptMixin } from './TranscriptMixin'; -export { ChapterMixin } from './chapter'; +export { ChapterNavigationMixin } from './chapter-navigation'; export { SavePositionMixin } from './SavePositionMixin'; From 67aba0d9ecc997ecf42ff01f3aa85e3f96df4e78 Mon Sep 17 00:00:00 2001 From: saasfreelancer Date: Thu, 1 Dec 2022 18:29:35 +0500 Subject: [PATCH 06/36] feat(cxl-ui): tweak chapter navigation mixin Co-authored-by: Andrew Noblet --- .../mixins/chapter-navigation/index.html.js | 3 +-- .../mixins/chapter-navigation/index.js | 14 ++++---------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.html.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.html.js index 88b64537d..6c1cb1f4d 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.html.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.html.js @@ -13,8 +13,7 @@ export const chapterNavigationTemplate = function (chapters) { theme="icon small primary" aria-label="Close" > - - ✕ +
    diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js index 051c4dca9..2ab998723 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js @@ -7,7 +7,7 @@ export function ChapterNavigationMixin(BaseClass) { class Mixin extends BaseClass { @property({ attribute: 'plugin-path', type: String }) pluginPath; - async __createChapterNavigation() { + async __setupChapterNavigation() { const chapters = await this.__getChapters(); this.__chapterNavigation = document.createElement('div'); @@ -19,19 +19,13 @@ export function ChapterNavigationMixin(BaseClass) { this.__jwPlayerContainer.appendChild(this.__chapterNavigation); this.__jwPlayer.addButton( - `${this.pluginPath}images/chapter-bookmark-icon.svg`, + ``, 'Show Chapters', this.__toggleChapterNavigation.bind(this), 'toggle-chapters' ); } - __addStyle() { - const el = document.createElement('style'); - render(style, el); - this.appendChild(el); - } - __chapterSeek(e) { const index = Number(e.currentTarget.dataset.index); this.__jwPlayer.seek(this.__chapters[index].data.start / 1000); @@ -40,8 +34,8 @@ export function ChapterNavigationMixin(BaseClass) { async __setup() { await super.__setup(); - this.__addStyle(); - this.__createChapterNavigation(); + this.__addStyle(style); + this.__setupChapterNavigation(); } __toggleChapterNavigation() { From d6433d61f735eed81dba3d0a62b545eec1f0093e Mon Sep 17 00:00:00 2001 From: saasfreelancer Date: Thu, 1 Dec 2022 18:07:51 +0500 Subject: [PATCH 07/36] feat(cxl-ui): add cxl-jw-player-transcript element Co-authored-by: Andrew Noblet --- .../cxl-jw-player-transcript-shadow.scss | 3 +++ .../cxl-jw-player-transcript.scss | 3 +++ .../cxl-jw-player-transcript/index.js | 21 +++++++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-transcript-shadow.scss create mode 100644 packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-transcript.scss create mode 100644 packages/cxl-ui/src/components/cxl-jw-player/cxl-jw-player-transcript/index.js diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-transcript-shadow.scss b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-transcript-shadow.scss new file mode 100644 index 000000000..769714c22 --- /dev/null +++ b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-transcript-shadow.scss @@ -0,0 +1,3 @@ +:host(:not([hidden])) { + display: block; +} diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-transcript.scss b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-transcript.scss new file mode 100644 index 000000000..769714c22 --- /dev/null +++ b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-transcript.scss @@ -0,0 +1,3 @@ +:host(:not([hidden])) { + display: block; +} diff --git a/packages/cxl-ui/src/components/cxl-jw-player/cxl-jw-player-transcript/index.js b/packages/cxl-ui/src/components/cxl-jw-player/cxl-jw-player-transcript/index.js new file mode 100644 index 000000000..5bbd17f44 --- /dev/null +++ b/packages/cxl-ui/src/components/cxl-jw-player/cxl-jw-player-transcript/index.js @@ -0,0 +1,21 @@ +import { html, LitElement } from 'lit'; +import { customElement } from 'lit/decorators.js'; +import style from '../../../styles/cxl-jw-player/cxl-jw-player-transcript-css'; +import shadowStyle from '../../../styles/cxl-jw-player/cxl-jw-player-transcript-shadow-css'; + +@customElement('cxl-jw-player-transcript') +export class CXLJWPlayerTranscriptElement extends LitElement { + static get styles() { + return [shadowStyle]; + } + + render() { + return html``; + } + + async __setup() { + await super.__setup(); + + this.__addStyle(style); + } +} From 5698fd18bb7f6c272b4f4ddc270ac054373899d6 Mon Sep 17 00:00:00 2001 From: saasfreelancer Date: Thu, 1 Dec 2022 19:06:23 +0500 Subject: [PATCH 08/36] feat: cleanup, refactor & improve the code for PHP `cxl/jw-player` * jw-player height tweaks * [jw-player] add support for sources cherry-pick: #236 * [cxl-jw-player] set up api endpoint cherry-pick: #234 --- .../cxl-jw-player/cxl-jw-player-shadow.scss | 4 -- .../src/components/cxl-jw-player/README.md | 3 +- .../components/cxl-jw-player/index.html.js | 2 +- .../src/components/cxl-jw-player/index.js | 2 +- .../cxl-jw-player/mixins/BaseMixin.js | 66 +++++++++++++++---- .../cxl-jw-player/mixins/SavePositionMixin.js | 8 ++- .../cxl-ui/cxl-jw-player/index.stories.js | 13 +++- 7 files changed, 73 insertions(+), 25 deletions(-) diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss index 5868a2c64..54f4f6c4e 100644 --- a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss +++ b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss @@ -8,10 +8,6 @@ } } -:host([captions]) #container { - grid-template-rows: 1fr max-content 1fr; -} - .captions { h2, span { diff --git a/packages/cxl-ui/src/components/cxl-jw-player/README.md b/packages/cxl-ui/src/components/cxl-jw-player/README.md index 33202d041..96d3b7815 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/README.md +++ b/packages/cxl-ui/src/components/cxl-jw-player/README.md @@ -4,10 +4,11 @@ ``` ``` diff --git a/packages/cxl-ui/src/components/cxl-jw-player/index.html.js b/packages/cxl-ui/src/components/cxl-jw-player/index.html.js index fd37a2de1..0199e1eb3 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/index.html.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/index.html.js @@ -5,7 +5,7 @@ import '@vaadin/text-field'; // eslint-disable-next-line func-names export const template = function () { return html` -
    +
    ${this.captions ? html` diff --git a/packages/cxl-ui/src/components/cxl-jw-player/index.js b/packages/cxl-ui/src/components/cxl-jw-player/index.js index 9d245c651..fd42ca9d0 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/index.js @@ -15,7 +15,6 @@ export class CXLJWPlayerElement extends mixin(LitElement, [ ]) { config = { width: '100%', - height: '100%', playbackRateControls: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2], plugins: { // 'http://192.168.0.101:8080/telemetry-8.20.0.js': {}, @@ -23,6 +22,7 @@ export class CXLJWPlayerElement extends mixin(LitElement, [ skin: { name: 'cxl-institute', }, + stretching: 'uniform', }; static get styles() { diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js index 986147623..531233f97 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js @@ -17,10 +17,18 @@ export function BaseMixin(BaseClass) { @property({ attribute: 'media-id', type: String }) mediaId; - @property({ attribute: 'player-id', type: String }) playerId; + @property({ attribute: 'media-source', type: String }) mediaSource; + + @property({ attribute: 'is-public', type: String }) isPublic; + + @property({ attribute: 'library-id', type: String }) libraryId; + + @property({ attribute: 'library-source', type: String }) librarySource; @property({ attribute: 'playlist-id', type: String }) playlistId; + @property({ attribute: 'playlist-source', type: String }) playlistSource; + firstUpdated(_changedProperties) { super.firstUpdated(_changedProperties); @@ -35,7 +43,17 @@ export function BaseMixin(BaseClass) { } get __scriptUrl() { - return `https://content.jwplatform.com/libraries/${this.playerId}.js`; + let scriptUrl; + + if (this.libraryId && this.isPublic) { + scriptUrl = `https://content.jwplatform.com/libraries/${this.libraryId}.js`; + } else if (this.librarySource) { + scriptUrl = this.librarySource; + } else { + return false; + } + + return scriptUrl; } __addStyle(style) { @@ -43,31 +61,42 @@ export function BaseMixin(BaseClass) { render(style, el); this.appendChild(el); } - + async __getChapters() { const playlistItem = this.__jwPlayer.getPlaylistItem(); - const { file } = playlistItem.tracks.filter((track) => track.kind === 'chapters')[0]; + const chapters = playlistItem.tracks.filter((track) => track.kind === 'chapters'); + const { file } = chapters.length > 0 ? chapters[0] : ''; const response = await (await fetch(file)).text(); return parseSync(response); } async __getMedia() { - if (!this.mediaId) return false; - - const response = await fetch(`https://cdn.jwplayer.com/v2/media/${this.mediaId}`); - const result = await response.json(); + let response; + + if (this.mediaId && this.isPublic) { + response = await fetch(`https://cdn.jwplayer.com/v2/media/${this.mediaId}`); + } else if (this.mediaSource) { + response = await fetch(this.mediaSource); + } else { + return false; + } - return result; + return response.json(); } async __getPlaylist() { - if (!this.playlistId) return false; - - const response = await fetch(`https://cdn.jwplayer.com/v2/playlists/${this.playlistId}`); - const result = await response.json(); + let response; + + if (this.playlistId) { + response = await fetch(`https://cdn.jwplayer.com/v2/playlists/${this.playlistId}`); + } else if (this.playlistSource) { + response = await fetch(`https://cdn.jwplayer.com/v2/playlists/${this.playlistId}`); + } else { + return false; + } - return result; + return response.json(); } async __loadScript() { @@ -97,6 +126,15 @@ export function BaseMixin(BaseClass) { * Each mixin has the ability to hook onto this method. */ async __setup() { + + // Merge configs from `cxlJWPlayerData`. + if (typeof window.cxlJWPlayerData !== 'undefined') { + // eslint-disable-next-line camelcase + const { media_config } = window.cxlJWPlayerData[this.mediaId]; + // eslint-disable-next-line camelcase + this.config = { ...this.config, ...media_config }; + } + const jwPlayer = await this.__loadScript(); const el = document.createElement('div'); diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js index 6ae10b0b6..9ea091ba6 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js @@ -1,6 +1,6 @@ export function SavePositionMixin(BaseClass) { class Mixin extends BaseClass { - __endpoint = ''; + __endpoint; __nonce; @@ -9,6 +9,12 @@ export function SavePositionMixin(BaseClass) { async __setup() { await super.__setup(); + this.__endpoint = `${window.ajaxurl}?action=jwplayer_save_position`; + + if ( typeof window.cxl_pum_vars !== 'undefined' ) { + this.__nonce = window.cxl_pum_vars.nonce; + } + this.__loadPosition(); } diff --git a/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js b/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js index a87cd4ad1..c9adc7c12 100644 --- a/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js +++ b/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js @@ -5,7 +5,7 @@ export default { title: 'CXL UI/cxl-jw-player', }; -const Template = ({ captions, mediaId, minimumSearchLength, playerId, playlistId, pluginPath }) => +const Template = ({ captions, mediaId, mediaSource, minimumSearchLength, libraryId, librarySource, playlistId, playlistSource, pluginPath }) => html` `; @@ -35,11 +39,14 @@ export const Default = Template.bind({}); Object.assign(Default, { args: { - captions: false, + captions: true, mediaId: 'fZ0XiGdb', + mediaSource: '', minimumSearchLength: 3, playerId: '5CFJNXKb', + playerSource: '', playlistId: '', + playlistSource: '', pluginPath: 'https://cxl.com/institute/wp-content/plugins/cxl-jwplayer/', }, }); From f296fbd2a84a67f12b24aebdad119bf6ac7769d9 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Mon, 20 Feb 2023 12:16:42 -0500 Subject: [PATCH 09/36] feat(cxl-ui): [cxl-jw-player] add styles directory --- packages/cxl-ui/src/styles/cxl-jw-player/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 packages/cxl-ui/src/styles/cxl-jw-player/.gitignore diff --git a/packages/cxl-ui/src/styles/cxl-jw-player/.gitignore b/packages/cxl-ui/src/styles/cxl-jw-player/.gitignore new file mode 100644 index 000000000..f935021a8 --- /dev/null +++ b/packages/cxl-ui/src/styles/cxl-jw-player/.gitignore @@ -0,0 +1 @@ +!.gitignore From ec4b4c6db2ea391f229835c11faeb291e0476662 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Mon, 20 Feb 2023 12:24:24 -0500 Subject: [PATCH 10/36] feat(cxl-ui): [cxl-jw-player] rename playerId, playerSource to libraryId, librarySource --- .../cxl-ui/cxl-jw-player/index.stories.js | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js b/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js index c9adc7c12..3d444231a 100644 --- a/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js +++ b/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js @@ -5,7 +5,17 @@ export default { title: 'CXL UI/cxl-jw-player', }; -const Template = ({ captions, mediaId, mediaSource, minimumSearchLength, libraryId, librarySource, playlistId, playlistSource, pluginPath }) => +const Template = ({ + captions, + mediaId, + mediaSource, + minimumSearchLength, + libraryId, + librarySource, + playlistId, + playlistSource, + pluginPath, +}) => html` + Date: Mon, 20 Feb 2023 12:54:01 -0500 Subject: [PATCH 11/36] feat(cxl-ui): [cxl-jw-player] add hidden property style --- .../scss/cxl-jw-player/cxl-jw-player-chapter-navigation.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-chapter-navigation.scss b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-chapter-navigation.scss index 471389014..1590821a5 100644 --- a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-chapter-navigation.scss +++ b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-chapter-navigation.scss @@ -14,6 +14,10 @@ background: var(--lumo-shade); gap: var(--lumo-space-s); + &[hidden] { + display: none; + } + .close { font-size: var(--lumo-font-size-xs); cursor: pointer; From 0468d8b7fac926387251a8d54206930cb9897900 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Mon, 20 Feb 2023 12:57:19 -0500 Subject: [PATCH 12/36] feat(cxl-ui): [cxl-jw-player] set container display and height --- packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss index 54f4f6c4e..3b4196d61 100644 --- a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss +++ b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss @@ -35,6 +35,11 @@ justify-content: center; } +.cxl-jw-player-container { + display: grid; + height: 100%; +} + .flex { display: flex; height: 100%; From e6fdf450a31a00513658e5c00896786008fe7dea Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Tue, 21 Feb 2023 09:44:00 -0500 Subject: [PATCH 13/36] feat(cxl-ui): [cxl-jw-player] fix playlist story --- .../cxl-ui/cxl-jw-player/playlist.stories.js | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js b/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js index 3a55354aa..c58988d76 100644 --- a/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js +++ b/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js @@ -5,7 +5,17 @@ export default { title: 'CXL UI/cxl-jw-player', }; -const Template = ({ captions, mediaId, playerId, playlistId, pluginPath }) => +const Template = ({ + captions, + mediaId, + mediaSource, + minimumSearchLength, + libraryId, + librarySource, + playlistId, + playlistSource, + pluginPath, +}) => html` + `; @@ -36,10 +50,14 @@ export const Playlist = Template.bind({}); Object.assign(Playlist, { args: { - captions: false, + captions: true, + libraryId: '5CFJNXKb', + librarySource: '', mediaId: '', - playerId: '5CFJNXKb', + mediaSource: '', + minimumSearchLength: 3, playlistId: 'tAxwbNsA', + playlistSource: '', pluginPath: 'https://cxl.com/institute/wp-content/plugins/cxl-jwplayer/', }, }); From 9bfba1ed3170cf2512a54464cb1fe8789e1da69b Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Tue, 21 Feb 2023 11:00:03 -0500 Subject: [PATCH 14/36] feat(cxl-ui): [cxl-jw-player] fix playlist styles --- .../scss/cxl-jw-player/cxl-jw-player.scss | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player.scss b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player.scss index 3a387c1c1..29e15a17d 100644 --- a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player.scss +++ b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player.scss @@ -1,8 +1,25 @@ -.jw-player-button { - width: 32px; - fill: rgba(255, 255, 255, 0.8); +cxl-jw-player { + .jw-player-button { + width: 32px; + fill: rgba(255, 255, 255, 0.8); - &:hover { - fill: rgba(255, 255, 255, 1); + &:hover { + fill: rgba(255, 255, 255, 1); + } + } + + .jw-related-item { + height: 100% !important; /* stylelint-disable-line declaration-no-important */ + } + + .jwplayer:not(.jw-flag-small-player) .jw-related-item-next-up { + .jw-related-item-poster { + height: 100%; + } + + .jw-related-item-title { + position: absolute; + bottom: 0; + } } } From 45c8607dd7cee5ffbd82a3cc10c42bc612203fef Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Thu, 23 Feb 2023 14:24:25 -0500 Subject: [PATCH 15/36] feat(cxl-ui): [cxl-jw-player] add next up CTA --- .../cxl-jw-player/cxl-jw-player-next-up.scss | 3 ++ .../src/components/cxl-jw-player/index.js | 11 ++++- .../cxl-jw-player/mixins/NextUpMixin.js | 42 +++++++++++++++++++ .../components/cxl-jw-player/mixins/index.js | 5 ++- 4 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-next-up.scss create mode 100644 packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-next-up.scss b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-next-up.scss new file mode 100644 index 000000000..6921bd6d4 --- /dev/null +++ b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-next-up.scss @@ -0,0 +1,3 @@ +.jw-next-up-cta { + pointer-events: all; +} diff --git a/packages/cxl-ui/src/components/cxl-jw-player/index.js b/packages/cxl-ui/src/components/cxl-jw-player/index.js index fd42ca9d0..dea8aa8a6 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/index.js @@ -1,16 +1,23 @@ import { LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; -import { BaseMixin, TranscriptMixin, ChapterNavigationMixin, SavePositionMixin } from './mixins'; import style from '../../styles/cxl-jw-player/cxl-jw-player-css'; import shadowStyle from '../../styles/cxl-jw-player/cxl-jw-player-shadow-css'; -import { mixin } from './utility'; import { template } from './index.html'; +import { + BaseMixin, + ChapterNavigationMixin, + NextUpMixin, + SavePositionMixin, + TranscriptMixin, +} from './mixins'; +import { mixin } from './utility'; @customElement('cxl-jw-player') export class CXLJWPlayerElement extends mixin(LitElement, [ BaseMixin, TranscriptMixin, ChapterNavigationMixin, + NextUpMixin, SavePositionMixin, ]) { config = { diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js new file mode 100644 index 000000000..f084e46b4 --- /dev/null +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js @@ -0,0 +1,42 @@ +import { html, render } from 'lit'; +import style from '../../../styles/cxl-jw-player/cxl-jw-player-next-up-css'; +export function NextUpMixin(BaseClass) { + class Mixin extends BaseClass { + __nextUpCTA; + + async __setup() { + await super.__setup(); + + this.__addStyle(style); + + this.__nextUpCTA = document.createElement('div'); + this.__nextUpCTA.classList.add('jw-next-up-cta'); + + const container = this.querySelector('.jw-nextup-container'); + container.insertBefore(this.__nextUpCTA, container.firstChild); + + this.__updateNextUp(); + this.__jwPlayer.on('playlistItem', this.__updateNextUp.bind(this)); + } + + __updateNextUp() { + const index = this.__jwPlayer.getPlaylistIndex(); + const playlistItem = this.__jwPlayer.getPlaylistItem(index + 1); + + if (playlistItem && playlistItem.coursePage) { + render(this.__getTemplate(playlistItem), this.__nextUpCTA); + } + } + + // eslint-disable-next-line class-methods-use-this + __getTemplate(playlistItem) { + return html` + + Go to the course page + + `; + } + } + + return Mixin; +} diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js index 280a40e71..a5ab24213 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js @@ -1,4 +1,5 @@ export { BaseMixin } from './BaseMixin'; -export { TranscriptMixin } from './TranscriptMixin'; -export { ChapterNavigationMixin } from './chapter-navigation'; +export { ChapterNavigationMixin } from './chapter-navigation/index.js'; +export { NextUpMixin } from './NextUpMixin'; export { SavePositionMixin } from './SavePositionMixin'; +export { TranscriptMixin } from './TranscriptMixin'; From ee00b4e50fe1505208d2051928d41f978c51f932 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Fri, 24 Feb 2023 09:04:28 -0500 Subject: [PATCH 16/36] feat(cxl-ui): [cxl-jw-player] hide default next up overlay --- .../scss/cxl-jw-player/cxl-jw-player-next-up.scss | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-next-up.scss b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-next-up.scss index 6921bd6d4..6aca1e473 100644 --- a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-next-up.scss +++ b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-next-up.scss @@ -1,3 +1,9 @@ -.jw-next-up-cta { - pointer-events: all; +cxl-jw-player { + .jw-nextup { + display: none; + } + + .jw-next-up-cta { + pointer-events: all; + } } From 6e8cc9f2d7ebe5a10c8f19c7e818ed9c28c386fd Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Fri, 24 Feb 2023 09:30:03 -0500 Subject: [PATCH 17/36] feat(cxl-ui): [cxl-jw-player] add pointer events to the link not the container --- packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-next-up.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-next-up.scss b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-next-up.scss index 6aca1e473..64848aecb 100644 --- a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-next-up.scss +++ b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-next-up.scss @@ -3,7 +3,7 @@ cxl-jw-player { display: none; } - .jw-next-up-cta { + .jw-next-up-cta > a { pointer-events: all; } } From 766337951eea9f31ba32f352978afd1a7c66c719 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Fri, 24 Feb 2023 09:39:22 -0500 Subject: [PATCH 18/36] feat(cxl-ui): [cxl-jw-player] move next up styles to the global directory --- .../scss/{ => global}/cxl-jw-player/cxl-jw-player-next-up.scss | 0 .../cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js | 2 +- packages/cxl-ui/src/styles/global/cxl-jw-player/.gitignore | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) rename packages/cxl-ui/scss/{ => global}/cxl-jw-player/cxl-jw-player-next-up.scss (100%) create mode 100644 packages/cxl-ui/src/styles/global/cxl-jw-player/.gitignore diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-next-up.scss b/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-next-up.scss similarity index 100% rename from packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-next-up.scss rename to packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-next-up.scss diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js index f084e46b4..7bd08d15c 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js @@ -1,5 +1,5 @@ import { html, render } from 'lit'; -import style from '../../../styles/cxl-jw-player/cxl-jw-player-next-up-css'; +import style from '../../../styles/global/cxl-jw-player/cxl-jw-player-next-up-css'; export function NextUpMixin(BaseClass) { class Mixin extends BaseClass { __nextUpCTA; diff --git a/packages/cxl-ui/src/styles/global/cxl-jw-player/.gitignore b/packages/cxl-ui/src/styles/global/cxl-jw-player/.gitignore new file mode 100644 index 000000000..f935021a8 --- /dev/null +++ b/packages/cxl-ui/src/styles/global/cxl-jw-player/.gitignore @@ -0,0 +1 @@ +!.gitignore From 08634744cddb6ba8460ca54ae9913b8d20ed31c9 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Mon, 27 Feb 2023 12:14:23 -0500 Subject: [PATCH 19/36] feat(cxl-ui): [cxl-jw-player] refactor private methods and properties to protected --- .../src/components/cxl-jw-player/README.md | 8 +- .../cxl-jw-player-transcript/index.js | 6 +- .../components/cxl-jw-player/index.html.js | 18 ++-- .../src/components/cxl-jw-player/index.js | 6 +- .../cxl-jw-player/mixins/BaseMixin.js | 56 ++++++------ .../cxl-jw-player/mixins/NextUpMixin.js | 28 +++--- .../cxl-jw-player/mixins/SavePositionMixin.js | 34 +++---- .../cxl-jw-player/mixins/TranscriptMixin.js | 90 +++++++++---------- .../mixins/chapter-navigation/index.html.js | 4 +- .../mixins/chapter-navigation/index.js | 34 +++---- 10 files changed, 142 insertions(+), 142 deletions(-) diff --git a/packages/cxl-ui/src/components/cxl-jw-player/README.md b/packages/cxl-ui/src/components/cxl-jw-player/README.md index 96d3b7815..0baa00e76 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/README.md +++ b/packages/cxl-ui/src/components/cxl-jw-player/README.md @@ -62,13 +62,13 @@ Order is important as each mixin extends the previous one. In this case, `MixinT There are currently two methods which are important to the lifecycle of the component: -`__setup()` +`_setup()` -This method is async and called when the component is first created. You must call `await super.__setup()` at the beginning of this method to make sure each parent class's setup method is called. +This method is async and called when the component is first created. You must call `await super._setup()` at the beginning of this method to make sure each parent class's setup method is called. -`__onTimeListener()` +`_onTimeListener()` -This method is async and called when the player's time changes. As with `__setup()`, you must call `await super.__onTimeListener()` at the beginning of this method. +This method is async and called when the player's time changes. As with `_setup()`, you must call `await super._onTimeListener()` at the beginning of this method. Current mixins available for use: diff --git a/packages/cxl-ui/src/components/cxl-jw-player/cxl-jw-player-transcript/index.js b/packages/cxl-ui/src/components/cxl-jw-player/cxl-jw-player-transcript/index.js index 5bbd17f44..03e2f19bc 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/cxl-jw-player-transcript/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/cxl-jw-player-transcript/index.js @@ -13,9 +13,9 @@ export class CXLJWPlayerTranscriptElement extends LitElement { return html``; } - async __setup() { - await super.__setup(); + async _setup() { + await super._setup(); - this.__addStyle(style); + this._addStyle(style); } } diff --git a/packages/cxl-ui/src/components/cxl-jw-player/index.html.js b/packages/cxl-ui/src/components/cxl-jw-player/index.html.js index 0199e1eb3..57f840bfa 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/index.html.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/index.html.js @@ -11,7 +11,7 @@ export const template = function () { ? html`
    - ${this.__tracks.map( + ${this._tracks.map( (track, index) => html`${track.isChapter - ? html`

    + ? html`

    ${track.data.text}

    ` : html` ${track.data.text} diff --git a/packages/cxl-ui/src/components/cxl-jw-player/index.js b/packages/cxl-ui/src/components/cxl-jw-player/index.js index dea8aa8a6..4a13e826a 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/index.js @@ -40,9 +40,9 @@ export class CXLJWPlayerElement extends mixin(LitElement, [ return template.bind(this)(); } - async __setup() { - await super.__setup(); + async _setup() { + await super._setup(); - this.__addStyle(style); + this._addStyle(style); } } diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js index 531233f97..0133d616c 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js @@ -5,15 +5,15 @@ import { parseSync } from 'subtitle'; export function BaseMixin(BaseClass) { class Mixin extends BaseClass { - __boundOnTimeListener; + _boundOnTimeListener; - __chapters; + _chapters; - __jwPlayer; + _jwPlayer; - __jwPlayerContainer; + _jwPlayerContainer; - __position; + _position; @property({ attribute: 'media-id', type: String }) mediaId; @@ -32,17 +32,17 @@ export function BaseMixin(BaseClass) { firstUpdated(_changedProperties) { super.firstUpdated(_changedProperties); - this.__setup(); + this._setup(); } updated(_changedProperties) { super.updated(_changedProperties); if (_changedProperties.has('captions') || _changedProperties.has('mediaId')) { - // this.__setup(); + // this._setup(); } } - get __scriptUrl() { + get _scriptUrl() { let scriptUrl; if (this.libraryId && this.isPublic) { @@ -56,14 +56,14 @@ export function BaseMixin(BaseClass) { return scriptUrl; } - __addStyle(style) { + _addStyle(style) { const el = document.createElement('style'); render(style, el); this.appendChild(el); } - async __getChapters() { - const playlistItem = this.__jwPlayer.getPlaylistItem(); + async _getChapters() { + const playlistItem = this._jwPlayer.getPlaylistItem(); const chapters = playlistItem.tracks.filter((track) => track.kind === 'chapters'); const { file } = chapters.length > 0 ? chapters[0] : ''; const response = await (await fetch(file)).text(); @@ -71,7 +71,7 @@ export function BaseMixin(BaseClass) { return parseSync(response); } - async __getMedia() { + async _getMedia() { let response; if (this.mediaId && this.isPublic) { @@ -85,7 +85,7 @@ export function BaseMixin(BaseClass) { return response.json(); } - async __getPlaylist() { + async _getPlaylist() { let response; if (this.playlistId) { @@ -99,10 +99,10 @@ export function BaseMixin(BaseClass) { return response.json(); } - async __loadScript() { + async _loadScript() { return new Promise((resolve) => { const el = document.createElement('script'); - el.src = this.__scriptUrl; + el.src = this._scriptUrl; el.onload = () => { resolve(self.jwplayer); }; @@ -115,17 +115,17 @@ export function BaseMixin(BaseClass) { */ // eslint-disable-next-line class-methods-use-this, no-unused-vars, no-empty-function - async __onTimeListener(event) {} + async _onTimeListener(event) {} - __registerListeners() { - this.__boundOnTimeListener = throttle(this.__onTimeListener.bind(this), 1000); - this.__jwPlayer.on('time', this.__boundOnTimeListener); + _registerListeners() { + this._boundOnTimeListener = throttle(this._onTimeListener.bind(this), 1000); + this._jwPlayer.on('time', this._boundOnTimeListener); } /** * Each mixin has the ability to hook onto this method. */ - async __setup() { + async _setup() { // Merge configs from `cxlJWPlayerData`. if (typeof window.cxlJWPlayerData !== 'undefined') { @@ -135,26 +135,26 @@ export function BaseMixin(BaseClass) { this.config = { ...this.config, ...media_config }; } - const jwPlayer = await this.__loadScript(); + const jwPlayer = await this._loadScript(); const el = document.createElement('div'); this.appendChild(el); - this.__jwPlayer = jwPlayer(el).setup({ + this._jwPlayer = jwPlayer(el).setup({ ...this.config, - ...(await this.__getMedia()), - ...(await this.__getPlaylist()), + ...(await this._getMedia()), + ...(await this._getPlaylist()), }); await new Promise((resolve) => { - this.__jwPlayer.on('ready', resolve); + this._jwPlayer.on('ready', resolve); }); - this.__jwPlayerContainer = this.__jwPlayer.getContainer(); + this._jwPlayerContainer = this._jwPlayer.getContainer(); - this.__registerListeners(); + this._registerListeners(); - this.__chapters = await this.__getChapters(); + this._chapters = await this._getChapters(); } } diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js index 7bd08d15c..e64279ac6 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js @@ -2,34 +2,34 @@ import { html, render } from 'lit'; import style from '../../../styles/global/cxl-jw-player/cxl-jw-player-next-up-css'; export function NextUpMixin(BaseClass) { class Mixin extends BaseClass { - __nextUpCTA; + _nextUpCTA; - async __setup() { - await super.__setup(); + async _setup() { + await super._setup(); - this.__addStyle(style); + this._addStyle(style); - this.__nextUpCTA = document.createElement('div'); - this.__nextUpCTA.classList.add('jw-next-up-cta'); + this._nextUpCTA = document.createElement('div'); + this._nextUpCTA.classList.add('jw-next-up-cta'); const container = this.querySelector('.jw-nextup-container'); - container.insertBefore(this.__nextUpCTA, container.firstChild); + container.insertBefore(this._nextUpCTA, container.firstChild); - this.__updateNextUp(); - this.__jwPlayer.on('playlistItem', this.__updateNextUp.bind(this)); + this._updateNextUp(); + this._jwPlayer.on('playlistItem', this._updateNextUp.bind(this)); } - __updateNextUp() { - const index = this.__jwPlayer.getPlaylistIndex(); - const playlistItem = this.__jwPlayer.getPlaylistItem(index + 1); + _updateNextUp() { + const index = this._jwPlayer.getPlaylistIndex(); + const playlistItem = this._jwPlayer.getPlaylistItem(index + 1); if (playlistItem && playlistItem.coursePage) { - render(this.__getTemplate(playlistItem), this.__nextUpCTA); + render(this._getTemplate(playlistItem), this._nextUpCTA); } } // eslint-disable-next-line class-methods-use-this - __getTemplate(playlistItem) { + _getTemplate(playlistItem) { return html` Go to the course page diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js index 9ea091ba6..8e2a990e4 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js @@ -1,42 +1,42 @@ export function SavePositionMixin(BaseClass) { class Mixin extends BaseClass { - __endpoint; + _endpoint; - __nonce; + _nonce; - __userId; + _userId; - async __setup() { - await super.__setup(); + async _setup() { + await super._setup(); - this.__endpoint = `${window.ajaxurl}?action=jwplayer_save_position`; + this._endpoint = `${window.ajaxurl}?action=jwplayer_save_position`; if ( typeof window.cxl_pum_vars !== 'undefined' ) { - this.__nonce = window.cxl_pum_vars.nonce; + this._nonce = window.cxl_pum_vars.nonce; } - this.__loadPosition(); + this._loadPosition(); } - async __loadPosition() { - this.__jwPlayer.seek(Number(localStorage.getItem(`jw-player-${this.mediaId}-position`))); - this.__jwPlayer.pause(); + async _loadPosition() { + this._jwPlayer.seek(Number(localStorage.getItem(`jw-player-${this.mediaId}-position`))); + this._jwPlayer.pause(); } /** * The listener is registered in the base class (../index.js). */ - __onTimeListener(event) { - super.__onTimeListener(event); + _onTimeListener(event) { + super._onTimeListener(event); - this.__savePosition(event); + this._savePosition(event); } - __savePosition({ position }) { + _savePosition({ position }) { localStorage.setItem(`jw-player-${this.mediaId}-position`, position); - fetch(this.__endpoint, { - _ajax_nonce: this.__nonce, + fetch(this._endpoint, { + _ajax_nonce: this._nonce, body: JSON.stringify({ mediaId: this.mediaId, position }), headers: { 'Content-Type': 'application/json', diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js index 9ee8d35f2..d1764bec8 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js @@ -5,38 +5,38 @@ import { parseSync } from 'subtitle'; export function TranscriptMixin(BaseClass) { class Mixin extends BaseClass { - __debouncedSearch; + _debouncedSearch; - __mark; + _mark; @property({ reflect: true, type: Boolean }) captions = false; - @state() __currentCue = 0; + @state() _currentCue = 0; - @state() __currentTrack = 0; + @state() _currentTrack = 0; - @state() __isSearchMinimumLength = false; + @state() _isSearchMinimumLength = false; - @state() __matches = 0; + @state() _matches = 0; @property({ attribute: 'minimum-search-length', type: Number }) minimumSearchLength = 3; @property({ type: Boolean }) shouldScroll = true; - @query('#search') __searchElement; + @query('#search') _searchElement; - @state() __searchValue; + @state() _searchValue; - @state() __tracks = []; + @state() _tracks = []; constructor() { super(); - this.__debouncedSearch = debounce(this.__search, 300); + this._debouncedSearch = debounce(this._search, 300); } - async __getCaptions() { - const playlistItem = this.__jwPlayer.getPlaylistItem(); + async _getCaptions() { + const playlistItem = this._jwPlayer.getPlaylistItem(); const { file } = playlistItem.tracks.filter((track) => track.kind === 'captions')[0]; const response = await (await fetch(file)).text(); @@ -44,7 +44,7 @@ export function TranscriptMixin(BaseClass) { } /* eslint-disable array-callback-return, class-methods-use-this, consistent-return, no-return-assign */ - __getCaptionsInChapter(chapters, captions, index) { + _getCaptionsInChapter(chapters, captions, index) { return captions.filter((caption) => { if (caption.data.start >= chapters[index].data.start) { if (chapters[index + 1]) { @@ -59,31 +59,31 @@ export function TranscriptMixin(BaseClass) { } /* eslint-enable array-callback-return, class-methods-use-this, consistent-return, no-return-assign */ - async __getTracks() { + async _getTracks() { const tracks = []; - const captions = await this.__getCaptions(); - const chapters = [...[{ data: { start: 0, text: '' } }], ...(await this.__getChapters())]; + const captions = await this._getCaptions(); + const chapters = [...[{ data: { start: 0, text: '' } }], ...(await this._getChapters())]; chapters.forEach((chapter, index) => { tracks.push({ ...chapter, ...{ isChapter: true } }); - tracks.push(...this.__getCaptionsInChapter(chapters, captions, index)); + tracks.push(...this._getCaptionsInChapter(chapters, captions, index)); }); return tracks; } - __onCaptionClick(e) { + _onCaptionClick(e) { const index = Number(e.currentTarget.dataset.index); - this.__jwPlayer.seek(this.__tracks[index].data.start / 1000); + this._jwPlayer.seek(this._tracks[index].data.start / 1000); } - __onTimeListener(event) { - super.__onTimeListener(event); + _onTimeListener(event) { + super._onTimeListener(event); const position = event.position * 1000; // Convert to milliseconds - this.__tracks.forEach(({ data: { end, start } }, index) => { + this._tracks.forEach(({ data: { end, start } }, index) => { if (start <= position && end >= position) { if (this.shouldScroll) { const el = this.renderRoot.querySelector(`[data-index="${index}"]`); @@ -92,51 +92,51 @@ export function TranscriptMixin(BaseClass) { } } - this.__currentTrack = index; + this._currentTrack = index; } }); } - __search() { - this.__mark.unmark(); + _search() { + this._mark.unmark(); - if (this.__searchElement.value.length >= this.minimumSearchLength) { - this.__isSearchMinimumLength = true; + if (this._searchElement.value.length >= this.minimumSearchLength) { + this._isSearchMinimumLength = true; - this.__mark.mark(this.__searchElement.value, { + this._mark.mark(this._searchElement.value, { done: (total) => { - this.__matches = total; + this._matches = total; }, separateWordSearch: false, }); } else { - this.__isSearchMinimumLength = false; + this._isSearchMinimumLength = false; } } - async __setup() { - await super.__setup(); + async _setup() { + await super._setup(); - this.__setupTranscript(); + this._setupTranscript(); } - async __setupTranscript() { - if (!this.__jwPlayer) return; + async _setupTranscript() { + if (!this._jwPlayer) return; - this.__jwPlayer.addButton( + this._jwPlayer.addButton( ``, 'Transcript', - this.__toggleTranscript.bind(this), + this._toggleTranscript.bind(this), 'toggle-transcript' ); if (this.captions) { - this.__tracks = await this.__getTracks(); + this._tracks = await this._getTracks(); // Make sure the DOM is up to date await this.updateComplete; - this.__mark = new Mark(this.renderRoot.querySelectorAll('.captions h2, .captions span')); + this._mark = new Mark(this.renderRoot.querySelectorAll('.captions h2, .captions span')); } } @@ -145,22 +145,22 @@ export function TranscriptMixin(BaseClass) { if (changedProperties.has('captions')) { if (this.captions) { - this.__setupTranscript(); + this._setupTranscript(); } else if (this.mark) { - this.__mark.unmark(); + this._mark.unmark(); } } } - __attachListeners() { - super.__attachListeners(); + _attachListeners() { + super._attachListeners(); } - __toggleShouldScroll() { + _toggleShouldScroll() { this.shouldScroll = !this.shouldScroll; } - __toggleTranscript() { + _toggleTranscript() { // this.dispatchEvent(new CustomEvent('toggle-transcript')); this.captions = !this.captions; diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.html.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.html.js index 6c1cb1f4d..cb89afd14 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.html.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.html.js @@ -8,7 +8,7 @@ export const chapterNavigationTemplate = function (chapters) {
    Chapters html` -
  • +
  • ${chapter.data.text}
  • ` diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js index 2ab998723..0260b6073 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js @@ -7,39 +7,39 @@ export function ChapterNavigationMixin(BaseClass) { class Mixin extends BaseClass { @property({ attribute: 'plugin-path', type: String }) pluginPath; - async __setupChapterNavigation() { - const chapters = await this.__getChapters(); + async _setupChapterNavigation() { + const chapters = await this._getChapters(); - this.__chapterNavigation = document.createElement('div'); - this.__chapterNavigation.classList.add('chapter-navigation'); - this.__chapterNavigation.hidden = true; + this._chapterNavigation = document.createElement('div'); + this._chapterNavigation.classList.add('chapter-navigation'); + this._chapterNavigation.hidden = true; - render(chapterNavigationTemplate.bind(this)(chapters), this.__chapterNavigation); + render(chapterNavigationTemplate.bind(this)(chapters), this._chapterNavigation); - this.__jwPlayerContainer.appendChild(this.__chapterNavigation); + this._jwPlayerContainer.appendChild(this._chapterNavigation); - this.__jwPlayer.addButton( + this._jwPlayer.addButton( ``, 'Show Chapters', - this.__toggleChapterNavigation.bind(this), + this._toggleChapterNavigation.bind(this), 'toggle-chapters' ); } - __chapterSeek(e) { + _chapterSeek(e) { const index = Number(e.currentTarget.dataset.index); - this.__jwPlayer.seek(this.__chapters[index].data.start / 1000); + this._jwPlayer.seek(this._chapters[index].data.start / 1000); } - async __setup() { - await super.__setup(); + async _setup() { + await super._setup(); - this.__addStyle(style); - this.__setupChapterNavigation(); + this._addStyle(style); + this._setupChapterNavigation(); } - __toggleChapterNavigation() { - this.__chapterNavigation.hidden = !this.__chapterNavigation.hidden; + _toggleChapterNavigation() { + this._chapterNavigation.hidden = !this._chapterNavigation.hidden; } } From b1372084c09c00f0e9a2b6d5fa72f2203ef52bc8 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Tue, 28 Feb 2023 12:16:46 -0500 Subject: [PATCH 20/36] feat(cxl-ui): [cxl-jw-player] refactor for playlists --- .../cxl-jw-player/cxl-jw-player-shadow.scss | 9 ++-- .../cxl-jw-player/mixins/BaseMixin.js | 6 ++- .../cxl-jw-player/mixins/TranscriptMixin.js | 46 +++++++++++++------ .../mixins/chapter-navigation/index.js | 6 +++ 4 files changed, 49 insertions(+), 18 deletions(-) diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss index 3b4196d61..22d930f3e 100644 --- a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss +++ b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss @@ -1,10 +1,12 @@ -@use "~@conversionxl/cxl-lumo-styles/scss/mixins"; +@use '~@conversionxl/cxl-lumo-styles/scss/mixins'; :host { box-sizing: border-box; +} - [active] { - background-color: var(--lumo-shade-10pct); +:host([has-captions]) { + .cxl-jw-player-container { + display: grid; } } @@ -36,7 +38,6 @@ } .cxl-jw-player-container { - display: grid; height: 100%; } diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js index 0133d616c..b01bbca74 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js @@ -65,6 +65,11 @@ export function BaseMixin(BaseClass) { async _getChapters() { const playlistItem = this._jwPlayer.getPlaylistItem(); const chapters = playlistItem.tracks.filter((track) => track.kind === 'chapters'); + + if (chapters.length === 0) { + return []; + } + const { file } = chapters.length > 0 ? chapters[0] : ''; const response = await (await fetch(file)).text(); @@ -126,7 +131,6 @@ export function BaseMixin(BaseClass) { * Each mixin has the ability to hook onto this method. */ async _setup() { - // Merge configs from `cxlJWPlayerData`. if (typeof window.cxlJWPlayerData !== 'undefined') { // eslint-disable-next-line camelcase diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js index d1764bec8..49b03c624 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js @@ -10,6 +10,7 @@ export function TranscriptMixin(BaseClass) { _mark; @property({ reflect: true, type: Boolean }) captions = false; + @property({ attribute: 'has-captions', reflect: true, type: Boolean }) hasCaptions = false; @state() _currentCue = 0; @@ -37,8 +38,13 @@ export function TranscriptMixin(BaseClass) { async _getCaptions() { const playlistItem = this._jwPlayer.getPlaylistItem(); - const { file } = playlistItem.tracks.filter((track) => track.kind === 'captions')[0]; - const response = await (await fetch(file)).text(); + const track = playlistItem.tracks.filter((track) => track.kind === 'captions')[0]; + + if (!track) { + return []; + } + + const response = await (await fetch(track.file)).text(); return parseSync(response); } @@ -63,12 +69,15 @@ export function TranscriptMixin(BaseClass) { const tracks = []; const captions = await this._getCaptions(); - const chapters = [...[{ data: { start: 0, text: '' } }], ...(await this._getChapters())]; - chapters.forEach((chapter, index) => { - tracks.push({ ...chapter, ...{ isChapter: true } }); - tracks.push(...this._getCaptionsInChapter(chapters, captions, index)); - }); + if (captions.length) { + const chapters = [...[{ data: { start: 0, text: '' } }], ...(await this._getChapters())]; + + chapters.forEach((chapter, index) => { + tracks.push({ ...chapter, ...{ isChapter: true } }); + tracks.push(...this._getCaptionsInChapter(chapters, captions, index)); + }); + } return tracks; } @@ -118,25 +127,36 @@ export function TranscriptMixin(BaseClass) { await super._setup(); this._setupTranscript(); + + this._jwPlayer.on('playlistItem', this._setupTranscript.bind(this)); } async _setupTranscript() { if (!this._jwPlayer) return; - this._jwPlayer.addButton( - ``, - 'Transcript', - this._toggleTranscript.bind(this), - 'toggle-transcript' - ); + this._tracks = []; if (this.captions) { this._tracks = await this._getTracks(); + } + + if (this._tracks.length) { + this.hasCaptions = true; // Make sure the DOM is up to date await this.updateComplete; this._mark = new Mark(this.renderRoot.querySelectorAll('.captions h2, .captions span')); + + this._jwPlayer.addButton( + ``, + 'Transcript', + this._toggleTranscript.bind(this), + 'toggle-transcript' + ); + } else { + this.hasCaptions = false; + this._jwPlayer.removeButton('toggle-transcript'); } } diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js index 0260b6073..a81609153 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js @@ -10,6 +10,12 @@ export function ChapterNavigationMixin(BaseClass) { async _setupChapterNavigation() { const chapters = await this._getChapters(); + if (!chapters.length) { + this._jwPlayer.removeButton('chapter-navigation'); + + return; + } + this._chapterNavigation = document.createElement('div'); this._chapterNavigation.classList.add('chapter-navigation'); this._chapterNavigation.hidden = true; From 0d2aad0692864270c63ff4a8ad490fad79d45ba5 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Tue, 28 Feb 2023 15:30:42 -0500 Subject: [PATCH 21/36] feat(cxl-ui): [cxl-jw-player] move styles to global directory --- .../cxl-jw-player/cxl-jw-player-chapter-navigation.scss | 0 .../{ => global}/cxl-jw-player/cxl-jw-player-transcript.scss | 0 .../cxl-ui/scss/{ => global}/cxl-jw-player/cxl-jw-player.scss | 0 .../components/cxl-jw-player/cxl-jw-player-transcript/index.js | 2 +- packages/cxl-ui/src/components/cxl-jw-player/index.js | 2 +- .../components/cxl-jw-player/mixins/chapter-navigation/index.js | 2 +- 6 files changed, 3 insertions(+), 3 deletions(-) rename packages/cxl-ui/scss/{ => global}/cxl-jw-player/cxl-jw-player-chapter-navigation.scss (100%) rename packages/cxl-ui/scss/{ => global}/cxl-jw-player/cxl-jw-player-transcript.scss (100%) rename packages/cxl-ui/scss/{ => global}/cxl-jw-player/cxl-jw-player.scss (100%) diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-chapter-navigation.scss b/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-chapter-navigation.scss similarity index 100% rename from packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-chapter-navigation.scss rename to packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-chapter-navigation.scss diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-transcript.scss b/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-transcript.scss similarity index 100% rename from packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-transcript.scss rename to packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-transcript.scss diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player.scss b/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player.scss similarity index 100% rename from packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player.scss rename to packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player.scss diff --git a/packages/cxl-ui/src/components/cxl-jw-player/cxl-jw-player-transcript/index.js b/packages/cxl-ui/src/components/cxl-jw-player/cxl-jw-player-transcript/index.js index 03e2f19bc..35a3a47c2 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/cxl-jw-player-transcript/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/cxl-jw-player-transcript/index.js @@ -1,6 +1,6 @@ import { html, LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; -import style from '../../../styles/cxl-jw-player/cxl-jw-player-transcript-css'; +import style from '../../../styles/global/cxl-jw-player/cxl-jw-player-transcript-css'; import shadowStyle from '../../../styles/cxl-jw-player/cxl-jw-player-transcript-shadow-css'; @customElement('cxl-jw-player-transcript') diff --git a/packages/cxl-ui/src/components/cxl-jw-player/index.js b/packages/cxl-ui/src/components/cxl-jw-player/index.js index 4a13e826a..0ce319264 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/index.js @@ -1,6 +1,6 @@ import { LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; -import style from '../../styles/cxl-jw-player/cxl-jw-player-css'; +import style from '../../styles/global/cxl-jw-player/cxl-jw-player-css'; import shadowStyle from '../../styles/cxl-jw-player/cxl-jw-player-shadow-css'; import { template } from './index.html'; import { diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js index a81609153..4e9df2514 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js @@ -1,6 +1,6 @@ import { render } from 'lit'; import { property } from 'lit/decorators.js'; -import style from '../../../../styles/cxl-jw-player/cxl-jw-player-chapter-navigation-css'; +import style from '../../../../styles/global/cxl-jw-player/cxl-jw-player-chapter-navigation-css'; import { chapterNavigationTemplate } from './index.html'; export function ChapterNavigationMixin(BaseClass) { From a6722278bbf72be7837de35c24943193809fe795 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Tue, 28 Feb 2023 15:31:35 -0500 Subject: [PATCH 22/36] feat(cxl-ui): [cxl-jw-player] remove save position endpoint request --- .../cxl-jw-player/mixins/SavePositionMixin.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js index 8e2a990e4..05594df77 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js @@ -11,7 +11,7 @@ export function SavePositionMixin(BaseClass) { this._endpoint = `${window.ajaxurl}?action=jwplayer_save_position`; - if ( typeof window.cxl_pum_vars !== 'undefined' ) { + if (typeof window.cxl_pum_vars !== 'undefined') { this._nonce = window.cxl_pum_vars.nonce; } @@ -34,15 +34,6 @@ export function SavePositionMixin(BaseClass) { _savePosition({ position }) { localStorage.setItem(`jw-player-${this.mediaId}-position`, position); - - fetch(this._endpoint, { - _ajax_nonce: this._nonce, - body: JSON.stringify({ mediaId: this.mediaId, position }), - headers: { - 'Content-Type': 'application/json', - }, - method: 'POST', - }); } } From c2f9f0f1cce0ce17fdd2340b0783bd1761f01e67 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Wed, 1 Mar 2023 12:11:59 -0500 Subject: [PATCH 23/36] feat(cxl-ui): [cxl-jw-player] add the ability to save the playback rate --- .../src/components/cxl-jw-player/index.js | 4 +- .../cxl-jw-player/mixins/BaseMixin.js | 2 - .../cxl-jw-player/mixins/SavePositionMixin.js | 41 ---------------- .../cxl-jw-player/mixins/StateMixin.js | 49 +++++++++++++++++++ .../components/cxl-jw-player/mixins/index.js | 2 +- 5 files changed, 52 insertions(+), 46 deletions(-) delete mode 100644 packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js create mode 100644 packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js diff --git a/packages/cxl-ui/src/components/cxl-jw-player/index.js b/packages/cxl-ui/src/components/cxl-jw-player/index.js index 0ce319264..5504602a4 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/index.js @@ -7,7 +7,7 @@ import { BaseMixin, ChapterNavigationMixin, NextUpMixin, - SavePositionMixin, + StateMixin, TranscriptMixin, } from './mixins'; import { mixin } from './utility'; @@ -18,7 +18,7 @@ export class CXLJWPlayerElement extends mixin(LitElement, [ TranscriptMixin, ChapterNavigationMixin, NextUpMixin, - SavePositionMixin, + StateMixin, ]) { config = { width: '100%', diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js index b01bbca74..d5a4eb2b5 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js @@ -13,8 +13,6 @@ export function BaseMixin(BaseClass) { _jwPlayerContainer; - _position; - @property({ attribute: 'media-id', type: String }) mediaId; @property({ attribute: 'media-source', type: String }) mediaSource; diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js deleted file mode 100644 index 05594df77..000000000 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/SavePositionMixin.js +++ /dev/null @@ -1,41 +0,0 @@ -export function SavePositionMixin(BaseClass) { - class Mixin extends BaseClass { - _endpoint; - - _nonce; - - _userId; - - async _setup() { - await super._setup(); - - this._endpoint = `${window.ajaxurl}?action=jwplayer_save_position`; - - if (typeof window.cxl_pum_vars !== 'undefined') { - this._nonce = window.cxl_pum_vars.nonce; - } - - this._loadPosition(); - } - - async _loadPosition() { - this._jwPlayer.seek(Number(localStorage.getItem(`jw-player-${this.mediaId}-position`))); - this._jwPlayer.pause(); - } - - /** - * The listener is registered in the base class (../index.js). - */ - _onTimeListener(event) { - super._onTimeListener(event); - - this._savePosition(event); - } - - _savePosition({ position }) { - localStorage.setItem(`jw-player-${this.mediaId}-position`, position); - } - } - - return Mixin; -} diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js new file mode 100644 index 000000000..6379f12c0 --- /dev/null +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js @@ -0,0 +1,49 @@ +export function StateMixin(BaseClass) { + class Mixin extends BaseClass { + _endpoint; + + _nonce; + + _userId; + + async _setup() { + await super._setup(); + + this._endpoint = `${window.ajaxurl}?action=jwplayer_save_position`; + + if (typeof window.cxl_pum_vars !== 'undefined') { + this._nonce = window.cxl_pum_vars.nonce; + } + + this._playbackRate(); + this._position(); + } + + _playbackRate() { + const playbackRate = localStorage.getItem(`jw-player-playback-rate`); + + if (playbackRate) { + this._jwPlayer.setPlaybackRate(Number(playbackRate)); + } + + this._jwPlayer.on('playbackRateChanged', ({ playbackRate }) => { + localStorage.setItem(`jw-player-playback-rate`, playbackRate); + }); + } + + _position() { + const position = localStorage.getItem(`jw-player-${this.mediaId}-position`); + + if (position) { + this._jwPlayer.seek(Number(position)); + this._jwPlayer.pause(); + } + + this._jwPlayer.on('time', ({ position }) => { + localStorage.setItem(`jw-player-${this.mediaId}-position`, position); + }); + } + } + + return Mixin; +} diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js index a5ab24213..ba2613c5a 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/index.js @@ -1,5 +1,5 @@ export { BaseMixin } from './BaseMixin'; export { ChapterNavigationMixin } from './chapter-navigation/index.js'; export { NextUpMixin } from './NextUpMixin'; -export { SavePositionMixin } from './SavePositionMixin'; +export { StateMixin } from './StateMixin'; export { TranscriptMixin } from './TranscriptMixin'; From a33acf6764790f7aaa68cb54e28dbbdc52d9de90 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Fri, 3 Mar 2023 10:28:49 -0500 Subject: [PATCH 24/36] feat(cxl-ui): [cxl-jw-player] add the ability to play protected content --- packages/cxl-ui/package.json | 2 + .../cxl-jw-player/mixins/BaseMixin.js | 54 ++++++++++++++----- .../cxl-ui/cxl-jw-player/index.stories.js | 15 ++++-- .../cxl-ui/cxl-jw-player/playlist.stories.js | 15 ++++-- yarn.lock | 10 ++++ 5 files changed, 74 insertions(+), 22 deletions(-) diff --git a/packages/cxl-ui/package.json b/packages/cxl-ui/package.json index 1465b1530..35bedfb16 100644 --- a/packages/cxl-ui/package.json +++ b/packages/cxl-ui/package.json @@ -30,8 +30,10 @@ "@vaadin/tooltip": "^23.3.7", "@vaadin/vaadin-themable-mixin": "^23.3.7", "cross-env": "~7.0.2", + "crypto-js": "^4.1.1", "headroom.js": "^0.12.0", "imports-loader": "^2.0.0", + "jose": "^4.13.1", "laravel-mix": "^6.0.39", "lit": "^2.2.5", "lodash-es": "^4.17.21", diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js index d5a4eb2b5..ac55edb38 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js @@ -1,7 +1,9 @@ +import * as jose from 'jose'; import { render } from 'lit'; import { property } from 'lit/decorators.js'; import { throttle } from 'lodash-es'; import { parseSync } from 'subtitle'; +import { MD5 } from 'crypto-js'; export function BaseMixin(BaseClass) { class Mixin extends BaseClass { @@ -13,16 +15,18 @@ export function BaseMixin(BaseClass) { _jwPlayerContainer; - @property({ attribute: 'media-id', type: String }) mediaId; - - @property({ attribute: 'media-source', type: String }) mediaSource; + @property({ attribute: 'api-secret', type: String }) apiSecret = ''; - @property({ attribute: 'is-public', type: String }) isPublic; + @property({ attribute: 'is-public', type: Boolean }) isPublic; @property({ attribute: 'library-id', type: String }) libraryId; @property({ attribute: 'library-source', type: String }) librarySource; + @property({ attribute: 'media-id', type: String }) mediaId; + + @property({ attribute: 'media-source', type: String }) mediaSource; + @property({ attribute: 'playlist-id', type: String }) playlistId; @property({ attribute: 'playlist-source', type: String }) playlistSource; @@ -41,14 +45,20 @@ export function BaseMixin(BaseClass) { } get _scriptUrl() { + if (!this.libraryId && !this.librarySource) return false; + let scriptUrl; - if (this.libraryId && this.isPublic) { - scriptUrl = `https://content.jwplatform.com/libraries/${this.libraryId}.js`; - } else if (this.librarySource) { + if (this.libraryId) { + if (this.isPublic) { + scriptUrl = `https://content.jwplatform.com/libraries/${this.libraryId}.js`; + } else { + scriptUrl = this.__signedURL(`libraries/${this.libraryId}.js`); + } + } + + if (this.librarySource) { scriptUrl = this.librarySource; - } else { - return false; } return scriptUrl; @@ -78,7 +88,7 @@ export function BaseMixin(BaseClass) { let response; if (this.mediaId && this.isPublic) { - response = await fetch(`https://cdn.jwplayer.com/v2/media/${this.mediaId}`); + response = await fetch(await this._signedJWTURL(`/v2/media/${this.mediaId}`)); } else if (this.mediaSource) { response = await fetch(this.mediaSource); } else { @@ -92,7 +102,7 @@ export function BaseMixin(BaseClass) { let response; if (this.playlistId) { - response = await fetch(`https://cdn.jwplayer.com/v2/playlists/${this.playlistId}`); + response = await fetch(await this._signedJWTURL(`/v2/playlists/${this.playlistId}`)); } else if (this.playlistSource) { response = await fetch(`https://cdn.jwplayer.com/v2/playlists/${this.playlistId}`); } else { @@ -103,7 +113,7 @@ export function BaseMixin(BaseClass) { } async _loadScript() { - return new Promise((resolve) => { + return new Promise(async (resolve) => { const el = document.createElement('script'); el.src = this._scriptUrl; el.onload = () => { @@ -158,6 +168,26 @@ export function BaseMixin(BaseClass) { this._chapters = await this._getChapters(); } + + async _signedJWTURL(path) { + const secret = new TextEncoder().encode(this.apiSecret); + const alg = 'HS256'; + const typ = 'JWT'; + + const token = await new jose.SignJWT({ resource: path }) + .setProtectedHeader({ alg, typ }) + .setExpirationTime('2h') + .sign(secret); + + return `https://cdn.jwplayer.com${path}?token=${token}`; + } + + __signedURL(path) { + const expires = Math.ceil((new Date().getTime() + 3600) / 300) * 300; + const signature = MD5(`${path}:${expires}:${this.apiSecret}`); + + return `https://cdn.jwplayer.com/${path}?exp=${expires}&sig=${signature}`; + } } return Mixin; diff --git a/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js b/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js index 3d444231a..12bce8a81 100644 --- a/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js +++ b/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js @@ -6,12 +6,14 @@ export default { }; const Template = ({ + apiSecret, captions, + isPublic, + libraryId, + librarySource, mediaId, mediaSource, minimumSearchLength, - libraryId, - librarySource, playlistId, playlistSource, pluginPath, @@ -33,13 +35,14 @@ const Template = ({ Date: Fri, 3 Mar 2023 12:23:30 -0500 Subject: [PATCH 25/36] feat(cxl-ui): [cxl-jw-player] fix media and playlist source url --- .../cxl-jw-player/mixins/BaseMixin.js | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js index ac55edb38..db0ac098d 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js @@ -85,28 +85,40 @@ export function BaseMixin(BaseClass) { } async _getMedia() { + if (!this.mediaId && !this.mediaSource) return false; + let response; - if (this.mediaId && this.isPublic) { - response = await fetch(await this._signedJWTURL(`/v2/media/${this.mediaId}`)); - } else if (this.mediaSource) { + if (this.mediaId) { + if (this.isPublic) { + response = await fetch(`https://cdn.jwplayer.com/v2/media/${this.mediaId}`); + } else { + response = await fetch(await this._signedJWTURL(`/v2/media/${this.mediaId}`)); + } + } + + if (this.mediaSource) { response = await fetch(this.mediaSource); - } else { - return false; } return response.json(); } async _getPlaylist() { + if (!this.playlistId && !this.playlistSource) return false; + let response; if (this.playlistId) { - response = await fetch(await this._signedJWTURL(`/v2/playlists/${this.playlistId}`)); - } else if (this.playlistSource) { - response = await fetch(`https://cdn.jwplayer.com/v2/playlists/${this.playlistId}`); - } else { - return false; + if (this.isPublic) { + response = await fetch(`https://cdn.jwplayer.com/v2/playlists/${this.playlistId}`); + } else { + response = await fetch(await this._signedJWTURL(`/v2/playlists/${this.playlistId}`)); + } + } + + if (this.playlistSource) { + response = await fetch(this.playlistSource); } return response.json(); From 0ec339701f7946ab0c982f58289fbc46aee20fa9 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Fri, 3 Mar 2023 16:14:33 -0500 Subject: [PATCH 26/36] feat(cxl-ui): [cxl-jw-player] fix and improve next up feature --- .../cxl-jw-player/cxl-jw-player-next-up.scss | 9 --------- .../cxl-jw-player/cxl-jw-player-nextup.scss | 20 +++++++++++++++++++ .../src/components/cxl-jw-player/index.js | 1 + .../cxl-jw-player/mixins/NextUpMixin.js | 9 ++++----- 4 files changed, 25 insertions(+), 14 deletions(-) delete mode 100644 packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-next-up.scss create mode 100644 packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-nextup.scss diff --git a/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-next-up.scss b/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-next-up.scss deleted file mode 100644 index 64848aecb..000000000 --- a/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-next-up.scss +++ /dev/null @@ -1,9 +0,0 @@ -cxl-jw-player { - .jw-nextup { - display: none; - } - - .jw-next-up-cta > a { - pointer-events: all; - } -} diff --git a/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-nextup.scss b/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-nextup.scss new file mode 100644 index 000000000..1587b92c9 --- /dev/null +++ b/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-nextup.scss @@ -0,0 +1,20 @@ +cxl-jw-player { + .jw-nextup-container { + display: flex; + flex-direction: column; + align-items: flex-end; + + .jw-nextup-cta { + max-width: 400px; + width: 64%; + + a { + pointer-events: all; + + vaadin-button { + width: 100%; + } + } + } + } +} diff --git a/packages/cxl-ui/src/components/cxl-jw-player/index.js b/packages/cxl-ui/src/components/cxl-jw-player/index.js index 5504602a4..903c10535 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/index.js @@ -22,6 +22,7 @@ export class CXLJWPlayerElement extends mixin(LitElement, [ ]) { config = { width: '100%', + nextupoffset: '-60', playbackRateControls: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2], plugins: { // 'http://192.168.0.101:8080/telemetry-8.20.0.js': {}, diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js index e64279ac6..3b8797d51 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js @@ -1,5 +1,5 @@ import { html, render } from 'lit'; -import style from '../../../styles/global/cxl-jw-player/cxl-jw-player-next-up-css'; +import style from '../../../styles/global/cxl-jw-player/cxl-jw-player-nextup-css'; export function NextUpMixin(BaseClass) { class Mixin extends BaseClass { _nextUpCTA; @@ -10,7 +10,7 @@ export function NextUpMixin(BaseClass) { this._addStyle(style); this._nextUpCTA = document.createElement('div'); - this._nextUpCTA.classList.add('jw-next-up-cta'); + this._nextUpCTA.classList.add('jw-nextup-cta'); const container = this.querySelector('.jw-nextup-container'); container.insertBefore(this._nextUpCTA, container.firstChild); @@ -20,8 +20,7 @@ export function NextUpMixin(BaseClass) { } _updateNextUp() { - const index = this._jwPlayer.getPlaylistIndex(); - const playlistItem = this._jwPlayer.getPlaylistItem(index + 1); + const playlistItem = this._jwPlayer.getPlaylistItem(); if (playlistItem && playlistItem.coursePage) { render(this._getTemplate(playlistItem), this._nextUpCTA); @@ -32,7 +31,7 @@ export function NextUpMixin(BaseClass) { _getTemplate(playlistItem) { return html` - Go to the course page + Click here to continue this course `; } From ffa54c4ade700606d7f1e661d1d1146e8c4f8943 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Fri, 3 Mar 2023 16:15:21 -0500 Subject: [PATCH 27/36] feat(cxl-ui): [cxl-jw-player] remove api secret default value --- packages/storybook/cxl-ui/cxl-jw-player/index.stories.js | 2 +- packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js b/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js index 12bce8a81..60b129bc8 100644 --- a/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js +++ b/packages/storybook/cxl-ui/cxl-jw-player/index.stories.js @@ -53,7 +53,7 @@ export const Default = Template.bind({}); Object.assign(Default, { args: { - apiSecret: 'API_SECRET', + apiSecret: '', captions: true, isPublic: true, libraryId: '5CFJNXKb', diff --git a/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js b/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js index 1d597111a..1db9e33ae 100644 --- a/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js +++ b/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js @@ -53,7 +53,7 @@ export const Playlist = Template.bind({}); Object.assign(Playlist, { args: { - apiSecret: 'API_SECRET', + apiSecret: '', captions: true, isPublic: true, libraryId: '5CFJNXKb', From e4c8edbf0faf7b4cedd287c901d32c67aa5f9544 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Fri, 3 Mar 2023 17:26:54 -0500 Subject: [PATCH 28/36] feat(cxl-ui): [cxl-jw-player] fix save position when using a playlist --- .../cxl-jw-player/mixins/StateMixin.js | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js index 6379f12c0..cb28364ed 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js @@ -32,17 +32,31 @@ export function StateMixin(BaseClass) { } _position() { - const position = localStorage.getItem(`jw-player-${this.mediaId}-position`); + const mediaId = this.mediaId || this._jwPlayer.getPlaylistItem().mediaId; + + const position = localStorage.getItem(`jw-player-${mediaId}-position`); if (position) { - this._jwPlayer.seek(Number(position)); - this._jwPlayer.pause(); + if (this.mediaId) { + this._setPosition(position); + } else { + this._jwPlayer.on('playlistItem', () => { + this._setPosition(position); + }); + + this._jwPlayer.playlistItem(this._jwPlayer.getPlaylistIndex()); + } } - this._jwPlayer.on('time', ({ position }) => { - localStorage.setItem(`jw-player-${this.mediaId}-position`, position); + this._jwPlayer.on('seek time', ({ position }) => { + localStorage.setItem(`jw-player-${mediaId}-position`, position); }); } + + _setPosition(position) { + this._jwPlayer.seek(Number(position)); + this._jwPlayer.pause(); + } } return Mixin; From 5fe476c5be7cd21776902c24944b31c9cd083d61 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Tue, 7 Mar 2023 08:45:36 -0500 Subject: [PATCH 29/36] feat(cxl-ui): [cxl-jw-player] add ability to save playlist index --- .../cxl-jw-player/mixins/StateMixin.js | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js index cb28364ed..14eef3ca9 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js @@ -20,36 +20,45 @@ export function StateMixin(BaseClass) { } _playbackRate() { - const playbackRate = localStorage.getItem(`jw-player-playback-rate`); + const playbackRate = localStorage.getItem(`cxl-jw-player-playback-rate`); if (playbackRate) { this._jwPlayer.setPlaybackRate(Number(playbackRate)); } this._jwPlayer.on('playbackRateChanged', ({ playbackRate }) => { - localStorage.setItem(`jw-player-playback-rate`, playbackRate); + localStorage.setItem(`cxl-jw-player-playback-rate`, playbackRate); }); } _position() { const mediaId = this.mediaId || this._jwPlayer.getPlaylistItem().mediaId; - const position = localStorage.getItem(`jw-player-${mediaId}-position`); + const position = localStorage.getItem(`cxl-jw-player-${mediaId}-position`); if (position) { if (this.mediaId) { this._setPosition(position); } else { - this._jwPlayer.on('playlistItem', () => { - this._setPosition(position); + this._jwPlayer.on('playlistItem', ({ index }) => { + localStorage.setItem(`cxl-jw-player-${this.playlistId}-index`, index); + + // Wait for the player to load the new playlist item + setTimeout(() => { + this._setPosition(position); + }, 1000); }); - this._jwPlayer.playlistItem(this._jwPlayer.getPlaylistIndex()); + const index = + localStorage.getItem(`cxl-jw-player-${this.playlistId}-index`) || + this._jwPlayer.getPlaylistIndex(); + + this._jwPlayer.playlistItem(index); } } this._jwPlayer.on('seek time', ({ position }) => { - localStorage.setItem(`jw-player-${mediaId}-position`, position); + localStorage.setItem(`cxl-jw-player-${mediaId}-position`, position); }); } From 4f5889ccb3850f024b6aaeaa625a4c7a6f644852 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Tue, 7 Mar 2023 09:50:05 -0500 Subject: [PATCH 30/36] feat(cxl-ui): [cxl-jw-player] add nextupoffset attribute --- .../cxl-ui/src/components/cxl-jw-player/index.js | 1 - .../components/cxl-jw-player/mixins/BaseMixin.js | 8 ++++++-- .../components/cxl-jw-player/mixins/NextUpMixin.js | 13 ++++++++++++- .../cxl-ui/cxl-jw-player/playlist.stories.js | 3 +++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/cxl-ui/src/components/cxl-jw-player/index.js b/packages/cxl-ui/src/components/cxl-jw-player/index.js index 903c10535..5504602a4 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/index.js @@ -22,7 +22,6 @@ export class CXLJWPlayerElement extends mixin(LitElement, [ ]) { config = { width: '100%', - nextupoffset: '-60', playbackRateControls: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2], plugins: { // 'http://192.168.0.101:8080/telemetry-8.20.0.js': {}, diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js index db0ac098d..3fc218bcd 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js @@ -31,9 +31,10 @@ export function BaseMixin(BaseClass) { @property({ attribute: 'playlist-source', type: String }) playlistSource; - firstUpdated(_changedProperties) { - super.firstUpdated(_changedProperties); + async firstUpdated(_changedProperties) { + await super.firstUpdated(_changedProperties); + await this._beforeSetup(); this._setup(); } @@ -70,6 +71,9 @@ export function BaseMixin(BaseClass) { this.appendChild(el); } + // eslint-disable-next-line class-methods-use-this, no-empty-function + _beforeSetup() {} + async _getChapters() { const playlistItem = this._jwPlayer.getPlaylistItem(); const chapters = playlistItem.tracks.filter((track) => track.kind === 'chapters'); diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js index 3b8797d51..011264f7d 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js @@ -1,9 +1,18 @@ import { html, render } from 'lit'; +import { property } from 'lit/decorators.js'; import style from '../../../styles/global/cxl-jw-player/cxl-jw-player-nextup-css'; export function NextUpMixin(BaseClass) { class Mixin extends BaseClass { _nextUpCTA; + @property({ attribute: 'nextupoffset', type: String }) nextupoffset = '-100%`'; + + async _beforeSetup() { + await super._beforeSetup(); + + this.config.nextupoffset = this.nextupoffset; + } + async _setup() { await super._setup(); @@ -31,7 +40,9 @@ export function NextUpMixin(BaseClass) { _getTemplate(playlistItem) { return html` - Click here to continue this course + Click here to continue this course `; } diff --git a/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js b/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js index 1db9e33ae..7e32092de 100644 --- a/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js +++ b/packages/storybook/cxl-ui/cxl-jw-player/playlist.stories.js @@ -14,6 +14,7 @@ const Template = ({ mediaId, mediaSource, minimumSearchLength, + nextupoffset, playlistId, playlistSource, pluginPath, @@ -43,6 +44,7 @@ const Template = ({ media-id=${mediaId} media-source=${mediaSource} minimum-search-length=${minimumSearchLength} + nextupoffset=${nextupoffset} playlist-id=${playlistId} playlist-source=${playlistSource} plugin-path="${pluginPath}" @@ -61,6 +63,7 @@ Object.assign(Playlist, { mediaId: '', mediaSource: '', minimumSearchLength: 3, + nextupoffset: '-100%', playlistId: 'tAxwbNsA', playlistSource: '', pluginPath: 'https://cxl.com/institute/wp-content/plugins/cxl-jwplayer/', From 71a4554641b74a0bb67af51e30728f4458846e9e Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Tue, 7 Mar 2023 10:26:52 -0500 Subject: [PATCH 31/36] feat(cxl-ui): [cxl-jw-player] add separate mobile CTA --- .../cxl-jw-player/cxl-jw-player-nextup.scss | 12 ++++++++ .../cxl-jw-player/mixins/BaseMixin.js | 18 ++++++++++++ .../cxl-jw-player/mixins/NextUpMixin.js | 29 ++++++++++++++----- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-nextup.scss b/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-nextup.scss index 1587b92c9..81bc380e1 100644 --- a/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-nextup.scss +++ b/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-nextup.scss @@ -1,4 +1,16 @@ cxl-jw-player { + &[wide] { + .jw-nextup-cta-mobile { + display: none; + } + } + + &:not([wide]) { + .jw-nextup-cta { + display: none; + } + } + .jw-nextup-container { display: flex; flex-direction: column; diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js index 3fc218bcd..91f4874c9 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js @@ -4,6 +4,7 @@ import { property } from 'lit/decorators.js'; import { throttle } from 'lodash-es'; import { parseSync } from 'subtitle'; import { MD5 } from 'crypto-js'; +import { MediaQueryController } from '@vaadin/component-base/src/media-query-controller.js'; export function BaseMixin(BaseClass) { class Mixin extends BaseClass { @@ -15,6 +16,9 @@ export function BaseMixin(BaseClass) { _jwPlayerContainer; + // Device Detector media query. + _wideMediaQuery = '(min-width: 750px)'; + @property({ attribute: 'api-secret', type: String }) apiSecret = ''; @property({ attribute: 'is-public', type: Boolean }) isPublic; @@ -31,6 +35,20 @@ export function BaseMixin(BaseClass) { @property({ attribute: 'playlist-source', type: String }) playlistSource; + // MediaQueryController. + @property({ type: Boolean, reflect: true }) + wide; + + constructor() { + super(); + + this.addController( + new MediaQueryController(this._wideMediaQuery, (matches) => { + this.wide = matches; + }) + ); + } + async firstUpdated(_changedProperties) { await super.firstUpdated(_changedProperties); diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js index 011264f7d..b654ccc58 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/NextUpMixin.js @@ -3,7 +3,8 @@ import { property } from 'lit/decorators.js'; import style from '../../../styles/global/cxl-jw-player/cxl-jw-player-nextup-css'; export function NextUpMixin(BaseClass) { class Mixin extends BaseClass { - _nextUpCTA; + _nextupCTA; + _nextupCTAMobile; @property({ attribute: 'nextupoffset', type: String }) nextupoffset = '-100%`'; @@ -18,11 +19,15 @@ export function NextUpMixin(BaseClass) { this._addStyle(style); - this._nextUpCTA = document.createElement('div'); - this._nextUpCTA.classList.add('jw-nextup-cta'); + this._nextupCTA = document.createElement('div'); + this._nextupCTA.classList.add('jw-nextup-cta'); + + this._nextupCTAMobile = document.createElement('div'); + this._nextupCTAMobile.classList.add('jw-nextup-cta-mobile'); const container = this.querySelector('.jw-nextup-container'); - container.insertBefore(this._nextUpCTA, container.firstChild); + container.insertBefore(this._nextupCTA, container.firstChild); + container.insertBefore(this._nextupCTAMobile, container.firstChild); this._updateNextUp(); this._jwPlayer.on('playlistItem', this._updateNextUp.bind(this)); @@ -32,17 +37,25 @@ export function NextUpMixin(BaseClass) { const playlistItem = this._jwPlayer.getPlaylistItem(); if (playlistItem && playlistItem.coursePage) { - render(this._getTemplate(playlistItem), this._nextUpCTA); + render(this._getTemplate(playlistItem), this._nextupCTA); + render(this._getMobileTemplate(playlistItem), this._nextupCTAMobile); } } + // eslint-disable-next-line class-methods-use-this + _getMobileTemplate(playlistItem) { + return html` + + Go to course + + `; + } + // eslint-disable-next-line class-methods-use-this _getTemplate(playlistItem) { return html` - Click here to continue this course + Go to course `; } From e9f39e22cdd7e168e0d424444ffcbeea135b3dfa Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Tue, 7 Mar 2023 10:44:48 -0500 Subject: [PATCH 32/36] feat(cxl-ui): [cxl-jw-player] fix chapter navigation when using playlists --- .../mixins/chapter-navigation/index.js | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js index 4e9df2514..009a4c0aa 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/chapter-navigation/index.js @@ -5,25 +5,21 @@ import { chapterNavigationTemplate } from './index.html'; export function ChapterNavigationMixin(BaseClass) { class Mixin extends BaseClass { + _chapterNavigation; + @property({ attribute: 'plugin-path', type: String }) pluginPath; async _setupChapterNavigation() { const chapters = await this._getChapters(); if (!chapters.length) { - this._jwPlayer.removeButton('chapter-navigation'); + this._jwPlayer.removeButton('toggle-chapters'); return; } - this._chapterNavigation = document.createElement('div'); - this._chapterNavigation.classList.add('chapter-navigation'); - this._chapterNavigation.hidden = true; - render(chapterNavigationTemplate.bind(this)(chapters), this._chapterNavigation); - this._jwPlayerContainer.appendChild(this._chapterNavigation); - this._jwPlayer.addButton( ``, 'Show Chapters', @@ -39,9 +35,23 @@ export function ChapterNavigationMixin(BaseClass) { async _setup() { await super._setup(); - + this._addStyle(style); - this._setupChapterNavigation(); + + this._chapterNavigation = document.createElement('div'); + this._chapterNavigation.classList.add('chapter-navigation'); + this._chapterNavigation.hidden = true; + this._jwPlayerContainer.appendChild(this._chapterNavigation); + + if (this.mediaId) { + this._setupChapterNavigation(); + } + + if (this.playlistId) { + this._jwPlayer.on('playlistItem', () => { + this._setupChapterNavigation(); + }); + } } _toggleChapterNavigation() { From 3f024f414e82ec249ff2cd4c4d5f6015a226abcd Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Tue, 7 Mar 2023 12:31:20 -0500 Subject: [PATCH 33/36] feat(cxl-ui): [cxl-jw-player] fix CTA pointer events --- .../cxl-jw-player/cxl-jw-player-nextup.scss | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-nextup.scss b/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-nextup.scss index 81bc380e1..3a1eb4ef2 100644 --- a/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-nextup.scss +++ b/packages/cxl-ui/scss/global/cxl-jw-player/cxl-jw-player-nextup.scss @@ -16,16 +16,19 @@ cxl-jw-player { flex-direction: column; align-items: flex-end; + .jw-nextup-cta, + .jw-nextup-cta-mobile { + a { + pointer-events: all; + } + } + .jw-nextup-cta { max-width: 400px; width: 64%; - a { - pointer-events: all; - - vaadin-button { - width: 100%; - } + vaadin-button { + width: 100%; } } } From 62876387c381a51f80f9e2bad2ce4837d3e1eccb Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Mon, 26 Aug 2024 13:48:33 +0000 Subject: [PATCH 34/36] feat(cxl-ui): [cxl-jw-player] fix saving position when using a playlist --- .../cxl-jw-player/mixins/BaseMixin.js | 9 ++- .../cxl-jw-player/mixins/StateMixin.js | 60 ++++++++++--------- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js index 91f4874c9..6068c042a 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/BaseMixin.js @@ -161,6 +161,9 @@ export function BaseMixin(BaseClass) { * Each mixin has the ability to hook onto this method. */ + // eslint-disable-next-line class-methods-use-this, no-unused-vars, no-empty-function + async _onReadyListener() {} + // eslint-disable-next-line class-methods-use-this, no-unused-vars, no-empty-function async _onTimeListener(event) {} @@ -193,7 +196,11 @@ export function BaseMixin(BaseClass) { }); await new Promise((resolve) => { - this._jwPlayer.on('ready', resolve); + this._jwPlayer.on('ready', async () => { + await this._onReadyListener(); + + resolve(); + }); }); this._jwPlayerContainer = this._jwPlayer.getContainer(); diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js index 14eef3ca9..1046210a7 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/StateMixin.js @@ -6,6 +6,26 @@ export function StateMixin(BaseClass) { _userId; + async _index() { + if (this.playlistId) { + const index = + localStorage.getItem(`cxl-jw-player-${this.playlistId}-index`) || + this._jwPlayer.getPlaylistIndex(); + + this._jwPlayer.playlistItem(index); + + this._jwPlayer.on('playlistItem', async ({ index }) => { + localStorage.setItem(`cxl-jw-player-${this.playlistId}-index`, index); + }); + } + } + + async _onReadyListener() { + await this._index(); + this._position(); + this._playbackRate(); + } + async _setup() { await super._setup(); @@ -14,9 +34,6 @@ export function StateMixin(BaseClass) { if (typeof window.cxl_pum_vars !== 'undefined') { this._nonce = window.cxl_pum_vars.nonce; } - - this._playbackRate(); - this._position(); } _playbackRate() { @@ -32,39 +49,28 @@ export function StateMixin(BaseClass) { } _position() { - const mediaId = this.mediaId || this._jwPlayer.getPlaylistItem().mediaId; - - const position = localStorage.getItem(`cxl-jw-player-${mediaId}-position`); + if (this.mediaId) { + this._setPosition(); + } - if (position) { - if (this.mediaId) { - this._setPosition(position); - } else { - this._jwPlayer.on('playlistItem', ({ index }) => { - localStorage.setItem(`cxl-jw-player-${this.playlistId}-index`, index); - - // Wait for the player to load the new playlist item - setTimeout(() => { - this._setPosition(position); - }, 1000); - }); - - const index = - localStorage.getItem(`cxl-jw-player-${this.playlistId}-index`) || - this._jwPlayer.getPlaylistIndex(); - - this._jwPlayer.playlistItem(index); - } + if (this.playlistId) { + this._jwPlayer.on('playlistItem', async ({ index }) => { + await jwplayer().getPlaylistItemPromise(index); + this._setPosition(); + }); } this._jwPlayer.on('seek time', ({ position }) => { + const mediaId = this.mediaId || this._jwPlayer.getPlaylistItem().mediaid; localStorage.setItem(`cxl-jw-player-${mediaId}-position`, position); }); } - _setPosition(position) { + _setPosition() { + const mediaId = this.mediaId || this._jwPlayer.getPlaylistItem().mediaid; + const position = localStorage.getItem(`cxl-jw-player-${mediaId}-position`); + this._jwPlayer.seek(Number(position)); - this._jwPlayer.pause(); } } From 8fcc612c8bc85c3dc1dc48c2f3a52dfef020f3dd Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Mon, 26 Aug 2024 14:02:05 +0000 Subject: [PATCH 35/36] feat(cxl-ui): cxl-jw-player update component references --- packages/cxl-ui/src/components/cxl-course-dialog.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/cxl-ui/src/components/cxl-course-dialog.js b/packages/cxl-ui/src/components/cxl-course-dialog.js index 45e8b063c..6f0cc5386 100644 --- a/packages/cxl-ui/src/components/cxl-course-dialog.js +++ b/packages/cxl-ui/src/components/cxl-course-dialog.js @@ -5,7 +5,7 @@ import { registerGlobalStyles } from '@conversionxl/cxl-lumo-styles/src/utils'; import '@vaadin/button'; import '@vaadin/dialog'; import './cxl-time.js'; -import './jw-player/index.js'; +import './cxl-jw-player/index.js'; import { dialogFooterRenderer, dialogRenderer } from '@vaadin/dialog/lit.js'; import cxlCourseDialogGlobalStyles from '../styles/global/cxl-course-dialog-css.js'; @@ -64,14 +64,14 @@ export class CXLCourseDialogElement extends LitElement {
    ${this.video - ? html` ` + >` : ''}

    ${this.course.description}

    From 3373bf13b60aab878a5748c4feba0ba11d2084c4 Mon Sep 17 00:00:00 2001 From: Andrew Noblet Date: Tue, 10 Sep 2024 14:31:57 +0000 Subject: [PATCH 36/36] feat(cxl-ui): [cxl-jw-player] fix poor refactoring --- .../cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss | 9 +++++++-- .../cxl-ui/src/components/cxl-jw-player/index.html.js | 2 +- packages/cxl-ui/src/components/cxl-jw-player/index.js | 1 + .../components/cxl-jw-player/mixins/TranscriptMixin.js | 4 ++-- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss index 22d930f3e..47d442925 100644 --- a/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss +++ b/packages/cxl-ui/scss/cxl-jw-player/cxl-jw-player-shadow.scss @@ -2,11 +2,16 @@ :host { box-sizing: border-box; + + [active] { + background-color: var(--lumo-shade-10pct); + } } -:host([has-captions]) { - .cxl-jw-player-container { +:host([captions]) { + #container { display: grid; + grid-template-rows: 1fr max-content 1fr; } } diff --git a/packages/cxl-ui/src/components/cxl-jw-player/index.html.js b/packages/cxl-ui/src/components/cxl-jw-player/index.html.js index 57f840bfa..c248e1a3e 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/index.html.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/index.html.js @@ -5,7 +5,7 @@ import '@vaadin/text-field'; // eslint-disable-next-line func-names export const template = function () { return html` -
    +
    ${this.captions ? html` diff --git a/packages/cxl-ui/src/components/cxl-jw-player/index.js b/packages/cxl-ui/src/components/cxl-jw-player/index.js index 5504602a4..1feb2ec0b 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/index.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/index.js @@ -21,6 +21,7 @@ export class CXLJWPlayerElement extends mixin(LitElement, [ StateMixin, ]) { config = { + height: '100%', width: '100%', playbackRateControls: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2], plugins: { diff --git a/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js b/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js index 49b03c624..9f72c6f90 100644 --- a/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js +++ b/packages/cxl-ui/src/components/cxl-jw-player/mixins/TranscriptMixin.js @@ -141,7 +141,7 @@ export function TranscriptMixin(BaseClass) { } if (this._tracks.length) { - this.hasCaptions = true; + this.captions = true; // Make sure the DOM is up to date await this.updateComplete; @@ -155,7 +155,7 @@ export function TranscriptMixin(BaseClass) { 'toggle-transcript' ); } else { - this.hasCaptions = false; + this.captions = false; this._jwPlayer.removeButton('toggle-transcript'); } }