@playkit-js/moderation 2.1.1 → 2.2.0-canary.10-af41e17

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.
Files changed (37) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/LICENSE +5 -5
  3. package/README.md +174 -8
  4. package/dist/playkit-moderation.js +1 -23
  5. package/dist/playkit-moderation.js.map +1 -1
  6. package/package.json +51 -53
  7. package/src/components/icons/error-icon.tsx +11 -0
  8. package/src/components/icons/index.ts +9 -0
  9. package/src/components/icons/success-icon.tsx +11 -0
  10. package/src/components/moderation/down-icon.tsx +12 -0
  11. package/src/components/moderation/moderation.scss +46 -25
  12. package/src/components/moderation/moderation.tsx +67 -104
  13. package/src/components/plugin-button/plugin-button.scss +14 -14
  14. package/src/components/plugin-button/plugin-button.tsx +26 -3
  15. package/src/components/popover/index.ts +1 -0
  16. package/src/components/popover/popover-menu.scss +4 -0
  17. package/src/components/popover/popover-menu.tsx +57 -0
  18. package/src/components/popover/popover.scss +30 -0
  19. package/src/components/popover/popover.tsx +224 -0
  20. package/src/global.d.ts +6 -6
  21. package/src/index.ts +14 -1
  22. package/src/moderation-plugin.scss +4 -12
  23. package/src/moderation-plugin.tsx +132 -161
  24. package/src/providers/index.ts +2 -0
  25. package/src/providers/report-loader.ts +69 -0
  26. package/src/providers/response-types/index.ts +2 -0
  27. package/src/providers/response-types/kaltura-moderation-flag-response.ts +13 -0
  28. package/src/providers/response-types/kaltura-moderation-flag.ts +51 -0
  29. package/src/variables.scss +4 -1
  30. package/src/assets/.gitkeep +0 -0
  31. package/src/assets/close.svg +0 -10
  32. package/src/assets/down.svg +0 -9
  33. package/src/assets/error.svg +0 -3
  34. package/src/assets/flag.svg +0 -6
  35. package/src/assets/report.svg +0 -3
  36. package/src/components/.gitkeep +0 -0
  37. package/src/components/moderation/assets/down.svg +0 -9
@@ -0,0 +1 @@
1
+ export * from './popover';
@@ -0,0 +1,4 @@
1
+ .popover-menu {
2
+ padding-top: 6px;
3
+ padding-bottom: 6px;
4
+ }
@@ -0,0 +1,57 @@
1
+ import {h, Component, ComponentChild} from 'preact';
2
+ import * as styles from './popover-menu.scss';
3
+
4
+ export interface PopoverMenuItem {
5
+ label?: string;
6
+ onMenuChosen?: Function;
7
+ customRenderer?: (el: PopoverMenuItem) => ComponentChild;
8
+ }
9
+
10
+ interface PopoverMenuProps {
11
+ options: Array<PopoverMenuItem>;
12
+ itemRenderer?: (el: PopoverMenuItem) => ComponentChild;
13
+ }
14
+
15
+ /**
16
+ * Popover menu renders list of options.
17
+ * options example:
18
+ * [
19
+ * {label: 'option_1', onMenuChosen: () => console.log('selected first')},
20
+ * {label: 'option_2', onMenuChosen: () => console.log('selected second')}
21
+ * ]
22
+ * In case when 'itemRenderer' properdy hasn't provided - PopoverMenu renders
23
+ * div with class "popover-menu-item" that contain label for the current option.
24
+ * Default render of options can be changed by providing 'itemRenderer' - it should be
25
+ * function that takes current option and returns valid 'preact' node.
26
+ * If some option need to be rendered with a different method - specific render
27
+ * method can be provided with 'customRenderer' property for the current option.
28
+ * option example with specific render method:
29
+ * { label: 'specific render', onMenuChosen: () => {}, customRenderer: el => (<span>{el.label}</span>)}
30
+ */
31
+
32
+ export class PopoverMenu extends Component<PopoverMenuProps> {
33
+ render(props: any) {
34
+ return (
35
+ <div className={styles.popoverMenu}>
36
+ {props.options.map((el: PopoverMenuItem) => {
37
+ if (el.customRenderer) {
38
+ return el.customRenderer(el);
39
+ }
40
+ if (props.itemRenderer) {
41
+ return props.itemRenderer(el);
42
+ }
43
+ return (
44
+ <div
45
+ className="popover-menu-item"
46
+ onClick={() => {
47
+ // @ts-ignore
48
+ el.onMenuChosen(el)
49
+ }}>
50
+ {el.label}
51
+ </div>
52
+ );
53
+ })}
54
+ </div>
55
+ );
56
+ }
57
+ }
@@ -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
+ }
package/src/global.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /// <reference path="../node_modules/@playkit-js-contrib/common/global-types/index.d.ts" />
2
2
 
3
- declare module "*.scss" {
4
- const content: { [className: string]: string };
5
- export = content;
3
+ declare module '*.scss' {
4
+ const content: {[className: string]: string};
5
+ export = content;
6
6
  }
7
7
 
8
- declare module "*.svg" {
9
- const content: any;
10
- export default content;
8
+ declare module '*.svg' {
9
+ const content: any;
10
+ export default content;
11
11
  }
package/src/index.ts CHANGED
@@ -1 +1,14 @@
1
- import "./moderation-plugin";
1
+ import {ModerationPlugin} from './moderation-plugin';
2
+
3
+ declare var __VERSION__: string;
4
+ declare var __NAME__: string;
5
+
6
+ const VERSION = __VERSION__;
7
+ const NAME = __NAME__;
8
+
9
+ export {ModerationPlugin as Plugin};
10
+ export {VERSION, NAME};
11
+
12
+ const pluginName: string = 'playkit-js-moderation';
13
+
14
+ KalturaPlayer.core.registerPlugin(pluginName, ModerationPlugin);
@@ -1,13 +1,5 @@
1
1
  .toast-icon {
2
- width: 16px;
3
- height: 16px;
4
- margin-right: 7px;
5
- background-position: center;
6
- background-repeat: no-repeat;
7
- &.success {
8
- background-image: url('./assets/report.svg');
9
- }
10
- &.error {
11
- background-image: url('./assets/error.svg');
12
- }
13
- }
2
+ width: 16px;
3
+ height: 16px;
4
+ margin-right: 7px;
5
+ }