@hubspot/video-player-core 0.1.19
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/LICENSE.md +15 -0
- package/README.md +5 -0
- package/dist/api/utils.d.ts +3 -0
- package/dist/api/utils.d.ts.map +1 -0
- package/dist/api/utils.js +8 -0
- package/dist/api/video.d.ts +9 -0
- package/dist/api/video.d.ts.map +1 -0
- package/dist/api/video.js +22 -0
- package/dist/components/CaptionTracks.d.ts +7 -0
- package/dist/components/CaptionTracks.d.ts.map +1 -0
- package/dist/components/CaptionTracks.js +11 -0
- package/dist/components/HSPlayerIcons.d.ts +12 -0
- package/dist/components/HSPlayerIcons.d.ts.map +1 -0
- package/dist/components/HSPlayerIcons.js +14 -0
- package/dist/components/HSThemeTemplate.d.ts +23 -0
- package/dist/components/HSThemeTemplate.d.ts.map +1 -0
- package/dist/components/HSThemeTemplate.js +94 -0
- package/dist/components/TranslationsProvider.d.ts +13 -0
- package/dist/components/TranslationsProvider.d.ts.map +1 -0
- package/dist/components/TranslationsProvider.js +28 -0
- package/dist/components/VideoFetchProvider.d.ts +22 -0
- package/dist/components/VideoFetchProvider.d.ts.map +1 -0
- package/dist/components/VideoFetchProvider.js +12 -0
- package/dist/components/VideoPlayer.d.ts +13 -0
- package/dist/components/VideoPlayer.d.ts.map +1 -0
- package/dist/components/VideoPlayer.js +51 -0
- package/dist/components/VideoPlayerProvider.d.ts +40 -0
- package/dist/components/VideoPlayerProvider.d.ts.map +1 -0
- package/dist/components/VideoPlayerProvider.js +162 -0
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +8 -0
- package/dist/hooks/useAsyncEffect.d.ts +9 -0
- package/dist/hooks/useAsyncEffect.d.ts.map +1 -0
- package/dist/hooks/useAsyncEffect.js +54 -0
- package/dist/hooks/useSubtitles.d.ts +6 -0
- package/dist/hooks/useSubtitles.d.ts.map +1 -0
- package/dist/hooks/useSubtitles.js +17 -0
- package/dist/hooks/useVideo.d.ts +7 -0
- package/dist/hooks/useVideo.d.ts.map +1 -0
- package/dist/hooks/useVideo.js +17 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/styles/mux-player.css +23 -0
- package/dist/styles/player-theme.css +446 -0
- package/dist/types.d.ts +57 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/utils/i18n.d.ts +43 -0
- package/dist/utils/i18n.d.ts.map +1 -0
- package/dist/utils/i18n.js +79 -0
- package/package.json +49 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { MediaActionTypes, MediaProvider, useMediaDispatch, useMediaSelector,
|
|
3
|
+
// @ts-expect-error cannot resolve - types are incomplete
|
|
4
|
+
} from 'media-chrome/react/media-store';
|
|
5
|
+
import { createContext, useContext, useEffect, useMemo, useRef, useState, } from 'react';
|
|
6
|
+
const createPlayerRegistry = () => {
|
|
7
|
+
const playersById = new Map();
|
|
8
|
+
const register = (videoId, handle) => {
|
|
9
|
+
playersById.set(videoId, handle);
|
|
10
|
+
};
|
|
11
|
+
const unregister = (videoId) => {
|
|
12
|
+
playersById.delete(videoId);
|
|
13
|
+
};
|
|
14
|
+
const activate = (videoId) => {
|
|
15
|
+
playersById.forEach((handle, id) => {
|
|
16
|
+
if (id !== videoId) {
|
|
17
|
+
handle.actions.pause('other-player');
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
return {
|
|
22
|
+
register,
|
|
23
|
+
unregister,
|
|
24
|
+
activate,
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
let videoPlayerRegistry;
|
|
28
|
+
const getVideoPlayerRegistry = () => {
|
|
29
|
+
if (!videoPlayerRegistry) {
|
|
30
|
+
videoPlayerRegistry = createPlayerRegistry();
|
|
31
|
+
}
|
|
32
|
+
return videoPlayerRegistry;
|
|
33
|
+
};
|
|
34
|
+
const VideoPlayerContext = createContext(null);
|
|
35
|
+
function addListener(el, events, fn) {
|
|
36
|
+
const listeners = events.split(' ');
|
|
37
|
+
listeners.forEach((e) => el.addEventListener(e, fn));
|
|
38
|
+
return () => {
|
|
39
|
+
listeners.forEach((e) => el.removeEventListener(e, fn));
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const VideoPlayerInternal = ({ video, children, playerCallbacks, }) => {
|
|
43
|
+
const mediaDispatch = useMediaDispatch();
|
|
44
|
+
const [mediaElement, setMediaElement] = useState(null);
|
|
45
|
+
const [playbackStartedAt, setPlaybackStartedAt] = useState();
|
|
46
|
+
// Maintaining our own picture-in-picture state instead of using MediaState's mediaIsPip.
|
|
47
|
+
// we render MediaController in a shadow DOM, making it unable to detect pip state changes
|
|
48
|
+
const [isPipMode, setIsPipMode] = useState(false);
|
|
49
|
+
const { onPlay, onPause, onCaptionChange, onQualityChange, onPlaybackRateChange, onToggleMenu, ...callbacks } = playerCallbacks || {};
|
|
50
|
+
const prevPlaybackRateRef = useRef(1);
|
|
51
|
+
const prevRenditionRef = useRef();
|
|
52
|
+
const pauseReasonRef = useRef();
|
|
53
|
+
const state = {
|
|
54
|
+
hasStarted: useMediaSelector((state) => state.mediaHasPlayed ?? false),
|
|
55
|
+
isPaused: useMediaSelector((state) => state.mediaPaused ?? true),
|
|
56
|
+
currentTime: useMediaSelector((state) => state.mediaCurrentTime ?? 0),
|
|
57
|
+
hasEnded: useMediaSelector((state) => state.mediaEnded ?? false),
|
|
58
|
+
loadedDuration: useMediaSelector((state) => isNaN(state.mediaDuration) ? 0 : state.mediaDuration),
|
|
59
|
+
selectedCaptionTrack: useMediaSelector((state) => state.mediaSubtitlesShowing?.length
|
|
60
|
+
? state.mediaSubtitlesShowing[0].language
|
|
61
|
+
: null),
|
|
62
|
+
playbackRate: useMediaSelector((state) => state.mediaPlaybackRate ?? 1),
|
|
63
|
+
selectedRendition: useMediaSelector((state) => state.mediaRenditionSelected),
|
|
64
|
+
element: mediaElement,
|
|
65
|
+
playbackStartedAt,
|
|
66
|
+
isPipMode,
|
|
67
|
+
};
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (onQualityChange &&
|
|
70
|
+
state.selectedRendition &&
|
|
71
|
+
prevRenditionRef.current !== state.selectedRendition) {
|
|
72
|
+
onQualityChange(state.selectedRendition);
|
|
73
|
+
}
|
|
74
|
+
prevRenditionRef.current = state.selectedRendition;
|
|
75
|
+
}, [onQualityChange, state.selectedRendition]);
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (onCaptionChange && state.selectedCaptionTrack) {
|
|
78
|
+
onCaptionChange(state.selectedCaptionTrack);
|
|
79
|
+
}
|
|
80
|
+
}, [state.selectedCaptionTrack, onCaptionChange]);
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (onPlaybackRateChange &&
|
|
83
|
+
prevPlaybackRateRef.current !== state.playbackRate) {
|
|
84
|
+
// Trigger callback only when playback rate changes from initial value
|
|
85
|
+
onPlaybackRateChange(state.playbackRate);
|
|
86
|
+
}
|
|
87
|
+
prevPlaybackRateRef.current = state.playbackRate;
|
|
88
|
+
}, [state.playbackRate, onPlaybackRateChange]);
|
|
89
|
+
const actions = useMemo(() => ({
|
|
90
|
+
play: () => mediaDispatch({ type: MediaActionTypes.MEDIA_PLAY_REQUEST }),
|
|
91
|
+
pause: (reason) => {
|
|
92
|
+
if (reason) {
|
|
93
|
+
// Store reason to trigger with onPause callback
|
|
94
|
+
pauseReasonRef.current = reason;
|
|
95
|
+
}
|
|
96
|
+
mediaDispatch({ type: MediaActionTypes.MEDIA_PAUSE_REQUEST });
|
|
97
|
+
},
|
|
98
|
+
toggleMenu: (menuType, isOpen) => {
|
|
99
|
+
onToggleMenu?.(menuType, isOpen);
|
|
100
|
+
},
|
|
101
|
+
setElement: setMediaElement,
|
|
102
|
+
}), [onToggleMenu]);
|
|
103
|
+
// Set up event listeners on native media element
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
if (!mediaElement) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const listeners = [
|
|
109
|
+
addListener(mediaElement, 'enterpictureinpicture leavepictureinpicture', (event) => setIsPipMode(event.type === 'enterpictureinpicture')),
|
|
110
|
+
];
|
|
111
|
+
return () => listeners.forEach((remove) => remove());
|
|
112
|
+
}, [mediaElement]);
|
|
113
|
+
// Register player instance
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
if (!video) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const registry = getVideoPlayerRegistry();
|
|
119
|
+
registry.register(video.videoId, { actions });
|
|
120
|
+
const handleVisibilityChange = () => {
|
|
121
|
+
if (document.visibilityState === 'hidden') {
|
|
122
|
+
actions.pause('visibility-hidden');
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
document.addEventListener('visibilitychange', handleVisibilityChange);
|
|
126
|
+
return () => {
|
|
127
|
+
registry.unregister(video.videoId);
|
|
128
|
+
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
129
|
+
};
|
|
130
|
+
}, [video]);
|
|
131
|
+
return (_jsx(VideoPlayerContext.Provider, { value: {
|
|
132
|
+
state,
|
|
133
|
+
actions,
|
|
134
|
+
eventCallbacks: {
|
|
135
|
+
...callbacks,
|
|
136
|
+
onPlay: (event) => {
|
|
137
|
+
if (video) {
|
|
138
|
+
const registry = getVideoPlayerRegistry();
|
|
139
|
+
registry.activate(video.videoId);
|
|
140
|
+
if (!playbackStartedAt) {
|
|
141
|
+
setPlaybackStartedAt(Date.now());
|
|
142
|
+
}
|
|
143
|
+
onPlay?.(event);
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
onPause: (event) => {
|
|
147
|
+
onPause?.(event, pauseReasonRef.current);
|
|
148
|
+
pauseReasonRef.current = undefined;
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
}, children: children }));
|
|
152
|
+
};
|
|
153
|
+
export const VideoPlayerProvider = ({ video, children, playerCallbacks, }) => {
|
|
154
|
+
return (_jsx(MediaProvider, { children: _jsx(VideoPlayerInternal, { video: video, playerCallbacks: playerCallbacks, children: children }) }));
|
|
155
|
+
};
|
|
156
|
+
export const useVideoPlayer = () => {
|
|
157
|
+
const context = useContext(VideoPlayerContext);
|
|
158
|
+
if (!context) {
|
|
159
|
+
throw new Error('useVideoPlayer must be used within a VideoPlayerProvider');
|
|
160
|
+
}
|
|
161
|
+
return context;
|
|
162
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const DEFAULT_ASPECT_RATIO: number;
|
|
2
|
+
export declare const DEFAULT_PLAY_BUTTON_COLOR = "#F7761F";
|
|
3
|
+
export declare const DEFAULT_HLS_OPTIONS: {
|
|
4
|
+
debug: boolean;
|
|
5
|
+
maxBufferSize: number;
|
|
6
|
+
maxBufferLength: number;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAE3C,eAAO,MAAM,yBAAyB,YAAY,CAAC;AAGnD,eAAO,MAAM,mBAAmB;;;;CAI/B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const DEFAULT_ASPECT_RATIO = 9 / 16;
|
|
2
|
+
export const DEFAULT_PLAY_BUTTON_COLOR = '#F7761F';
|
|
3
|
+
// do we want `autoStartLoad: false`? this was an important cost saving measure https://git.hubteam.com/HubSpot/hubspot-video-ui/commit/dd6d03586bd3a0c6f45178f660967ca52a4898d0#diff-270ff8e18fd756a342307e5269a906b4207090351052e5b1987171753bea6386R45
|
|
4
|
+
export const DEFAULT_HLS_OPTIONS = {
|
|
5
|
+
debug: true,
|
|
6
|
+
maxBufferSize: 20,
|
|
7
|
+
maxBufferLength: 15,
|
|
8
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type EffectResult = void | undefined | (() => EffectResult) | Promise<void | undefined | (() => EffectResult)>;
|
|
2
|
+
/**
|
|
3
|
+
* In some cases it may be necessary to mock dismissErrorWithoutHandling
|
|
4
|
+
* in tests.
|
|
5
|
+
*/
|
|
6
|
+
export declare function dismissErrorWithoutHandling(error: Error): void;
|
|
7
|
+
export declare function useAsyncEffect(effect: () => EffectResult, deps: unknown[]): void;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=useAsyncEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAsyncEffect.d.ts","sourceRoot":"","sources":["../../src/hooks/useAsyncEffect.ts"],"names":[],"mappings":"AAKA,KAAK,YAAY,GACb,IAAI,GACJ,SAAS,GACT,CAAC,MAAM,YAAY,CAAC,GACpB,OAAO,CAAC,IAAI,GAAG,SAAS,GAAG,CAAC,MAAM,YAAY,CAAC,CAAC,CAAC;AAErD;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,KAAK,QAIvD;AAsBD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,QAgCzE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* In some cases it may be necessary to mock dismissErrorWithoutHandling
|
|
4
|
+
* in tests.
|
|
5
|
+
*/
|
|
6
|
+
export function dismissErrorWithoutHandling(error) {
|
|
7
|
+
setTimeout(() => {
|
|
8
|
+
throw error;
|
|
9
|
+
}, 0);
|
|
10
|
+
}
|
|
11
|
+
function createRethrowAsync() {
|
|
12
|
+
const syncStackError = new Error(`Encountered unexpected rejection in async side effect`);
|
|
13
|
+
return (error) => {
|
|
14
|
+
dismissErrorWithoutHandling(error);
|
|
15
|
+
dismissErrorWithoutHandling(syncStackError);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
async function handleEffectResult(effectResult) {
|
|
19
|
+
if (effectResult instanceof Promise) {
|
|
20
|
+
return handleEffectResult(await effectResult);
|
|
21
|
+
}
|
|
22
|
+
else if (typeof effectResult === 'function') {
|
|
23
|
+
return handleEffectResult(effectResult());
|
|
24
|
+
}
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
export function useAsyncEffect(effect, deps) {
|
|
28
|
+
const rethrowAsync = useMemo(createRethrowAsync, []);
|
|
29
|
+
const { current: asyncEffectState } = useRef({
|
|
30
|
+
mostRecentEffect: effect,
|
|
31
|
+
asyncQueue: Promise.resolve(undefined),
|
|
32
|
+
done: false,
|
|
33
|
+
});
|
|
34
|
+
asyncEffectState.mostRecentEffect = effect;
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
const newLink = handleEffectResult(asyncEffectState.asyncQueue)
|
|
37
|
+
.catch(rethrowAsync)
|
|
38
|
+
.then(() => {
|
|
39
|
+
// we've reached the end of the queue, so it's time to trigger work
|
|
40
|
+
if (!asyncEffectState.done && asyncEffectState.asyncQueue === newLink) {
|
|
41
|
+
return asyncEffectState.mostRecentEffect();
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
.catch(rethrowAsync);
|
|
48
|
+
asyncEffectState.asyncQueue = newLink;
|
|
49
|
+
}, [asyncEffectState, rethrowAsync, ...deps]);
|
|
50
|
+
useEffect(() => () => {
|
|
51
|
+
asyncEffectState.done = true;
|
|
52
|
+
handleEffectResult(asyncEffectState.asyncQueue).catch(rethrowAsync);
|
|
53
|
+
}, [asyncEffectState, rethrowAsync]);
|
|
54
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { HsEnvironment, SubtitlesByLanguage } from '../types';
|
|
2
|
+
export declare const useSubtitles: (videoId: number, portalId: number, env?: HsEnvironment, hublet?: string) => {
|
|
3
|
+
subtitles: SubtitlesByLanguage | undefined;
|
|
4
|
+
fetchError: Error | undefined;
|
|
5
|
+
};
|
|
6
|
+
//# sourceMappingURL=useSubtitles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSubtitles.d.ts","sourceRoot":"","sources":["../../src/hooks/useSubtitles.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE9D,eAAO,MAAM,YAAY,YACd,MAAM,YACL,MAAM,QACV,aAAa,WACV,MAAM;;;CAiBhB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { fetchSubtitles } from '../api/video';
|
|
3
|
+
export const useSubtitles = (videoId, portalId, env, hublet) => {
|
|
4
|
+
const [fetchError, setFetchError] = useState();
|
|
5
|
+
const [subtitles, setSubtitles] = useState();
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
fetchSubtitles(videoId, portalId, env, hublet)
|
|
8
|
+
.then((resp) => {
|
|
9
|
+
setSubtitles(resp);
|
|
10
|
+
})
|
|
11
|
+
.catch((err) => {
|
|
12
|
+
console.error('Subtitles fetch failed:', err);
|
|
13
|
+
setFetchError(err);
|
|
14
|
+
});
|
|
15
|
+
}, [videoId, portalId, env, hublet]);
|
|
16
|
+
return { subtitles, fetchError };
|
|
17
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { FetchError } from '../api/video';
|
|
2
|
+
import { HsEnvironment, VideoCrmObject } from '../types';
|
|
3
|
+
export declare const useVideo: (videoId: number, portalId: number, env?: HsEnvironment, hublet?: string, skip?: boolean) => {
|
|
4
|
+
video: VideoCrmObject | undefined;
|
|
5
|
+
fetchError: FetchError | undefined;
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=useVideo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useVideo.d.ts","sourceRoot":"","sources":["../../src/hooks/useVideo.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAc,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAGzD,eAAO,MAAM,QAAQ,YACV,MAAM,YACL,MAAM,QACV,aAAa,WACV,MAAM,SACR,OAAO;;;CAef,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { fetchVideo } from '../api/video';
|
|
3
|
+
import { useAsyncEffect } from './useAsyncEffect';
|
|
4
|
+
export const useVideo = (videoId, portalId, env, hublet, skip) => {
|
|
5
|
+
const [fetchError, setFetchError] = useState();
|
|
6
|
+
const [video, setVideo] = useState();
|
|
7
|
+
useAsyncEffect(async () => {
|
|
8
|
+
try {
|
|
9
|
+
const resp = await fetchVideo(videoId, portalId, env, hublet, skip);
|
|
10
|
+
setVideo(resp.video);
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
setFetchError(err);
|
|
14
|
+
}
|
|
15
|
+
}, [videoId, env, hublet, skip]);
|
|
16
|
+
return { video, fetchError };
|
|
17
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { VideoPlayer } from './components/VideoPlayer';
|
|
2
|
+
export { VideoFetchProvider, VideoFetchContext, } from './components/VideoFetchProvider';
|
|
3
|
+
export * from './components/VideoPlayerProvider';
|
|
4
|
+
export * from './components/TranslationsProvider';
|
|
5
|
+
export * from './components/HSPlayerIcons';
|
|
6
|
+
export { HSPlayerThemes } from './components/HSThemeTemplate';
|
|
7
|
+
export { useVideo } from './hooks/useVideo';
|
|
8
|
+
export * from './api/video';
|
|
9
|
+
export * from './types';
|
|
10
|
+
export * from './constants';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EACL,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,iCAAiC,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { VideoPlayer } from './components/VideoPlayer';
|
|
2
|
+
export { VideoFetchProvider, VideoFetchContext, } from './components/VideoFetchProvider';
|
|
3
|
+
export * from './components/VideoPlayerProvider';
|
|
4
|
+
export * from './components/TranslationsProvider';
|
|
5
|
+
export * from './components/HSPlayerIcons';
|
|
6
|
+
export { HSPlayerThemes } from './components/HSThemeTemplate';
|
|
7
|
+
export { useVideo } from './hooks/useVideo';
|
|
8
|
+
export * from './api/video';
|
|
9
|
+
export * from './types';
|
|
10
|
+
export * from './constants';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
@font-face {
|
|
2
|
+
font-family: Lexend Deca;
|
|
3
|
+
src: url(//static.hsappstatic.net/ui-fonts/static-1.291/fonts/LexendDeca-Light.woff2)
|
|
4
|
+
format('woff2');
|
|
5
|
+
}
|
|
6
|
+
@font-face {
|
|
7
|
+
font-family: Lexend Deca;
|
|
8
|
+
src: url(//static.hsappstatic.net/ui-fonts/static-1.291/fonts/LexendDeca-Medium.woff2)
|
|
9
|
+
format('woff2');
|
|
10
|
+
font-weight: 500;
|
|
11
|
+
}
|
|
12
|
+
@font-face {
|
|
13
|
+
font-family: Lexend Deca;
|
|
14
|
+
src: url(//static.hsappstatic.net/ui-fonts/static-1.291/fonts/LexendDeca-SemiBold.woff2)
|
|
15
|
+
format('woff2');
|
|
16
|
+
font-weight: 600;
|
|
17
|
+
}
|
|
18
|
+
@font-face {
|
|
19
|
+
font-family: Lexend Deca;
|
|
20
|
+
src: url(//static.hsappstatic.net/ui-fonts/static-1.291/fonts/LexendDeca-Bold.woff2)
|
|
21
|
+
format('woff2');
|
|
22
|
+
font-weight: 700;
|
|
23
|
+
}
|