@mottosports/motto-video-player 1.0.1-rc.15 → 1.0.1-rc.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/index.js +137 -50
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +116 -29
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@ React video player component for the Motto platform, powered by Shaka Player wit
|
|
|
8
8
|
- 🔄 **TanStack Query Integration**: Advanced caching, background refetching, and error handling
|
|
9
9
|
- 📱 **Responsive Design**: Automatic aspect ratio handling and mobile-friendly controls
|
|
10
10
|
- 🎮 **Skip Controls**: Built-in skip back/forward buttons with customizable durations
|
|
11
|
+
- ⌨️ **Keyboard Controls**: Desktop keyboard shortcuts (arrows for skip, spacebar for play/pause)
|
|
11
12
|
- 🎯 **Quality Control**: Automatic quality selection and manual quality switching
|
|
12
13
|
- 📊 **Analytics**: Built-in Mux analytics support
|
|
13
14
|
- 🖥️ **Chromecast Support**: Cast videos to compatible devices
|
|
@@ -126,6 +127,16 @@ function MyPlayer() {
|
|
|
126
127
|
/>
|
|
127
128
|
```
|
|
128
129
|
|
|
130
|
+
### Keyboard Controls
|
|
131
|
+
|
|
132
|
+
Desktop users can control the player using keyboard shortcuts:
|
|
133
|
+
|
|
134
|
+
- **←** Left Arrow: Skip back 15 seconds
|
|
135
|
+
- **→** Right Arrow: Skip forward 15 seconds
|
|
136
|
+
- **Space**: Play/Pause toggle
|
|
137
|
+
|
|
138
|
+
Keyboard controls are automatically enabled on desktop devices (disabled on mobile) and work when the player is focused or when no input fields are active.
|
|
139
|
+
|
|
129
140
|
### Responsive Sizing
|
|
130
141
|
|
|
131
142
|
```jsx
|
package/dist/index.js
CHANGED
|
@@ -67,7 +67,7 @@ function styleInject(css, { insertAt } = {}) {
|
|
|
67
67
|
styleInject('/*! tailwindcss v4.1.8 | MIT License | https://tailwindcss.com */\n@layer properties;\n@layer theme, base, components, utilities;\n@layer theme {\n :root,\n :host {\n --font-sans:\n ui-sans-serif,\n system-ui,\n sans-serif,\n "Apple Color Emoji",\n "Segoe UI Emoji",\n "Segoe UI Symbol",\n "Noto Color Emoji";\n --font-mono:\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n "Liberation Mono",\n "Courier New",\n monospace;\n --color-red-600: oklch(57.7% 0.245 27.325);\n --color-black: #000;\n --color-white: #fff;\n --spacing: 0.25rem;\n --text-xs: 0.75rem;\n --text-xs--line-height: calc(1 / 0.75);\n --text-sm: 0.875rem;\n --text-sm--line-height: calc(1.25 / 0.875);\n --text-base: 1rem;\n --text-base--line-height: calc(1.5 / 1);\n --text-lg: 1.125rem;\n --text-lg--line-height: calc(1.75 / 1.125);\n --text-xl: 1.25rem;\n --text-xl--line-height: calc(1.75 / 1.25);\n --text-2xl: 1.5rem;\n --text-2xl--line-height: calc(2 / 1.5);\n --text-5xl: 3rem;\n --text-5xl--line-height: 1;\n --font-weight-medium: 500;\n --font-weight-semibold: 600;\n --font-weight-bold: 700;\n --tracking-wide: 0.025em;\n --tracking-widest: 0.1em;\n --radius-md: 0.375rem;\n --radius-2xl: 1rem;\n --animate-spin: spin 1s linear infinite;\n --animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n --aspect-video: 16 / 9;\n --default-transition-duration: 150ms;\n --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n --default-font-family: var(--font-sans);\n --default-mono-font-family: var(--font-mono);\n }\n}\n@layer base {\n *,\n ::after,\n ::before,\n ::backdrop,\n ::file-selector-button {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0 solid;\n }\n html,\n :host {\n line-height: 1.5;\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n }\n hr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n }\n abbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-size: inherit;\n font-weight: inherit;\n }\n a {\n color: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n }\n b,\n strong {\n font-weight: bolder;\n }\n code,\n kbd,\n samp,\n pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n }\n small {\n font-size: 80%;\n }\n sub,\n sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n }\n sub {\n bottom: -0.25em;\n }\n sup {\n top: -0.5em;\n }\n table {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n }\n :-moz-focusring {\n outline: auto;\n }\n progress {\n vertical-align: baseline;\n }\n summary {\n display: list-item;\n }\n ol,\n ul,\n menu {\n list-style: none;\n }\n img,\n svg,\n video,\n canvas,\n audio,\n iframe,\n embed,\n object {\n display: block;\n vertical-align: middle;\n }\n img,\n video {\n max-width: 100%;\n height: auto;\n }\n button,\n input,\n select,\n optgroup,\n textarea,\n ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n border-radius: 0;\n background-color: transparent;\n opacity: 1;\n }\n :where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n }\n :where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n }\n ::file-selector-button {\n margin-inline-end: 4px;\n }\n ::placeholder {\n opacity: 1;\n }\n @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentcolor;\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n }\n textarea {\n resize: vertical;\n }\n ::-webkit-search-decoration {\n -webkit-appearance: none;\n }\n ::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n }\n ::-webkit-datetime-edit {\n display: inline-flex;\n }\n ::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n }\n ::-webkit-datetime-edit,\n ::-webkit-datetime-edit-year-field,\n ::-webkit-datetime-edit-month-field,\n ::-webkit-datetime-edit-day-field,\n ::-webkit-datetime-edit-hour-field,\n ::-webkit-datetime-edit-minute-field,\n ::-webkit-datetime-edit-second-field,\n ::-webkit-datetime-edit-millisecond-field,\n ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n }\n :-moz-ui-invalid {\n box-shadow: none;\n }\n button,\n input:where([type=button], [type=reset], [type=submit]),\n ::file-selector-button {\n appearance: button;\n }\n ::-webkit-inner-spin-button,\n ::-webkit-outer-spin-button {\n height: auto;\n }\n [hidden]:where(:not([hidden=until-found])) {\n display: none !important;\n }\n}\n@layer utilities {\n .pointer-events-auto {\n pointer-events: auto;\n }\n .pointer-events-none {\n pointer-events: none;\n }\n .visible {\n visibility: visible;\n }\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n }\n .absolute {\n position: absolute;\n }\n .fixed {\n position: fixed;\n }\n .relative {\n position: relative;\n }\n .static {\n position: static;\n }\n .inset-0 {\n inset: calc(var(--spacing) * 0);\n }\n .top-0 {\n top: calc(var(--spacing) * 0);\n }\n .top-4 {\n top: calc(var(--spacing) * 4);\n }\n .right-0 {\n right: calc(var(--spacing) * 0);\n }\n .right-4 {\n right: calc(var(--spacing) * 4);\n }\n .bottom-0 {\n bottom: calc(var(--spacing) * 0);\n }\n .bottom-4 {\n bottom: calc(var(--spacing) * 4);\n }\n .left-0 {\n left: calc(var(--spacing) * 0);\n }\n .left-4 {\n left: calc(var(--spacing) * 4);\n }\n .z-10 {\n z-index: 10;\n }\n .z-50 {\n z-index: 50;\n }\n .container {\n width: 100%;\n @media (width >= 40rem) {\n max-width: 40rem;\n }\n @media (width >= 48rem) {\n max-width: 48rem;\n }\n @media (width >= 64rem) {\n max-width: 64rem;\n }\n @media (width >= 80rem) {\n max-width: 80rem;\n }\n @media (width >= 96rem) {\n max-width: 96rem;\n }\n }\n .m-6 {\n margin: calc(var(--spacing) * 6);\n }\n .mt-1 {\n margin-top: calc(var(--spacing) * 1);\n }\n .mt-3 {\n margin-top: calc(var(--spacing) * 3);\n }\n .mb-2 {\n margin-bottom: calc(var(--spacing) * 2);\n }\n .mb-6 {\n margin-bottom: calc(var(--spacing) * 6);\n }\n .flex {\n display: flex;\n }\n .grid {\n display: grid;\n }\n .hidden {\n display: none;\n }\n .aspect-video {\n aspect-ratio: var(--aspect-video);\n }\n .h-2 {\n height: calc(var(--spacing) * 2);\n }\n .h-12 {\n height: calc(var(--spacing) * 12);\n }\n .h-24 {\n height: calc(var(--spacing) * 24);\n }\n .h-full {\n height: 100%;\n }\n .w-2 {\n width: calc(var(--spacing) * 2);\n }\n .w-12 {\n width: calc(var(--spacing) * 12);\n }\n .w-24 {\n width: calc(var(--spacing) * 24);\n }\n .w-full {\n width: 100%;\n }\n .animate-pulse {\n animation: var(--animate-pulse);\n }\n .animate-spin {\n animation: var(--animate-spin);\n }\n .auto-cols-max {\n grid-auto-columns: max-content;\n }\n .grid-flow-col {\n grid-auto-flow: column;\n }\n .flex-col {\n flex-direction: column;\n }\n .items-center {\n align-items: center;\n }\n .justify-center {\n justify-content: center;\n }\n .justify-stretch {\n justify-content: stretch;\n }\n .gap-1 {\n gap: calc(var(--spacing) * 1);\n }\n .gap-5 {\n gap: calc(var(--spacing) * 5);\n }\n .overflow-hidden {\n overflow: hidden;\n }\n .rounded-full {\n border-radius: calc(infinity * 1px);\n }\n .rounded-md {\n border-radius: var(--radius-md);\n }\n .bg-\\[\\#151515\\] {\n background-color: #151515;\n }\n .bg-black {\n background-color: var(--color-black);\n }\n .bg-red-600 {\n background-color: var(--color-red-600);\n }\n .bg-white {\n background-color: var(--color-white);\n }\n .bg-gradient-to-t {\n --tw-gradient-position: to top in oklab;\n background-image: linear-gradient(var(--tw-gradient-stops));\n }\n .from-black\\/70 {\n --tw-gradient-from: color-mix(in srgb, #000 70%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n --tw-gradient-from: color-mix(in oklab, var(--color-black) 70%, transparent);\n }\n --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));\n }\n .to-transparent {\n --tw-gradient-to: transparent;\n --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));\n }\n .bg-cover {\n background-size: cover;\n }\n .bg-center {\n background-position: center;\n }\n .bg-no-repeat {\n background-repeat: no-repeat;\n }\n .p-2 {\n padding: calc(var(--spacing) * 2);\n }\n .p-4 {\n padding: calc(var(--spacing) * 4);\n }\n .px-2 {\n padding-inline: calc(var(--spacing) * 2);\n }\n .px-4 {\n padding-inline: calc(var(--spacing) * 4);\n }\n .py-1 {\n padding-block: calc(var(--spacing) * 1);\n }\n .text-center {\n text-align: center;\n }\n .text-left {\n text-align: left;\n }\n .font-mono {\n font-family: var(--font-mono);\n }\n .text-2xl {\n font-size: var(--text-2xl);\n line-height: var(--tw-leading, var(--text-2xl--line-height));\n }\n .text-5xl {\n font-size: var(--text-5xl);\n line-height: var(--tw-leading, var(--text-5xl--line-height));\n }\n .text-base {\n font-size: var(--text-base);\n line-height: var(--tw-leading, var(--text-base--line-height));\n }\n .text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n }\n .text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n .text-xl {\n font-size: var(--text-xl);\n line-height: var(--tw-leading, var(--text-xl--line-height));\n }\n .text-xs {\n font-size: var(--text-xs);\n line-height: var(--tw-leading, var(--text-xs--line-height));\n }\n .text-\\[10px\\] {\n font-size: 10px;\n }\n .font-bold {\n --tw-font-weight: var(--font-weight-bold);\n font-weight: var(--font-weight-bold);\n }\n .font-medium {\n --tw-font-weight: var(--font-weight-medium);\n font-weight: var(--font-weight-medium);\n }\n .font-semibold {\n --tw-font-weight: var(--font-weight-semibold);\n font-weight: var(--font-weight-semibold);\n }\n .tracking-wide {\n --tw-tracking: var(--tracking-wide);\n letter-spacing: var(--tracking-wide);\n }\n .tracking-widest {\n --tw-tracking: var(--tracking-widest);\n letter-spacing: var(--tracking-widest);\n }\n .text-white {\n color: var(--color-white);\n }\n .uppercase {\n text-transform: uppercase;\n }\n .shadow-lg {\n --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow:\n var(--tw-inset-shadow),\n var(--tw-inset-ring-shadow),\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow);\n }\n .filter {\n filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);\n }\n .md\\:rounded-2xl {\n @media (width >= 48rem) {\n border-radius: var(--radius-2xl);\n }\n }\n .md\\:rounded-2xl\\! {\n @media (width >= 48rem) {\n border-radius: var(--radius-2xl) !important;\n }\n }\n .md\\:text-base {\n @media (width >= 48rem) {\n font-size: var(--text-base);\n line-height: var(--tw-leading, var(--text-base--line-height));\n }\n }\n .md\\:text-sm {\n @media (width >= 48rem) {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n }\n .md\\:text-xl {\n @media (width >= 48rem) {\n font-size: var(--text-xl);\n line-height: var(--tw-leading, var(--text-xl--line-height));\n }\n }\n}\n@layer components {\n .motto-video-container {\n position: relative;\n width: 100%;\n min-height: 300px;\n }\n @supports (aspect-ratio: 16/9) {\n .motto-video-container {\n min-height: auto;\n }\n }\n .motto-video-responsive {\n position: absolute;\n top: calc(var(--spacing) * 0);\n left: calc(var(--spacing) * 0);\n height: 100%;\n width: 100%;\n }\n .motto-skip-button {\n position: absolute;\n top: calc(1/2 * 100%);\n z-index: 10;\n display: flex;\n height: calc(var(--spacing) * 16);\n width: calc(var(--spacing) * 16);\n --tw-translate-y: calc(calc(1/2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n cursor: pointer;\n align-items: center;\n justify-content: center;\n border-radius: calc(infinity * 1px);\n border-style: var(--tw-border-style);\n border-width: 0px;\n background-color: color-mix(in srgb, #000 70%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 70%, transparent);\n }\n font-size: var(--text-2xl);\n line-height: var(--tw-leading, var(--text-2xl--line-height));\n color: var(--color-white);\n opacity: 80%;\n transition-property: all;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n --tw-duration: 200ms;\n transition-duration: 200ms;\n &:hover {\n @media (hover: hover) {\n --tw-scale-x: 110%;\n --tw-scale-y: 110%;\n --tw-scale-z: 110%;\n scale: var(--tw-scale-x) var(--tw-scale-y);\n }\n }\n &:hover {\n @media (hover: hover) {\n opacity: 100%;\n }\n }\n &:active {\n --tw-scale-x: 95%;\n --tw-scale-y: 95%;\n --tw-scale-z: 95%;\n scale: var(--tw-scale-x) var(--tw-scale-y);\n }\n }\n .motto-skip-button-back {\n left: calc(var(--spacing) * 5);\n }\n .motto-skip-button-forward {\n right: calc(var(--spacing) * 5);\n }\n .motto-mobile-controls-overlay {\n position: absolute;\n inset: calc(var(--spacing) * 0);\n z-index: 20;\n display: flex;\n align-items: center;\n justify-content: center;\n transition-property: opacity;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n --tw-duration: 300ms;\n transition-duration: 300ms;\n pointer-events: none;\n }\n .motto-mobile-controls-group {\n display: flex;\n align-items: center;\n gap: calc(var(--spacing) * 8);\n opacity: 100%;\n transition-property: all;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n --tw-duration: 200ms;\n transition-duration: 200ms;\n pointer-events: none;\n }\n .motto-mobile-play-button {\n display: flex;\n height: calc(var(--spacing) * 14);\n width: calc(var(--spacing) * 14);\n cursor: pointer;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n border-radius: calc(infinity * 1px);\n border-style: var(--tw-border-style);\n border-width: 0px;\n background-color: color-mix(in srgb, #000 30%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 30%, transparent);\n }\n color: var(--color-white);\n --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow:\n var(--tw-inset-shadow),\n var(--tw-inset-ring-shadow),\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow);\n transition-property: all;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n --tw-duration: 200ms;\n transition-duration: 200ms;\n pointer-events: auto;\n }\n .motto-mobile-play-button:active {\n --tw-scale-x: 95%;\n --tw-scale-y: 95%;\n --tw-scale-z: 95%;\n scale: var(--tw-scale-x) var(--tw-scale-y);\n }\n .motto-mobile-play-button svg {\n height: calc(var(--spacing) * 7);\n width: calc(var(--spacing) * 7);\n }\n .motto-mobile-skip-button {\n display: flex;\n height: calc(var(--spacing) * 10);\n width: calc(var(--spacing) * 10);\n cursor: pointer;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n border-radius: calc(infinity * 1px);\n border-style: var(--tw-border-style);\n border-width: 0px;\n background-color: color-mix(in srgb, #000 30%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 30%, transparent);\n }\n color: var(--color-white);\n --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow:\n var(--tw-inset-shadow),\n var(--tw-inset-ring-shadow),\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow);\n transition-property: all;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n --tw-duration: 200ms;\n transition-duration: 200ms;\n pointer-events: auto;\n }\n .motto-mobile-skip-button:active {\n --tw-scale-x: 95%;\n --tw-scale-y: 95%;\n --tw-scale-z: 95%;\n scale: var(--tw-scale-x) var(--tw-scale-y);\n }\n .motto-mobile-skip-button svg {\n height: calc(var(--spacing) * 6);\n width: calc(var(--spacing) * 6);\n }\n}\n@media (min-width: 768px) {\n .motto-mobile-controls-overlay {\n display: none !important;\n }\n}\n@media (max-width: 767px) {\n .shaka-controls-container .motto-native-skip-button,\n .shaka-controls-container .motto-skip-back-button,\n .shaka-controls-container .motto-skip-forward-button,\n .shaka-controls-container .shaka-button[title*="Skip back"],\n .shaka-controls-container .shaka-button[title*="Skip forward"],\n .shaka-controls-container .shaka-button[aria-label*="Skip back"],\n .shaka-controls-container .shaka-button[aria-label*="Skip forward"],\n .shaka-controls-container button[title*="Skip back"],\n .shaka-controls-container button[title*="Skip forward"],\n .shaka-controls-container button[aria-label*="Skip back"],\n .shaka-controls-container button[aria-label*="Skip forward"],\n .motto-native-skip-button:not(.motto-mobile-skip-button),\n .motto-skip-back-button:not(.motto-mobile-skip-button),\n .motto-skip-forward-button:not(.motto-mobile-skip-button),\n .shaka-button[title*="Skip back"]:not(.motto-mobile-skip-button),\n .shaka-button[title*="Skip forward"]:not(.motto-mobile-skip-button),\n .shaka-button[aria-label*="Skip back"]:not(.motto-mobile-skip-button),\n .shaka-button[aria-label*="Skip forward"]:not(.motto-mobile-skip-button),\n button[title*="Skip back"]:not(.motto-mobile-skip-button),\n button[title*="Skip forward"]:not(.motto-mobile-skip-button),\n button[aria-label*="Skip back"]:not(.motto-mobile-skip-button),\n button[aria-label*="Skip forward"]:not(.motto-mobile-skip-button) {\n display: none !important;\n visibility: hidden !important;\n opacity: 0 !important;\n width: 0 !important;\n height: 0 !important;\n padding: 0 !important;\n margin: 0 !important;\n }\n .motto-mobile-skip-button {\n display: flex !important;\n visibility: visible !important;\n opacity: 1 !important;\n }\n}\n.shaka-seek-bar-container {\n height: 6px !important;\n width: 100% !important;\n margin: 8px 0 !important;\n border-radius: 4px !important;\n position: relative !important;\n border-top: none !important;\n border-bottom: none !important;\n box-shadow: none !important;\n}\n.shaka-seek-bar {\n height: 6px !important;\n width: 100% !important;\n -webkit-appearance: none !important;\n appearance: none !important;\n background: transparent !important;\n cursor: pointer !important;\n border: none !important;\n outline: none !important;\n position: absolute !important;\n top: 0 !important;\n left: 0 !important;\n border-radius: 4px !important;\n}\n.shaka-seek-bar::-webkit-slider-runnable-track {\n height: 6px !important;\n background: transparent !important;\n border-radius: 4px !important;\n border: none !important;\n}\n.shaka-seek-bar::-moz-range-track {\n height: 6px !important;\n background: transparent !important;\n border-radius: 4px !important;\n border: none !important;\n}\n.shaka-seek-bar::-webkit-slider-thumb {\n -webkit-appearance: none !important;\n appearance: none !important;\n width: 16px !important;\n height: 16px !important;\n border-radius: 50% !important;\n background: #ffffff !important;\n cursor: pointer !important;\n border: 2px solid #ffffff !important;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3) !important;\n margin-top: -4px !important;\n}\n.shaka-seek-bar::-moz-range-thumb {\n width: 16px !important;\n height: 16px !important;\n border-radius: 50% !important;\n background: #ffffff !important;\n cursor: pointer !important;\n border: 2px solid #ffffff !important;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3) !important;\n margin-top: -4px !important;\n}\n.motto-skip-back-button,\n.motto-skip-forward-button,\n.motto-native-skip-button {\n background: transparent !important;\n border: none !important;\n padding: 4px !important;\n margin: 0px !important;\n cursor: pointer !important;\n color: #ffffff !important;\n transition: all 0.2s ease !important;\n min-width: 32px !important;\n height: 32px !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n border-radius: 4px !important;\n width: 25px;\n}\n.motto-skip-back-button:hover,\n.motto-skip-forward-button:hover,\n.motto-native-skip-button:hover {\n opacity: 0.8 !important;\n background: transparent !important;\n transform: scale(1.05) !important;\n}\n.motto-skip-back-button:active,\n.motto-skip-forward-button:active,\n.motto-native-skip-button:active {\n transform: scale(0.95) !important;\n}\n.motto-skip-back-button svg,\n.motto-skip-forward-button svg,\n.motto-native-skip-button svg {\n width: 24px !important;\n height: 24px !important;\n}\n@media (max-width: 767px) {\n .shaka-controls-container .motto-native-skip-button,\n .shaka-controls-container .motto-skip-back-button,\n .shaka-controls-container .motto-skip-forward-button,\n .shaka-controls-container .shaka-play-button,\n .shaka-controls-container .shaka-pause-button {\n display: none !important;\n }\n}\n.shaka-spinner-svg {\n color: white !important;\n fill: white !important;\n}\n.shaka-spinner-path {\n stroke: white !important;\n fill: none !important;\n}\n.shaka-spinner-container {\n color: white !important;\n}\n.shaka-buffering-spinner {\n color: white !important;\n fill: white !important;\n}\n.shaka-buffering-spinner svg {\n color: white !important;\n fill: white !important;\n}\n.shaka-buffering-spinner path {\n stroke: white !important;\n fill: none !important;\n}\n[data-shaka-player-container] .shaka-spinner,\n[data-shaka-player-container] .spinner {\n color: white !important;\n border-color: white !important;\n}\n.material-icons.shaka-spinner {\n color: white !important;\n}\n.shaka-controls-container .shaka-spinner,\n.shaka-video-container .shaka-spinner {\n color: white !important;\n fill: white !important;\n}\n.shaka-controls-container .shaka-spinner svg,\n.shaka-video-container .shaka-spinner svg {\n color: white !important;\n fill: white !important;\n}\n.shaka-controls-container .shaka-spinner path,\n.shaka-video-container .shaka-spinner path {\n stroke: white !important;\n}\n.motto-video-loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background:\n linear-gradient(\n 135deg,\n #1a1a1a 0%,\n #2d2d2d 100%);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n z-index: 10;\n transition: opacity 0.3s ease;\n}\n.motto-video-loading-overlay.hidden {\n opacity: 0;\n pointer-events: none;\n}\n.motto-video-loading-content {\n text-align: center;\n color: white;\n}\n.motto-video-loading-icon {\n width: 64px;\n height: 64px;\n margin-bottom: 16px;\n opacity: 0.7;\n}\n.motto-video-loading-text {\n font-size: 16px;\n font-weight: 500;\n margin-bottom: 8px;\n}\n.motto-video-loading-subtext {\n font-size: 14px;\n opacity: 0.7;\n}\n@keyframes pulse-live {\n 0% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.7;\n transform: scale(1.1);\n }\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n}\n.shaka-play-button-container {\n display: none !important;\n}\n@media (max-width: 767px) {\n .shaka-controls-container {\n z-index: 90 !important;\n height: 100px !important;\n bottom: 0 !important;\n top: unset !important;\n }\n}\n@property --tw-gradient-position { syntax: "*"; inherits: false; }\n@property --tw-gradient-from { syntax: "<color>"; inherits: false; initial-value: #0000; }\n@property --tw-gradient-via { syntax: "<color>"; inherits: false; initial-value: #0000; }\n@property --tw-gradient-to { syntax: "<color>"; inherits: false; initial-value: #0000; }\n@property --tw-gradient-stops { syntax: "*"; inherits: false; }\n@property --tw-gradient-via-stops { syntax: "*"; inherits: false; }\n@property --tw-gradient-from-position { syntax: "<length-percentage>"; inherits: false; initial-value: 0%; }\n@property --tw-gradient-via-position { syntax: "<length-percentage>"; inherits: false; initial-value: 50%; }\n@property --tw-gradient-to-position { syntax: "<length-percentage>"; inherits: false; initial-value: 100%; }\n@property --tw-font-weight { syntax: "*"; inherits: false; }\n@property --tw-tracking { syntax: "*"; inherits: false; }\n@property --tw-shadow { syntax: "*"; inherits: false; initial-value: 0 0 #0000; }\n@property --tw-shadow-color { syntax: "*"; inherits: false; }\n@property --tw-shadow-alpha { syntax: "<percentage>"; inherits: false; initial-value: 100%; }\n@property --tw-inset-shadow { syntax: "*"; inherits: false; initial-value: 0 0 #0000; }\n@property --tw-inset-shadow-color { syntax: "*"; inherits: false; }\n@property --tw-inset-shadow-alpha { syntax: "<percentage>"; inherits: false; initial-value: 100%; }\n@property --tw-ring-color { syntax: "*"; inherits: false; }\n@property --tw-ring-shadow { syntax: "*"; inherits: false; initial-value: 0 0 #0000; }\n@property --tw-inset-ring-color { syntax: "*"; inherits: false; }\n@property --tw-inset-ring-shadow { syntax: "*"; inherits: false; initial-value: 0 0 #0000; }\n@property --tw-ring-inset { syntax: "*"; inherits: false; }\n@property --tw-ring-offset-width { syntax: "<length>"; inherits: false; initial-value: 0px; }\n@property --tw-ring-offset-color { syntax: "*"; inherits: false; initial-value: #fff; }\n@property --tw-ring-offset-shadow { syntax: "*"; inherits: false; initial-value: 0 0 #0000; }\n@property --tw-blur { syntax: "*"; inherits: false; }\n@property --tw-brightness { syntax: "*"; inherits: false; }\n@property --tw-contrast { syntax: "*"; inherits: false; }\n@property --tw-grayscale { syntax: "*"; inherits: false; }\n@property --tw-hue-rotate { syntax: "*"; inherits: false; }\n@property --tw-invert { syntax: "*"; inherits: false; }\n@property --tw-opacity { syntax: "*"; inherits: false; }\n@property --tw-saturate { syntax: "*"; inherits: false; }\n@property --tw-sepia { syntax: "*"; inherits: false; }\n@property --tw-drop-shadow { syntax: "*"; inherits: false; }\n@property --tw-drop-shadow-color { syntax: "*"; inherits: false; }\n@property --tw-drop-shadow-alpha { syntax: "<percentage>"; inherits: false; initial-value: 100%; }\n@property --tw-drop-shadow-size { syntax: "*"; inherits: false; }\n@property --tw-translate-x { syntax: "*"; inherits: false; initial-value: 0; }\n@property --tw-translate-y { syntax: "*"; inherits: false; initial-value: 0; }\n@property --tw-translate-z { syntax: "*"; inherits: false; initial-value: 0; }\n@property --tw-border-style { syntax: "*"; inherits: false; initial-value: solid; }\n@property --tw-duration { syntax: "*"; inherits: false; }\n@property --tw-scale-x { syntax: "*"; inherits: false; initial-value: 1; }\n@property --tw-scale-y { syntax: "*"; inherits: false; initial-value: 1; }\n@property --tw-scale-z { syntax: "*"; inherits: false; initial-value: 1; }\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n@keyframes pulse {\n 50% {\n opacity: 0.5;\n }\n}\n@layer properties {\n @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {\n *,\n ::before,\n ::after,\n ::backdrop {\n --tw-gradient-position: initial;\n --tw-gradient-from: #0000;\n --tw-gradient-via: #0000;\n --tw-gradient-to: #0000;\n --tw-gradient-stops: initial;\n --tw-gradient-via-stops: initial;\n --tw-gradient-from-position: 0%;\n --tw-gradient-via-position: 50%;\n --tw-gradient-to-position: 100%;\n --tw-font-weight: initial;\n --tw-tracking: initial;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-blur: initial;\n --tw-brightness: initial;\n --tw-contrast: initial;\n --tw-grayscale: initial;\n --tw-hue-rotate: initial;\n --tw-invert: initial;\n --tw-opacity: initial;\n --tw-saturate: initial;\n --tw-sepia: initial;\n --tw-drop-shadow: initial;\n --tw-drop-shadow-color: initial;\n --tw-drop-shadow-alpha: 100%;\n --tw-drop-shadow-size: initial;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-translate-z: 0;\n --tw-border-style: solid;\n --tw-duration: initial;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-scale-z: 1;\n }\n }\n}\n');
|
|
68
68
|
|
|
69
69
|
// src/Player.tsx
|
|
70
|
-
var
|
|
70
|
+
var import_react11 = require("react");
|
|
71
71
|
var import_shaka_player4 = __toESM(require("shaka-player/dist/shaka-player.ui"));
|
|
72
72
|
|
|
73
73
|
// src/hooks/useShakePlayer.ts
|
|
@@ -158,11 +158,25 @@ var useQualityControl = (playerRef, qualityConfig, onQualityChange) => {
|
|
|
158
158
|
if (!playerRef.current) return;
|
|
159
159
|
if (height === 0) {
|
|
160
160
|
playerRef.current.configure({
|
|
161
|
-
abr: {
|
|
161
|
+
abr: {
|
|
162
|
+
enabled: true,
|
|
163
|
+
switchInterval: 2,
|
|
164
|
+
// quicker re-checks
|
|
165
|
+
clearBufferSwitch: true,
|
|
166
|
+
safeMarginSwitch: 10
|
|
167
|
+
// leave ~10 s in front of the playhead }
|
|
168
|
+
}
|
|
162
169
|
});
|
|
163
170
|
} else {
|
|
164
171
|
playerRef.current.configure({
|
|
165
|
-
abr: {
|
|
172
|
+
abr: {
|
|
173
|
+
enabled: false,
|
|
174
|
+
switchInterval: 2,
|
|
175
|
+
// quicker re-checks
|
|
176
|
+
clearBufferSwitch: true,
|
|
177
|
+
safeMarginSwitch: 10
|
|
178
|
+
// leave ~10 s in front of the playhead }
|
|
179
|
+
}
|
|
166
180
|
});
|
|
167
181
|
const tracks = playerRef.current.getVariantTracks();
|
|
168
182
|
const targetTrack = tracks.find((track) => track.height === height);
|
|
@@ -589,6 +603,7 @@ var MobileControlsContainerFactory = class {
|
|
|
589
603
|
};
|
|
590
604
|
var useShakaUI = (playerRef, containerRef, videoRef, controls, chromecastConfig, seekbarColors, onSkipBack, onSkipForward) => {
|
|
591
605
|
const uiRef = (0, import_react5.useRef)(null);
|
|
606
|
+
const mobileOverlayRef = (0, import_react5.useRef)(null);
|
|
592
607
|
const registeredElements = (0, import_react5.useRef)(/* @__PURE__ */ new Set());
|
|
593
608
|
const initializeUI = (0, import_react5.useCallback)(async () => {
|
|
594
609
|
if (!controls || !containerRef.current || !playerRef.current || !videoRef.current) {
|
|
@@ -660,7 +675,14 @@ var useShakaUI = (playerRef, containerRef, videoRef, controls, chromecastConfig,
|
|
|
660
675
|
const container = containerRef.current;
|
|
661
676
|
const video = videoRef.current;
|
|
662
677
|
if (container && video) {
|
|
663
|
-
|
|
678
|
+
if (!mobileOverlayRef.current) {
|
|
679
|
+
mobileOverlayRef.current = new MobileControlsContainer(
|
|
680
|
+
container,
|
|
681
|
+
{ getVideo: () => video },
|
|
682
|
+
onSkipBack,
|
|
683
|
+
onSkipForward
|
|
684
|
+
);
|
|
685
|
+
}
|
|
664
686
|
}
|
|
665
687
|
}, 500);
|
|
666
688
|
}
|
|
@@ -675,6 +697,14 @@ var useShakaUI = (playerRef, containerRef, videoRef, controls, chromecastConfig,
|
|
|
675
697
|
}
|
|
676
698
|
uiRef.current = null;
|
|
677
699
|
}
|
|
700
|
+
if (mobileOverlayRef.current) {
|
|
701
|
+
try {
|
|
702
|
+
mobileOverlayRef.current.release();
|
|
703
|
+
} catch (error) {
|
|
704
|
+
console.warn("Error releasing mobile controls overlay:", error);
|
|
705
|
+
}
|
|
706
|
+
mobileOverlayRef.current = null;
|
|
707
|
+
}
|
|
678
708
|
}, []);
|
|
679
709
|
return {
|
|
680
710
|
uiRef,
|
|
@@ -859,12 +889,10 @@ var useLiveIndicator = (containerRef, options = {}) => {
|
|
|
859
889
|
characterData: true,
|
|
860
890
|
characterDataOldValue: true
|
|
861
891
|
});
|
|
862
|
-
const intervalId = setInterval(checkForLiveContent, 1e3);
|
|
863
892
|
return () => {
|
|
864
893
|
if (observerRef.current) {
|
|
865
894
|
observerRef.current.disconnect();
|
|
866
895
|
}
|
|
867
|
-
clearInterval(intervalId);
|
|
868
896
|
};
|
|
869
897
|
}, [containerRef, enabled, indicatorColor, indicatorSize, showPulseAnimation]);
|
|
870
898
|
return {
|
|
@@ -880,6 +908,51 @@ var useLiveIndicator = (containerRef, options = {}) => {
|
|
|
880
908
|
};
|
|
881
909
|
};
|
|
882
910
|
|
|
911
|
+
// src/hooks/useKeyboardControls.ts
|
|
912
|
+
var import_react10 = require("react");
|
|
913
|
+
var useKeyboardControls = (videoRef, options = {}) => {
|
|
914
|
+
const { skipBack, skipForward, enabled = true } = options;
|
|
915
|
+
const isDesktop = (0, import_react10.useCallback)(() => {
|
|
916
|
+
return window.innerWidth > 767 && !/Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
|
917
|
+
}, []);
|
|
918
|
+
const handleKeydown = (0, import_react10.useCallback)((event) => {
|
|
919
|
+
if (!enabled || !isDesktop() || !videoRef.current) return;
|
|
920
|
+
const activeElement = document.activeElement;
|
|
921
|
+
if (activeElement && (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA" || activeElement.isContentEditable)) {
|
|
922
|
+
return;
|
|
923
|
+
}
|
|
924
|
+
switch (event.key) {
|
|
925
|
+
case "ArrowLeft":
|
|
926
|
+
event.preventDefault();
|
|
927
|
+
skipBack?.();
|
|
928
|
+
break;
|
|
929
|
+
case "ArrowRight":
|
|
930
|
+
event.preventDefault();
|
|
931
|
+
skipForward?.();
|
|
932
|
+
break;
|
|
933
|
+
case " ":
|
|
934
|
+
case "Space":
|
|
935
|
+
event.preventDefault();
|
|
936
|
+
if (videoRef.current.paused) {
|
|
937
|
+
videoRef.current.play();
|
|
938
|
+
} else {
|
|
939
|
+
videoRef.current.pause();
|
|
940
|
+
}
|
|
941
|
+
break;
|
|
942
|
+
}
|
|
943
|
+
}, [enabled, videoRef, skipBack, skipForward, isDesktop]);
|
|
944
|
+
(0, import_react10.useEffect)(() => {
|
|
945
|
+
if (!enabled || !isDesktop()) return;
|
|
946
|
+
document.addEventListener("keydown", handleKeydown);
|
|
947
|
+
return () => {
|
|
948
|
+
document.removeEventListener("keydown", handleKeydown);
|
|
949
|
+
};
|
|
950
|
+
}, [handleKeydown, enabled, isDesktop]);
|
|
951
|
+
return {
|
|
952
|
+
isDesktop: isDesktop()
|
|
953
|
+
};
|
|
954
|
+
};
|
|
955
|
+
|
|
883
956
|
// src/components/Loading.tsx
|
|
884
957
|
var import_tailwind_merge = require("tailwind-merge");
|
|
885
958
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -996,7 +1069,7 @@ styleInject('/*! tailwindcss v4.1.8 | MIT License | https://tailwindcss.com */\n
|
|
|
996
1069
|
// src/Player.tsx
|
|
997
1070
|
var import_tailwind_merge2 = require("tailwind-merge");
|
|
998
1071
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
999
|
-
var Player = (0,
|
|
1072
|
+
var Player = (0, import_react11.forwardRef)(
|
|
1000
1073
|
({
|
|
1001
1074
|
src,
|
|
1002
1075
|
autoPlay = false,
|
|
@@ -1016,12 +1089,12 @@ var Player = (0, import_react10.forwardRef)(
|
|
|
1016
1089
|
seekbarConfig,
|
|
1017
1090
|
events,
|
|
1018
1091
|
containerClassName,
|
|
1019
|
-
...
|
|
1092
|
+
...videoProps
|
|
1020
1093
|
}, ref) => {
|
|
1021
|
-
const videoRef = (0,
|
|
1022
|
-
const containerRef = (0,
|
|
1023
|
-
const adContainerRef = (0,
|
|
1024
|
-
(0,
|
|
1094
|
+
const videoRef = (0, import_react11.useRef)(null);
|
|
1095
|
+
const containerRef = (0, import_react11.useRef)(null);
|
|
1096
|
+
const adContainerRef = (0, import_react11.useRef)(null);
|
|
1097
|
+
(0, import_react11.useImperativeHandle)(ref, () => videoRef.current, []);
|
|
1025
1098
|
const { playerRef, initializePlayer, destroyPlayer } = useShakePlayer({
|
|
1026
1099
|
src,
|
|
1027
1100
|
shakaConfig,
|
|
@@ -1041,6 +1114,11 @@ var Player = (0, import_react10.forwardRef)(
|
|
|
1041
1114
|
skipDuration,
|
|
1042
1115
|
shouldShowSkipControls
|
|
1043
1116
|
} = useSkipControls(videoRef, events?.onSkipBack, events?.onSkipForward);
|
|
1117
|
+
useKeyboardControls(videoRef, {
|
|
1118
|
+
skipBack,
|
|
1119
|
+
skipForward,
|
|
1120
|
+
enabled: true
|
|
1121
|
+
});
|
|
1044
1122
|
const {
|
|
1045
1123
|
initializeMux,
|
|
1046
1124
|
updateMuxData,
|
|
@@ -1116,7 +1194,7 @@ var Player = (0, import_react10.forwardRef)(
|
|
|
1116
1194
|
console.warn("Chromecast initialization failed:", error);
|
|
1117
1195
|
}
|
|
1118
1196
|
};
|
|
1119
|
-
(0,
|
|
1197
|
+
(0, import_react11.useEffect)(() => {
|
|
1120
1198
|
const video = videoRef.current;
|
|
1121
1199
|
if (!video) return;
|
|
1122
1200
|
const initialize = async () => {
|
|
@@ -1142,7 +1220,7 @@ var Player = (0, import_react10.forwardRef)(
|
|
|
1142
1220
|
destroyPlayer();
|
|
1143
1221
|
};
|
|
1144
1222
|
}, [src]);
|
|
1145
|
-
(0,
|
|
1223
|
+
(0, import_react11.useEffect)(() => {
|
|
1146
1224
|
const video = videoRef.current;
|
|
1147
1225
|
if (!video) return;
|
|
1148
1226
|
video.autoplay = autoPlay;
|
|
@@ -1151,7 +1229,14 @@ var Player = (0, import_react10.forwardRef)(
|
|
|
1151
1229
|
video.controls = false;
|
|
1152
1230
|
if (poster) video.poster = poster;
|
|
1153
1231
|
}, [autoPlay, loop, muted, poster]);
|
|
1154
|
-
(0,
|
|
1232
|
+
(0, import_react11.useEffect)(() => {
|
|
1233
|
+
const video = videoRef.current;
|
|
1234
|
+
if (!video) return;
|
|
1235
|
+
video.controls = false;
|
|
1236
|
+
video.setAttribute("controls", "false");
|
|
1237
|
+
video.removeAttribute("controls");
|
|
1238
|
+
}, []);
|
|
1239
|
+
(0, import_react11.useImperativeHandle)(ref, () => ({
|
|
1155
1240
|
...videoRef.current,
|
|
1156
1241
|
// Custom methods for quality control
|
|
1157
1242
|
getAvailableQualities,
|
|
@@ -1172,6 +1257,8 @@ var Player = (0, import_react10.forwardRef)(
|
|
|
1172
1257
|
} : { width, height };
|
|
1173
1258
|
const videoClasses = isResponsive ? "motto-video-responsive" : "w-full h-full ";
|
|
1174
1259
|
const videoStyle = isResponsive ? {} : { width, height };
|
|
1260
|
+
const filteredVideoProps = { ...videoProps };
|
|
1261
|
+
delete filteredVideoProps.controls;
|
|
1175
1262
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1176
1263
|
"div",
|
|
1177
1264
|
{
|
|
@@ -1190,7 +1277,7 @@ var Player = (0, import_react10.forwardRef)(
|
|
|
1190
1277
|
height: isResponsive ? void 0 : height,
|
|
1191
1278
|
style: videoStyle,
|
|
1192
1279
|
controls: false,
|
|
1193
|
-
...
|
|
1280
|
+
...filteredVideoProps
|
|
1194
1281
|
}
|
|
1195
1282
|
),
|
|
1196
1283
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(LiveBadge, { isVisible: isLiveBadgeVisible }),
|
|
@@ -1209,7 +1296,7 @@ var Player = (0, import_react10.forwardRef)(
|
|
|
1209
1296
|
Player.displayName = "Player";
|
|
1210
1297
|
|
|
1211
1298
|
// src/Video.tsx
|
|
1212
|
-
var
|
|
1299
|
+
var import_react13 = require("react");
|
|
1213
1300
|
var import_tailwind_merge3 = require("tailwind-merge");
|
|
1214
1301
|
var import_react_query = require("@tanstack/react-query");
|
|
1215
1302
|
|
|
@@ -1350,7 +1437,7 @@ var getErrorType = (error, video) => {
|
|
|
1350
1437
|
};
|
|
1351
1438
|
|
|
1352
1439
|
// src/messages/useMessages.tsx
|
|
1353
|
-
var
|
|
1440
|
+
var import_react12 = require("react");
|
|
1354
1441
|
|
|
1355
1442
|
// src/messages/en.json
|
|
1356
1443
|
var en_default = {
|
|
@@ -1652,9 +1739,9 @@ var getBrowserLanguage = () => {
|
|
|
1652
1739
|
return availableLanguages[language] ? language : "en";
|
|
1653
1740
|
};
|
|
1654
1741
|
var useMessages = (locale) => {
|
|
1655
|
-
const [language, setLanguage] = (0,
|
|
1656
|
-
const [translations, setTranslations] = (0,
|
|
1657
|
-
(0,
|
|
1742
|
+
const [language, setLanguage] = (0, import_react12.useState)("en");
|
|
1743
|
+
const [translations, setTranslations] = (0, import_react12.useState)(availableLanguages.en);
|
|
1744
|
+
(0, import_react12.useEffect)(() => {
|
|
1658
1745
|
const lang = !!availableLanguages?.[locale] ? locale : getBrowserLanguage();
|
|
1659
1746
|
;
|
|
1660
1747
|
setLanguage(lang);
|
|
@@ -1716,7 +1803,7 @@ var Video = ({
|
|
|
1716
1803
|
const { t } = useMessages_default(locale);
|
|
1717
1804
|
const activePlaylist = findHLSPlaylist(video);
|
|
1718
1805
|
const hlsUrl = activePlaylist?.url;
|
|
1719
|
-
(0,
|
|
1806
|
+
(0, import_react13.useEffect)(() => {
|
|
1720
1807
|
if (events?.onVideoData && video) {
|
|
1721
1808
|
events.onVideoData(video);
|
|
1722
1809
|
}
|
|
@@ -1767,7 +1854,7 @@ var Video = ({
|
|
|
1767
1854
|
};
|
|
1768
1855
|
|
|
1769
1856
|
// src/Event.tsx
|
|
1770
|
-
var
|
|
1857
|
+
var import_react14 = require("react");
|
|
1771
1858
|
var import_tailwind_merge4 = require("tailwind-merge");
|
|
1772
1859
|
var import_react_query2 = require("@tanstack/react-query");
|
|
1773
1860
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
@@ -1800,8 +1887,8 @@ var Event = ({
|
|
|
1800
1887
|
retry: queryOptions.retry ?? 3,
|
|
1801
1888
|
retryDelay: queryOptions.retryDelay ?? ((attemptIndex) => Math.min(1e3 * 2 ** attemptIndex, 3e4))
|
|
1802
1889
|
});
|
|
1803
|
-
const [activePlaylist, setActivePlaylist] = (0,
|
|
1804
|
-
const [activeVideoId, setActiveVideoId] = (0,
|
|
1890
|
+
const [activePlaylist, setActivePlaylist] = (0, import_react14.useState)();
|
|
1891
|
+
const [activeVideoId, setActiveVideoId] = (0, import_react14.useState)();
|
|
1805
1892
|
const videoIds = eventData?.videoIds ?? [];
|
|
1806
1893
|
const {
|
|
1807
1894
|
data: videosData,
|
|
@@ -1817,8 +1904,8 @@ var Event = ({
|
|
|
1817
1904
|
retry: queryOptions.retry ?? 3,
|
|
1818
1905
|
retryDelay: queryOptions.retryDelay ?? ((attemptIndex) => Math.min(1e3 * 2 ** attemptIndex, 3e4))
|
|
1819
1906
|
});
|
|
1820
|
-
const [loadingApisState, setLoadingApisState] = (0,
|
|
1821
|
-
(0,
|
|
1907
|
+
const [loadingApisState, setLoadingApisState] = (0, import_react14.useState)(true);
|
|
1908
|
+
(0, import_react14.useEffect)(() => {
|
|
1822
1909
|
if (videosData !== void 0) {
|
|
1823
1910
|
setLoadingApisState(false);
|
|
1824
1911
|
const videosWithPlaylists = videosData.filter(
|
|
@@ -1850,12 +1937,12 @@ var Event = ({
|
|
|
1850
1937
|
}
|
|
1851
1938
|
}, [videosData, eventData]);
|
|
1852
1939
|
const { t } = useMessages_default(locale);
|
|
1853
|
-
(0,
|
|
1940
|
+
(0, import_react14.useEffect)(() => {
|
|
1854
1941
|
if (events?.onEventData && eventData) {
|
|
1855
1942
|
events.onEventData(eventData);
|
|
1856
1943
|
}
|
|
1857
1944
|
}, [eventData, events]);
|
|
1858
|
-
(0,
|
|
1945
|
+
(0, import_react14.useEffect)(() => {
|
|
1859
1946
|
if (events?.onVideoData && activeVideoId && videosData) {
|
|
1860
1947
|
const activeVideo = videosData.find((video) => video.id === activeVideoId);
|
|
1861
1948
|
if (activeVideo) {
|
|
@@ -1863,10 +1950,10 @@ var Event = ({
|
|
|
1863
1950
|
}
|
|
1864
1951
|
}
|
|
1865
1952
|
}, [activeVideoId, videosData, events]);
|
|
1866
|
-
const [error, setError] = (0,
|
|
1867
|
-
const [loadingPlaylist, setLoadingPlaylist] = (0,
|
|
1953
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
1954
|
+
const [loadingPlaylist, setLoadingPlaylist] = (0, import_react14.useState)(true);
|
|
1868
1955
|
const videosDataError = videosData?.some((video) => !!video.error);
|
|
1869
|
-
(0,
|
|
1956
|
+
(0, import_react14.useEffect)(() => {
|
|
1870
1957
|
if (eventError || videosError || videosDataError) {
|
|
1871
1958
|
const errorObj = eventError || videosError || videosData?.find((video) => !!video.error)?.error && new Error(videosData?.find((video) => !!video.error)?.error) || new Error("default");
|
|
1872
1959
|
setError(errorObj);
|
|
@@ -1877,7 +1964,7 @@ var Event = ({
|
|
|
1877
1964
|
setError(null);
|
|
1878
1965
|
}
|
|
1879
1966
|
}, [eventError, videosError, videosDataError, videosData, events]);
|
|
1880
|
-
(0,
|
|
1967
|
+
(0, import_react14.useEffect)(() => {
|
|
1881
1968
|
const eventLoadedWithNoVideos = !isEventLoading && eventData && eventData.videoIds && (!eventData.videoIds || eventData?.videoIds?.length === 0) && !loadingApisState;
|
|
1882
1969
|
const allApisLoadedWithPotentialVideos = !isEventLoading && !videosIsLoading && eventData && !loadingApisState;
|
|
1883
1970
|
if (eventLoadedWithNoVideos || allApisLoadedWithPotentialVideos) {
|
|
@@ -1948,12 +2035,12 @@ function PreEvent({
|
|
|
1948
2035
|
}) {
|
|
1949
2036
|
const date = new Date(event.startTime);
|
|
1950
2037
|
const now = /* @__PURE__ */ new Date();
|
|
1951
|
-
const [remainingTime, setRemainingTime] = (0,
|
|
2038
|
+
const [remainingTime, setRemainingTime] = (0, import_react14.useState)(
|
|
1952
2039
|
date.getTime() - now.getTime()
|
|
1953
2040
|
);
|
|
1954
2041
|
const shouldBeStarted = remainingTime < 0;
|
|
1955
2042
|
const { t } = useMessages_default(locale);
|
|
1956
|
-
(0,
|
|
2043
|
+
(0, import_react14.useEffect)(() => {
|
|
1957
2044
|
const interval = setInterval(() => {
|
|
1958
2045
|
if (remainingTime < 0) {
|
|
1959
2046
|
clearInterval(interval);
|
|
@@ -1963,7 +2050,7 @@ function PreEvent({
|
|
|
1963
2050
|
}, 1e3);
|
|
1964
2051
|
return () => clearInterval(interval);
|
|
1965
2052
|
}, [date, remainingTime]);
|
|
1966
|
-
const renderCountdown = (0,
|
|
2053
|
+
const renderCountdown = (0, import_react14.useCallback)(() => {
|
|
1967
2054
|
if (shouldBeStarted) {
|
|
1968
2055
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-base-content text-xl", children: t("EVENT_NOT_STARTED") });
|
|
1969
2056
|
}
|
|
@@ -2093,7 +2180,7 @@ var TitleAndDescription = ({
|
|
|
2093
2180
|
};
|
|
2094
2181
|
|
|
2095
2182
|
// src/CreativeWork.tsx
|
|
2096
|
-
var
|
|
2183
|
+
var import_react15 = require("react");
|
|
2097
2184
|
var import_tailwind_merge5 = require("tailwind-merge");
|
|
2098
2185
|
var import_react_query3 = require("@tanstack/react-query");
|
|
2099
2186
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
@@ -2126,9 +2213,9 @@ var CreativeWork = ({
|
|
|
2126
2213
|
retry: queryOptions.retry ?? 3,
|
|
2127
2214
|
retryDelay: queryOptions.retryDelay ?? ((attemptIndex) => Math.min(1e3 * 2 ** attemptIndex, 3e4))
|
|
2128
2215
|
});
|
|
2129
|
-
const [activePlaylist, setActivePlaylist] = (0,
|
|
2130
|
-
const [activeVideoId, setActiveVideoId] = (0,
|
|
2131
|
-
const [showCountDown, setShowCountDown] = (0,
|
|
2216
|
+
const [activePlaylist, setActivePlaylist] = (0, import_react15.useState)();
|
|
2217
|
+
const [activeVideoId, setActiveVideoId] = (0, import_react15.useState)();
|
|
2218
|
+
const [showCountDown, setShowCountDown] = (0, import_react15.useState)(false);
|
|
2132
2219
|
const videoIds = creativeWorkData?.videoIds ?? [];
|
|
2133
2220
|
const {
|
|
2134
2221
|
data: videosData,
|
|
@@ -2144,8 +2231,8 @@ var CreativeWork = ({
|
|
|
2144
2231
|
retry: queryOptions.retry ?? 3,
|
|
2145
2232
|
retryDelay: queryOptions.retryDelay ?? ((attemptIndex) => Math.min(1e3 * 2 ** attemptIndex, 3e4))
|
|
2146
2233
|
});
|
|
2147
|
-
const [loadingApisState, setLoadingApisState] = (0,
|
|
2148
|
-
(0,
|
|
2234
|
+
const [loadingApisState, setLoadingApisState] = (0, import_react15.useState)(true);
|
|
2235
|
+
(0, import_react15.useEffect)(() => {
|
|
2149
2236
|
if (videosData !== void 0) {
|
|
2150
2237
|
setLoadingApisState(false);
|
|
2151
2238
|
const videosWithPlaylists = videosData.filter(
|
|
@@ -2177,7 +2264,7 @@ var CreativeWork = ({
|
|
|
2177
2264
|
}
|
|
2178
2265
|
}, [videosData, creativeWorkData]);
|
|
2179
2266
|
const { t } = useMessages_default(locale);
|
|
2180
|
-
(0,
|
|
2267
|
+
(0, import_react15.useEffect)(() => {
|
|
2181
2268
|
if (events?.onCreativeWorkData && creativeWorkData) {
|
|
2182
2269
|
events.onCreativeWorkData(creativeWorkData);
|
|
2183
2270
|
}
|
|
@@ -2185,7 +2272,7 @@ var CreativeWork = ({
|
|
|
2185
2272
|
setShowCountDown(true);
|
|
2186
2273
|
}
|
|
2187
2274
|
}, [creativeWorkData, events]);
|
|
2188
|
-
(0,
|
|
2275
|
+
(0, import_react15.useEffect)(() => {
|
|
2189
2276
|
if (events?.onVideoData && activeVideoId && videosData) {
|
|
2190
2277
|
const activeVideo = videosData.find((video) => video.id === activeVideoId);
|
|
2191
2278
|
if (activeVideo) {
|
|
@@ -2193,9 +2280,9 @@ var CreativeWork = ({
|
|
|
2193
2280
|
}
|
|
2194
2281
|
}
|
|
2195
2282
|
}, [activeVideoId, videosData, events]);
|
|
2196
|
-
const [error, setError] = (0,
|
|
2283
|
+
const [error, setError] = (0, import_react15.useState)(null);
|
|
2197
2284
|
const videosDataError = videosData?.some((video) => !!video.error);
|
|
2198
|
-
(0,
|
|
2285
|
+
(0, import_react15.useEffect)(() => {
|
|
2199
2286
|
if (creativeWorkError || videosError || videosDataError) {
|
|
2200
2287
|
const errorObj = creativeWorkError || videosError || videosData?.find((video) => !!video.error)?.error && new Error(videosData?.find((video) => !!video.error)?.error) || new Error("default");
|
|
2201
2288
|
setError(errorObj);
|
|
@@ -2217,8 +2304,8 @@ var CreativeWork = ({
|
|
|
2217
2304
|
}
|
|
2218
2305
|
) }) });
|
|
2219
2306
|
}
|
|
2220
|
-
const [loadingPlaylist, setLoadingPlaylist] = (0,
|
|
2221
|
-
(0,
|
|
2307
|
+
const [loadingPlaylist, setLoadingPlaylist] = (0, import_react15.useState)(true);
|
|
2308
|
+
(0, import_react15.useEffect)(() => {
|
|
2222
2309
|
const creativeWorkLoadedWithNoVideos = !isCreativeWorkLoading && creativeWorkData && creativeWorkData.videoIds && creativeWorkData.videoIds.length === 0;
|
|
2223
2310
|
const creativeWorkLoadedWithNoData = !isCreativeWorkLoading && creativeWorkData && !creativeWorkData.videoIds;
|
|
2224
2311
|
const isEventsFinished = !videosIsLoading && videosData && videosData.length > 0 && videosData.every((video) => video.playlists && video.playlists.length === 0);
|
|
@@ -2294,12 +2381,12 @@ function PreCreativeWork({
|
|
|
2294
2381
|
}) {
|
|
2295
2382
|
const date = new Date(creativeWork.releaseTime);
|
|
2296
2383
|
const now = /* @__PURE__ */ new Date();
|
|
2297
|
-
const [remainingTime, setRemainingTime] = (0,
|
|
2384
|
+
const [remainingTime, setRemainingTime] = (0, import_react15.useState)(
|
|
2298
2385
|
date.getTime() - now.getTime()
|
|
2299
2386
|
);
|
|
2300
2387
|
const shouldBeStarted = remainingTime < 0;
|
|
2301
2388
|
const { t } = useMessages_default(locale);
|
|
2302
|
-
(0,
|
|
2389
|
+
(0, import_react15.useEffect)(() => {
|
|
2303
2390
|
const interval = setInterval(() => {
|
|
2304
2391
|
if (remainingTime < 0) {
|
|
2305
2392
|
clearInterval(interval);
|