@playkit-js/moderation 2.1.1 → 2.2.0-canary.2-223f8a4
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/CHANGELOG.md +7 -0
- package/LICENSE +5 -5
- package/README.md +105 -8
- package/dist/3758875b5327755db91c.svg +3 -0
- package/dist/4e88e84bb6cd6f386467.svg +9 -0
- package/{src/components/moderation/assets/down.svg → dist/699b282225ecacccffd9.svg} +2 -2
- package/dist/f4a8c73d84c247e719f8.svg +3 -0
- package/dist/playkit-moderation.js +1 -23
- package/dist/playkit-moderation.js.map +1 -1
- package/package.json +49 -54
- package/src/components/a11y-wrapper/a11y-wrapper.tsx +26 -0
- package/src/components/a11y-wrapper/index.ts +1 -0
- package/src/components/icons/index.ts +9 -0
- package/src/components/moderation/moderation.scss +25 -7
- package/src/components/moderation/moderation.tsx +64 -104
- package/src/components/plugin-button/plugin-button.scss +14 -14
- package/src/components/plugin-button/plugin-button.tsx +26 -3
- package/src/components/popover/index.ts +1 -0
- package/src/components/popover/popover-menu.scss +4 -0
- package/src/components/popover/popover-menu.tsx +57 -0
- package/src/components/popover/popover.scss +30 -0
- package/src/components/popover/popover.tsx +224 -0
- package/src/contrib-services/common-types.ts +2 -0
- package/src/contrib-services/contrib-services.ts +80 -0
- package/src/contrib-services/contrib-utils.ts +16 -0
- package/src/contrib-services/events-manager.ts +59 -0
- package/src/contrib-services/floating-item-data.tsx +31 -0
- package/src/contrib-services/floating-item.tsx +116 -0
- package/src/contrib-services/floating-manager.tsx +224 -0
- package/src/contrib-services/index.ts +2 -0
- package/src/contrib-services/injected-component/index.ts +1 -0
- package/src/contrib-services/injected-component/injected-component.scss +5 -0
- package/src/contrib-services/injected-component/injected-component.tsx +58 -0
- package/src/contrib-services/kaltura-player-utils.ts +18 -0
- package/src/contrib-services/managed-component/_managed-component.scss +8 -0
- package/src/contrib-services/managed-component/index.ts +1 -0
- package/src/contrib-services/managed-component/managed-component.tsx +71 -0
- package/src/contrib-services/object-utils.ts +157 -0
- package/src/contrib-services/player-contrib-registry.ts +34 -0
- package/src/contrib-services/player-utils.ts +37 -0
- package/src/contrib-services/preset-item-data.tsx +43 -0
- package/src/contrib-services/preset-item.tsx +113 -0
- package/src/contrib-services/preset-manager.tsx +153 -0
- package/src/contrib-services/presets-utils.ts +27 -0
- package/src/contrib-services/toast/_toast.scss +93 -0
- package/src/contrib-services/toast/assets/close.svg +9 -0
- package/src/contrib-services/toast/index.ts +1 -0
- package/src/contrib-services/toast/toast.tsx +67 -0
- package/src/contrib-services/toast-manager.tsx +121 -0
- package/src/contrib-services/toasts-container/_toasts-container.scss +21 -0
- package/src/contrib-services/toasts-container/index.ts +1 -0
- package/src/contrib-services/toasts-container/toasts-container.tsx +23 -0
- package/src/contrib-services/ui-player-adapter/index.tsx +1 -0
- package/src/contrib-services/ui-player-adapter/ui-player-adapter.tsx +27 -0
- package/src/contrib-services/uuid.ts +6 -0
- package/src/global.d.ts +6 -6
- package/src/index.ts +13 -1
- package/src/moderation-plugin.scss +12 -12
- package/src/moderation-plugin.tsx +123 -160
- package/src/providers/index.ts +2 -0
- package/src/providers/report-loader.ts +69 -0
- package/src/providers/response-types/index.ts +2 -0
- package/src/providers/response-types/kaltura-moderation-flag-response.ts +13 -0
- package/src/providers/response-types/kaltura-moderation-flag.ts +51 -0
- package/src/variables.scss +4 -1
- package/src/assets/.gitkeep +0 -0
- package/src/assets/close.svg +0 -10
- package/src/assets/flag.svg +0 -6
- package/src/components/.gitkeep +0 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
.popover-container {
|
|
2
|
+
position: relative;
|
|
3
|
+
.popover-component {
|
|
4
|
+
background-color: #222222;
|
|
5
|
+
border-radius: 4px;
|
|
6
|
+
position: absolute;
|
|
7
|
+
right: 0px;
|
|
8
|
+
font-size: 15px;
|
|
9
|
+
display: block;
|
|
10
|
+
&.visible {
|
|
11
|
+
visibility: visible;
|
|
12
|
+
opacity: 1;
|
|
13
|
+
z-index: 10;
|
|
14
|
+
}
|
|
15
|
+
&.top {
|
|
16
|
+
bottom: 100%;
|
|
17
|
+
margin-bottom: 6px;
|
|
18
|
+
}
|
|
19
|
+
&.bottom {
|
|
20
|
+
top: 100%;
|
|
21
|
+
margin-top: 6px;
|
|
22
|
+
}
|
|
23
|
+
&.right {
|
|
24
|
+
left: 0px;
|
|
25
|
+
}
|
|
26
|
+
&.left {
|
|
27
|
+
right: 0px;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import {h, Component, ComponentChild} from 'preact';
|
|
2
|
+
import * as styles from './popover.scss';
|
|
3
|
+
|
|
4
|
+
export enum PopoverVerticalPositions {
|
|
5
|
+
Top = 'top',
|
|
6
|
+
Bottom = 'bottom',
|
|
7
|
+
}
|
|
8
|
+
export enum PopoverHorizontalPositions {
|
|
9
|
+
Left = 'left',
|
|
10
|
+
Right = 'right',
|
|
11
|
+
}
|
|
12
|
+
export enum PopoverTriggerMode {
|
|
13
|
+
Click = 'click',
|
|
14
|
+
Hover = 'hover',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export enum KeyboardKeys {
|
|
18
|
+
Esc = 27,
|
|
19
|
+
Enter = 13,
|
|
20
|
+
Tab = 9,
|
|
21
|
+
Space = 32,
|
|
22
|
+
End = 35,
|
|
23
|
+
Home = 36,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const CLOSE_ON_HOVER_DELAY = 500;
|
|
27
|
+
|
|
28
|
+
const defaultProps = {
|
|
29
|
+
verticalPosition: PopoverVerticalPositions.Top,
|
|
30
|
+
horizontalPosition: PopoverHorizontalPositions.Left,
|
|
31
|
+
triggerMode: PopoverTriggerMode.Click,
|
|
32
|
+
className: 'popover',
|
|
33
|
+
closeOnEsc: true,
|
|
34
|
+
closeOnClick: true,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
interface PopoverProps {
|
|
38
|
+
onClose?: () => void;
|
|
39
|
+
onOpen?: () => void;
|
|
40
|
+
closeOnClick: boolean;
|
|
41
|
+
closeOnEsc: boolean;
|
|
42
|
+
verticalPosition: PopoverVerticalPositions;
|
|
43
|
+
horizontalPosition: PopoverHorizontalPositions;
|
|
44
|
+
className: string;
|
|
45
|
+
triggerMode: PopoverTriggerMode;
|
|
46
|
+
content: ComponentChild;
|
|
47
|
+
children: ComponentChild;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface PopoverState {
|
|
51
|
+
open: boolean;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Popover renders popup with a target.
|
|
56
|
+
* Properties description:
|
|
57
|
+
* onOpen - function that will be executed when popover opens;
|
|
58
|
+
* onClose - function that will be executed when popover closes;
|
|
59
|
+
* closeOnClick - close the popover on mouse click;
|
|
60
|
+
* verticalPosition - vertical position of popover relative to target ("top" or "bottom"), default - "top";
|
|
61
|
+
* horizontalPosition - horizontal position of popover relative to target ("left" or "right"), default - "left";
|
|
62
|
+
* !!! known limitation of popover positions: if popover opens beyond the visible area of the player - the popover will be overlapped by player
|
|
63
|
+
* className - popover class, can be use for popover styling, default - 'popover';
|
|
64
|
+
* closeOnEsc - handle ESC keyboard pressed event and close popover, default - true;
|
|
65
|
+
* triggerMode - popover support 2 ways for opening: click (keyPress) and mouse hover ("click" or "hover"), default - "click";
|
|
66
|
+
* content - content of popover. Can be any valid Preact node, ex:
|
|
67
|
+
* <select>
|
|
68
|
+
* <option>Option 1</option>
|
|
69
|
+
* ...
|
|
70
|
+
* <option>Option n</option>
|
|
71
|
+
* </select>
|
|
72
|
+
* children - popover target. Can be any valid Preact node, ex:
|
|
73
|
+
* <button>
|
|
74
|
+
* <i className="icon" />
|
|
75
|
+
* </button>
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
export class Popover extends Component<PopoverProps, PopoverState> {
|
|
79
|
+
private _closeTimeout: any = null;
|
|
80
|
+
private _controlElement = null;
|
|
81
|
+
static defaultProps = {
|
|
82
|
+
...defaultProps,
|
|
83
|
+
};
|
|
84
|
+
state = {
|
|
85
|
+
open: false,
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
componentWillUnmount() {
|
|
89
|
+
this._removeListeners();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private _clearTimeout = () => {
|
|
93
|
+
clearTimeout(this._closeTimeout);
|
|
94
|
+
this._closeTimeout = null;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
private _handleMouseEvent = (event: MouseEvent) => {
|
|
98
|
+
if (
|
|
99
|
+
// @ts-ignore
|
|
100
|
+
!this._controlElement.contains(event.target) &&
|
|
101
|
+
this.props.closeOnClick
|
|
102
|
+
) {
|
|
103
|
+
this._closePopover();
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
private _handleKeyboardEvent = (event: KeyboardEvent) => {
|
|
108
|
+
if (
|
|
109
|
+
// @ts-ignore
|
|
110
|
+
this._controlElement.contains(event.target) &&
|
|
111
|
+
event.keyCode === KeyboardKeys.Enter
|
|
112
|
+
) {
|
|
113
|
+
// handle Enter key pressed on Target icon to prevent triggering of _closePopover twice
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (
|
|
117
|
+
(this.props.closeOnEsc && event.keyCode === KeyboardKeys.Esc) ||
|
|
118
|
+
event.keyCode === KeyboardKeys.Enter
|
|
119
|
+
) {
|
|
120
|
+
// handle if ESC or Enter button presesd
|
|
121
|
+
this._closePopover();
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
private _openPopover = () => {
|
|
126
|
+
const {onOpen} = this.props;
|
|
127
|
+
this._clearTimeout();
|
|
128
|
+
this.setState({open: true}, () => {
|
|
129
|
+
this._addListeners();
|
|
130
|
+
if (onOpen) {
|
|
131
|
+
onOpen();
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
private _closePopover = () => {
|
|
137
|
+
const {onClose} = this.props;
|
|
138
|
+
this._clearTimeout();
|
|
139
|
+
this.setState({open: false}, () => {
|
|
140
|
+
this._removeListeners();
|
|
141
|
+
if (onClose) {
|
|
142
|
+
onClose();
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
private _togglePopover = (e: MouseEvent | KeyboardEvent) => {
|
|
148
|
+
if (this.state.open) {
|
|
149
|
+
this._closePopover();
|
|
150
|
+
} else {
|
|
151
|
+
this._openPopover();
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
private _handleMouseEnter = () => {
|
|
155
|
+
if (!this.state.open) {
|
|
156
|
+
this._openPopover();
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
private _handleMouseLeave = () => {
|
|
160
|
+
this._closeTimeout = setTimeout(this._closePopover, CLOSE_ON_HOVER_DELAY);
|
|
161
|
+
};
|
|
162
|
+
private _handleHoverOnPopover = () => {
|
|
163
|
+
if (this.state.open && this._closeTimeout) {
|
|
164
|
+
this._clearTimeout();
|
|
165
|
+
} else {
|
|
166
|
+
this._closePopover();
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
private _addListeners = () => {
|
|
170
|
+
document.addEventListener('click', this._handleMouseEvent);
|
|
171
|
+
document.addEventListener('keydown', this._handleKeyboardEvent);
|
|
172
|
+
};
|
|
173
|
+
private _removeListeners = () => {
|
|
174
|
+
document.removeEventListener('click', this._handleMouseEvent);
|
|
175
|
+
document.removeEventListener('keydown', this._handleKeyboardEvent);
|
|
176
|
+
};
|
|
177
|
+
private _getHoverEvents = () => {
|
|
178
|
+
if (this.props.triggerMode === PopoverTriggerMode.Hover) {
|
|
179
|
+
return {
|
|
180
|
+
targetEvents: {
|
|
181
|
+
onMouseEnter: this._handleMouseEnter,
|
|
182
|
+
onMouseLeave: this._handleMouseLeave,
|
|
183
|
+
},
|
|
184
|
+
popoverEvents: {
|
|
185
|
+
onMouseEnter: this._handleHoverOnPopover,
|
|
186
|
+
onMouseLeave: this._handleHoverOnPopover,
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
return {targetEvents: {onClick: this._togglePopover}, popoverEvents: {}};
|
|
191
|
+
};
|
|
192
|
+
render(props: PopoverProps) {
|
|
193
|
+
if (!props.content || !props.children) {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
const {targetEvents, popoverEvents} = this._getHoverEvents();
|
|
197
|
+
return (
|
|
198
|
+
<div className={styles.popoverContainer}>
|
|
199
|
+
<div
|
|
200
|
+
className="popover-anchor-container"
|
|
201
|
+
ref={node => {
|
|
202
|
+
// @ts-ignore
|
|
203
|
+
this._controlElement = node;
|
|
204
|
+
}}
|
|
205
|
+
{...targetEvents}>
|
|
206
|
+
{props.children}
|
|
207
|
+
</div>
|
|
208
|
+
{this.state.open && (
|
|
209
|
+
<div
|
|
210
|
+
aria-expanded="true"
|
|
211
|
+
className={[
|
|
212
|
+
props.className,
|
|
213
|
+
styles.popoverComponent,
|
|
214
|
+
styles[props.verticalPosition],
|
|
215
|
+
styles[props.horizontalPosition],
|
|
216
|
+
].join(' ')}
|
|
217
|
+
{...popoverEvents}>
|
|
218
|
+
{props.content}
|
|
219
|
+
</div>
|
|
220
|
+
)}
|
|
221
|
+
</div>
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import {PlayerContribRegistry} from './player-contrib-registry';
|
|
2
|
+
import {PresetManager} from './preset-manager';
|
|
3
|
+
import {ToastManager} from './toast-manager';
|
|
4
|
+
import {FloatingManager} from './floating-manager';
|
|
5
|
+
|
|
6
|
+
export interface ContribServicesOptions {
|
|
7
|
+
kalturaPlayer: KalturaPlayerTypes.Player;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function getPlayerContribRegistry(kalturaPlayer: KalturaPlayerTypes.Player): PlayerContribRegistry {
|
|
11
|
+
return PlayerContribRegistry.get(kalturaPlayer);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class ContribServices {
|
|
15
|
+
static get(options: ContribServicesOptions): ContribServices {
|
|
16
|
+
const playerContribRegistry = getPlayerContribRegistry(options.kalturaPlayer);
|
|
17
|
+
return playerContribRegistry.register('ContribServices', () => {
|
|
18
|
+
return new ContribServices(playerContribRegistry, options);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private _toastManager: ToastManager;
|
|
23
|
+
private _floatingManager: FloatingManager;
|
|
24
|
+
private _presetManager: PresetManager;
|
|
25
|
+
|
|
26
|
+
constructor(private _playerContribRegistry: PlayerContribRegistry, private _options: ContribServicesOptions) {
|
|
27
|
+
const kalturaPlayer = this._options.kalturaPlayer;
|
|
28
|
+
|
|
29
|
+
const presetManager = new PresetManager({
|
|
30
|
+
kalturaPlayer
|
|
31
|
+
});
|
|
32
|
+
const floatingManager = new FloatingManager({
|
|
33
|
+
kalturaPlayer,
|
|
34
|
+
presetManager
|
|
35
|
+
});
|
|
36
|
+
const toastManager = new ToastManager({
|
|
37
|
+
floatingManager
|
|
38
|
+
});
|
|
39
|
+
this._toastManager = toastManager;
|
|
40
|
+
this._floatingManager = floatingManager;
|
|
41
|
+
this._presetManager = presetManager;
|
|
42
|
+
|
|
43
|
+
this._addListeners();
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private _addListeners = (): void => {
|
|
48
|
+
const kalturaPlayer = this._options.kalturaPlayer;
|
|
49
|
+
kalturaPlayer.addEventListener(kalturaPlayer.Event.PLAYER_RESET, this.reset);
|
|
50
|
+
kalturaPlayer.addEventListener(kalturaPlayer.Event.PLAYER_DESTROY, this._removeListeners);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
private _removeListeners = (): void => {
|
|
54
|
+
const kalturaPlayer = this._options.kalturaPlayer;
|
|
55
|
+
kalturaPlayer.removeEventListener(kalturaPlayer.Event.PLAYER_RESET, this.reset);
|
|
56
|
+
kalturaPlayer.removeEventListener(kalturaPlayer.Event.PLAYER_DESTROY, this._removeListeners);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
public get presetManager(): PresetManager {
|
|
60
|
+
return this._presetManager;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public get floatingManager(): FloatingManager {
|
|
64
|
+
return this._floatingManager;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public get toastManager(): ToastManager {
|
|
68
|
+
return this._toastManager;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
reset = (): void => {
|
|
72
|
+
this._toastManager.reset();
|
|
73
|
+
this._floatingManager.reset();
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
public getPlayerKS(): string | null {
|
|
77
|
+
const {session} = this._options.kalturaPlayer.config;
|
|
78
|
+
return session && session.ks ? session.ks : null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {KalturaPlayerUtils} from './kaltura-player-utils';
|
|
2
|
+
|
|
3
|
+
export function getContribConfig<T>(
|
|
4
|
+
player: KalturaPlayerTypes.Player,
|
|
5
|
+
path: string,
|
|
6
|
+
baseConfig: T,
|
|
7
|
+
options?: {explicitMerge: string[]}
|
|
8
|
+
): T {
|
|
9
|
+
return KalturaPlayerUtils.getPlayerConfig(
|
|
10
|
+
player,
|
|
11
|
+
`contrib.${path}`,
|
|
12
|
+
baseConfig,
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
options
|
|
15
|
+
);
|
|
16
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export type Handler<T> = (event: T) => void;
|
|
2
|
+
export type WildcardHandler = (event: any) => void;
|
|
3
|
+
|
|
4
|
+
export interface Event {
|
|
5
|
+
type: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class EventsManager<T extends Event> {
|
|
9
|
+
private _eventListeners: Record<string, Handler<any>[]> = {};
|
|
10
|
+
private _wildcardEventListeners: WildcardHandler[] = [];
|
|
11
|
+
|
|
12
|
+
on<TEvent extends Event>(
|
|
13
|
+
type: TEvent['type'],
|
|
14
|
+
handler: Handler<TEvent>
|
|
15
|
+
): void;
|
|
16
|
+
on(type: '*', handler: WildcardHandler): void;
|
|
17
|
+
on(type: string, handler: any): void {
|
|
18
|
+
if (type === '*') {
|
|
19
|
+
this._wildcardEventListeners.push(handler);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
(this._eventListeners[type] || (this._eventListeners[type] = [])).push(
|
|
24
|
+
handler
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
off<TEvent extends Event>(
|
|
29
|
+
type: TEvent['type'],
|
|
30
|
+
handler: Handler<TEvent>
|
|
31
|
+
): void;
|
|
32
|
+
off(type: '*', handler: WildcardHandler): void;
|
|
33
|
+
off(type: string, handler: any): void {
|
|
34
|
+
if (type === '*') {
|
|
35
|
+
this._wildcardEventListeners.splice(
|
|
36
|
+
this._wildcardEventListeners.indexOf(handler) >>> 0,
|
|
37
|
+
1
|
|
38
|
+
);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const eventListeners = this._eventListeners[type];
|
|
43
|
+
|
|
44
|
+
if (!eventListeners) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
eventListeners.splice(eventListeners.indexOf(handler) >>> 0, 1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
emit(event: T): void {
|
|
52
|
+
(this._eventListeners[event.type] || []).slice().map(handler => {
|
|
53
|
+
handler(event);
|
|
54
|
+
});
|
|
55
|
+
this._wildcardEventListeners.slice().map(handler => {
|
|
56
|
+
handler(event);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {ComponentChild, Ref} from 'preact';
|
|
2
|
+
import {PlayerSize, VideoSize} from './common-types';
|
|
3
|
+
|
|
4
|
+
export enum FloatingUIModes {
|
|
5
|
+
MediaLoaded = 'MediaLoaded',
|
|
6
|
+
OnDemand = 'OnDemand',
|
|
7
|
+
Immediate = 'Immediate',
|
|
8
|
+
FirstPlay = 'FirstPlay',
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export enum FloatingPositions {
|
|
12
|
+
VideoArea = 'VideoArea',
|
|
13
|
+
PresetArea = 'PresetArea',
|
|
14
|
+
InteractiveArea = 'InteractiveArea',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface FloatingItemData {
|
|
18
|
+
label: string;
|
|
19
|
+
mode: FloatingUIModes;
|
|
20
|
+
renderContent: (floatingItemProps: FloatingItemProps) => ComponentChild;
|
|
21
|
+
className?: string;
|
|
22
|
+
position: FloatingPositions;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface FloatingItemProps {
|
|
26
|
+
currentTime: number;
|
|
27
|
+
canvas: {
|
|
28
|
+
playerSize: PlayerSize;
|
|
29
|
+
videoSize: VideoSize;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import {h} from 'preact';
|
|
2
|
+
import {
|
|
3
|
+
FloatingItemData,
|
|
4
|
+
FloatingItemProps,
|
|
5
|
+
FloatingUIModes,
|
|
6
|
+
} from './floating-item-data';
|
|
7
|
+
import {ManagedComponent} from './managed-component';
|
|
8
|
+
|
|
9
|
+
export interface FloatingItemOptions {
|
|
10
|
+
kalturaPlayer: KalturaPlayerTypes.Player;
|
|
11
|
+
data: FloatingItemData;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class FloatingItem {
|
|
15
|
+
private _destroyed = false;
|
|
16
|
+
private _options: FloatingItemOptions;
|
|
17
|
+
private _isShown = false;
|
|
18
|
+
private _componentRef: ManagedComponent | null = null;
|
|
19
|
+
|
|
20
|
+
constructor(options: FloatingItemOptions) {
|
|
21
|
+
this._options = options;
|
|
22
|
+
|
|
23
|
+
this._addPlayerBindings();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get data(): FloatingItemData {
|
|
27
|
+
return this._options.data;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
remove = (): void => {
|
|
31
|
+
this._isShown = false;
|
|
32
|
+
if (!this._componentRef) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
this._componentRef.update();
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
add = (): void => {
|
|
40
|
+
this._isShown = true;
|
|
41
|
+
if (!this._componentRef) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
this._componentRef.update();
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
public update() {
|
|
49
|
+
if (!this._componentRef) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
this._componentRef.update();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* destory the ui item
|
|
58
|
+
*/
|
|
59
|
+
destroy(): void {
|
|
60
|
+
this._destroyed = true;
|
|
61
|
+
this.remove();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
renderFloatingChild(props: FloatingItemProps) {
|
|
65
|
+
const {label} = this._options.data;
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<ManagedComponent
|
|
69
|
+
label={label}
|
|
70
|
+
renderChildren={() => this._options.data.renderContent(props)}
|
|
71
|
+
isShown={() => this._isShown}
|
|
72
|
+
ref={(ref: any) => (this._componentRef = ref)}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private _handleMediaLoaded = () => {
|
|
78
|
+
const {kalturaPlayer} = this._options;
|
|
79
|
+
kalturaPlayer.removeEventListener(
|
|
80
|
+
kalturaPlayer.Event.MEDIA_LOADED,
|
|
81
|
+
this._handleMediaLoaded
|
|
82
|
+
);
|
|
83
|
+
this.add();
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
private _handleFirstPlay = () => {
|
|
87
|
+
const {kalturaPlayer} = this._options;
|
|
88
|
+
kalturaPlayer.removeEventListener(
|
|
89
|
+
kalturaPlayer.Event.FIRST_PLAY,
|
|
90
|
+
this._handleFirstPlay
|
|
91
|
+
);
|
|
92
|
+
this.add();
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
private _addPlayerBindings() {
|
|
96
|
+
const {kalturaPlayer, data} = this._options;
|
|
97
|
+
|
|
98
|
+
if (data.mode === FloatingUIModes.MediaLoaded) {
|
|
99
|
+
kalturaPlayer.addEventListener(
|
|
100
|
+
kalturaPlayer.Event.MEDIA_LOADED,
|
|
101
|
+
this._handleMediaLoaded
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (data.mode === FloatingUIModes.FirstPlay) {
|
|
106
|
+
kalturaPlayer.addEventListener(
|
|
107
|
+
kalturaPlayer.Event.FIRST_PLAY,
|
|
108
|
+
this._handleFirstPlay
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (data.mode === FloatingUIModes.Immediate) {
|
|
113
|
+
this.add();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|