@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
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@playkit-js/moderation",
3
- "version": "2.1.1",
3
+ "version": "2.2.0-canary.10-af41e17",
4
+ "main": "dist/playkit-moderation.js",
4
5
  "private": false,
5
6
  "bugs": {
6
7
  "url": "https://github.com/kaltura/playkit-js-moderation/issues"
@@ -13,27 +14,32 @@
13
14
  "publishConfig": {
14
15
  "access": "public"
15
16
  },
16
- "dependencies": {
17
- "@playkit-js-contrib/cli": "1.1.0",
18
- "@playkit-js-contrib/common": "^4.1.10",
19
- "@playkit-js-contrib/plugin": "^4.1.13",
20
- "@playkit-js-contrib/ui": "^4.1.13",
21
- "classnames": "2.2.6",
22
- "kaltura-typescript-client": "file:libs/kaltura-typescript-client-7.0.0-v20190324-101134.tgz",
23
- "null": "^2.0.0"
24
- },
25
17
  "devDependencies": {
26
- "@commitlint/cli": "8.3.5",
27
- "@commitlint/config-conventional": "8.3.4",
28
- "@types/classnames": "2.2.9",
29
- "@types/node": "13.7.6",
30
- "@typescript-eslint/eslint-plugin": "2.21.0",
31
- "@typescript-eslint/parser": "2.21.0",
32
- "husky": "3.1.0",
33
- "preact": "^10.4.1",
34
- "tslint": "5.20.1",
35
- "standard-version": "^6.0.1",
36
- "typescript": "3.8.2"
18
+ "@typescript-eslint/eslint-plugin": "^5.23.0",
19
+ "@typescript-eslint/parser": "^5.23.0",
20
+ "conventional-github-releaser": "3.1.3",
21
+ "cross-env": "^7.0.3",
22
+ "css-loader": "^6.7.1",
23
+ "documentation": "^13.2.5",
24
+ "husky": "^8.0.1",
25
+ "jest": "^28.1.0",
26
+ "kaltura-player-js": "https://github.com/kaltura/kaltura-player-js.git#master",
27
+ "lint-staged": "^12.4.1",
28
+ "prettier": "^2.6.2",
29
+ "sass": "^1.52.3",
30
+ "sass-loader": "^12.6.0",
31
+ "standard-version": "^9.3.2",
32
+ "style-loader": "1.3.0",
33
+ "ts-loader": "^9.3.0",
34
+ "tslint": "^6.1.3",
35
+ "typescript": "^4.6.4",
36
+ "uglifyjs-webpack-plugin": "^2.2.0",
37
+ "webpack": "^5.72.1",
38
+ "webpack-cli": "^4.9.2",
39
+ "webpack-dev-server": "^4.9.0"
40
+ },
41
+ "peerDependencies": {
42
+ "kaltura-player-js": "https://github.com/kaltura/kaltura-player-js.git#master"
37
43
  },
38
44
  "license": "AGPL-3.0",
39
45
  "files": [
@@ -44,38 +50,30 @@
44
50
  "src"
45
51
  ],
46
52
  "scripts": {
47
- "clean": "rm -rf dist",
48
- "reset": "npm run clean && rm -rf node_modules",
49
- "build": "kcontrib build",
50
- "build:dev": "kcontrib build --dev",
51
- "bump-canary": "standard-version --prerelease canary --skip.commit=true --skip.tag=true",
52
- "serve": "kcontrib serve",
53
- "serve:update-modes": "kcontrib serve --update-modes",
54
- "serve:update-player": "kcontrib serve --update-player",
55
- "analyze": "npm run build && npx source-map-explorer dist/playkit-moderation.js",
56
- "lint": "tsc --noEmit && eslint ./src --ext .ts,.tsx",
57
- "lint:fix": "tsc --noEmit && eslint ./src --ext .ts,.tsx --fix",
58
- "husky:pre-commit": "lint-staged",
59
- "husky:commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
60
- "deploy:prepare": "kcontrib deploy --prepare",
61
- "deploy:publish-to-npm": "kcontrib deploy --publish",
62
- "deploy:next:prepare": "kcontrib deploy --prepare --prerelease next",
63
- "contrib:latest": "kcontrib infra --type=latest",
64
- "infra:latest": "kcontrib infra --type=latest",
65
- "infra:next": "kcontrib infra --type=next",
66
- "infra:local": "kcontrib infra --type=local",
67
- "infra:add": "kcontrib infra --add"
53
+ "clean": "rm -rf ./dist",
54
+ "prebuild": "npm run clean",
55
+ "build": "webpack --mode production",
56
+ "dev": "webpack-dev-server --mode development",
57
+ "watch": "webpack --progress --color --watch --mode development",
58
+ "test": "jest",
59
+ "release": "standard-version",
60
+ "pushTaggedRelease": "git push --follow-tags --no-verify origin master",
61
+ "eslint": "eslint . --color",
62
+ "commit:dist": "git add --force --all dist && (git commit -m 'chore: update dist' || exit 0)",
63
+ "docs:generate": "documentation build flow-typed/** src/** -f md -o docs/configuration.md",
64
+ "docs:serve": "documentation serve flow-typed/** src/** --watch",
65
+ "precommit": "lint-staged",
66
+ "prettier:fix": "prettier --write ."
68
67
  },
69
- "browserslist": {
70
- "production": [
71
- ">0.2%",
72
- "not dead",
73
- "not op_mini all"
74
- ],
75
- "development": [
76
- "last 1 chrome version",
77
- "last 1 firefox version",
78
- "last 1 safari version"
79
- ]
68
+ "keywords": [
69
+ "moderation",
70
+ "kaltura",
71
+ "player",
72
+ "playkit-js",
73
+ "playkit-js-moderation",
74
+ "html5 player"
75
+ ],
76
+ "dependencies": {
77
+ "@playkit-js/common": "^1.0.2"
80
78
  }
81
79
  }
@@ -0,0 +1,11 @@
1
+ import {h} from 'preact';
2
+
3
+ export const ErrorIcon = () => (
4
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
5
+ <path
6
+ fill="#CCC"
7
+ fill-rule="evenodd"
8
+ d="M8 2c3.314 0 6 2.686 6 6s-2.686 6-6 6-6-2.686-6-6 2.686-6 6-6zm0 8c-.552 0-1 .448-1 1s.448 1 1 1 1-.448 1-1-.448-1-1-1zm0-6c-.552 0-1 .444-1 1v3c0 .513.383.936.883.993L8 9c.552 0 1-.444 1-1V5c0-.513-.383-.936-.883-.993L8 4z"
9
+ />
10
+ </svg>
11
+ );
@@ -0,0 +1,9 @@
1
+ export namespace icons {
2
+ export const PLUGIN_ICON =
3
+ 'M8.378 7.084l5.175 19.314c.134.497-.126 1.005-.594 1.19l-.112.037c-.533.143-1.08-.165-1.225-.71L6.447 7.603c-.134-.497.126-1.005.594-1.19l.112-.037c.533-.143 1.08.165 1.225.71zM21.882 7c1.878 0 2.79 1.622 1.84 3.239l-1.386 2.36 2.94 3.246C26.6 17.31 25.842 19 23.868 19h-10.21c-.452 0-.848-.304-.966-.741l-2.68-10c-.17-.635.31-1.259.967-1.259h10.902zm.211 1.994l-.21.006h-9.6l2.144 8h9.196l-3.263-3.604c-.293-.324-.342-.8-.12-1.178l1.757-2.992c.114-.194.168-.23.096-.232z';
4
+ export const CLOSE_ICON =
5
+ 'M17.9113162,16 L24.6072325,9.30408374 C25.1313645,8.77995172 25.1287183,7.92687249 24.6009229,7.3990771 C24.0694478,6.86760201 23.220227,6.86845682 22.6959163,7.39276754 L16,14.0886838 L9.30408374,7.39276754 C8.77995172,6.86863552 7.92687249,6.8712817 7.3990771,7.3990771 C6.86760201,7.93055219 6.86845682,8.77977302 7.39276754,9.30408374 L14.0886838,16 L7.39276754,22.6959163 C6.86863552,23.2200483 6.8712817,24.0731275 7.3990771,24.6009229 C7.93055219,25.132398 8.77977302,25.1315432 9.30408374,24.6072325 L16,17.9113162 L22.6959163,24.6072325 C23.2200483,25.1313645 24.0731275,25.1287183 24.6009229,24.6009229 C25.132398,24.0694478 25.1315432,23.220227 24.6072325,22.6959163 L17.9113162,16 Z';
6
+ export const BigSize = 32;
7
+ export const MediumSize = 24;
8
+ export const SmallSize = 16;
9
+ }
@@ -0,0 +1,11 @@
1
+ import {h} from 'preact';
2
+
3
+ export const SuccessIcon = () => (
4
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
5
+ <path
6
+ fill="#CCC"
7
+ fill-rule="evenodd"
8
+ d="M3.292 1.488L6.69 14.172c.086.32-.076.646-.371.774l-.093.032c-.35.094-.712-.122-.805-.466L2.023 1.828c-.086-.32.076-.646.371-.774l.093-.032c.35-.094.712.122.805.466zm8.868-.055c1.233 0 1.832 1.065 1.208 2.127l-.91 1.55 1.93 2.132c.87.961.373 2.071-.923 2.071H6.76c-.297 0-.558-.2-.635-.486l-1.76-6.568c-.111-.417.203-.826.635-.826h7.16z"
9
+ />
10
+ </svg>
11
+ );
@@ -0,0 +1,12 @@
1
+ import {h} from 'preact';
2
+
3
+ export const DownIcon = () => (
4
+ <svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
5
+ <g id="Icons/16/Arrow/down" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
6
+ <path
7
+ d="M4.78325732,5.37830235 C4.43990319,4.94572127 3.81088342,4.87338855 3.37830235,5.21674268 C2.94572127,5.56009681 2.87338855,6.18911658 3.21674268,6.62169765 L7.21674268,11.6611718 C7.61710439,12.165575 8.38289561,12.165575 8.78325732,11.6611718 L12.7832573,6.62169765 C13.1266115,6.18911658 13.0542787,5.56009681 12.6216977,5.21674268 C12.1891166,4.87338855 11.5600968,4.94572127 11.2167427,5.37830235 L8,9.43097528 L4.78325732,5.37830235 Z"
8
+ id="Path-2"
9
+ fill="#ffffff"></path>
10
+ </g>
11
+ </svg>
12
+ );
@@ -8,32 +8,36 @@
8
8
  height: 100%;
9
9
  display: flex;
10
10
  justify-content: center;
11
+ align-items: center;
11
12
  padding: 60px 32px 32px 32px;
12
13
  color: $white-color;
13
14
  background-color: $root-background;
14
15
  -webkit-backdrop-filter: blur(16px);
15
16
  backdrop-filter: blur(16px);
17
+ z-index: 1;
16
18
  .close-button {
17
19
  position: absolute;
18
20
  top: 32px;
19
21
  right: 32px;
22
+ display: flex;
20
23
  width: 32px;
21
24
  height: 32px;
22
- min-width: 32px;
25
+ padding: 0;
26
+ background: transparent;
27
+ border: none;
23
28
  cursor: pointer;
24
- background-image: url('../../assets/close.svg');
25
29
  &:focus {
26
30
  outline: 1px solid $focus-color;
27
31
  }
28
- }
32
+ }
29
33
  .main-wrapper {
30
- height: 100%;
31
- width: 400px;
34
+ width: 60%;
32
35
  .title {
33
36
  margin-bottom: 8px;
34
37
  font-size: 28px;
35
38
  font-weight: bold;
36
- text-align: center;
39
+ text-align: left;
40
+ line-height: 32px;
37
41
  }
38
42
  .subtitle {
39
43
  margin-top: 16px;
@@ -58,7 +62,7 @@
58
62
  background-color: $semigray-color;
59
63
  }
60
64
  &:focus {
61
- outline: 1px solid $focus-color;
65
+ outline: 1px solid $focus-color;
62
66
  }
63
67
  }
64
68
  .select-wrapper {
@@ -82,12 +86,12 @@
82
86
  font-weight: bold;
83
87
  }
84
88
  .down-arrow {
85
- width: 10px;
86
- height: 10px;
87
- margin-left: 10px;
88
- background-image: url('../../assets/down.svg');
89
- background-position: center;
90
- background-repeat: no-repeat;
89
+ width: 14px;
90
+ margin-left: 8px;
91
+ padding: 0;
92
+ display: flex;
93
+ justify-content: center;
94
+ align-items: center;
91
95
  }
92
96
  }
93
97
  .textarea {
@@ -105,15 +109,18 @@
105
109
  &.active {
106
110
  background-color: $black-color;
107
111
  }
108
- &:-ms-input-placeholderr { /* Internet Explorer 10-11 */
112
+ &:-ms-input-placeholderr {
113
+ /* Internet Explorer 10-11 */
109
114
  color: $gray-color !important;
110
115
  font-size: 15px;
111
116
  opacity: 1;
112
117
  }
113
- &::-ms-input-placeholder { /* Microsoft Edge */
118
+ &::-ms-input-placeholder {
119
+ /* Microsoft Edge */
114
120
  color: $gray-color;
115
121
  }
116
- &::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
122
+ &::placeholder {
123
+ /* Chrome, Firefox, Opera, Safari 10.1+ */
117
124
  color: $gray-color;
118
125
  opacity: 1; /* Firefox */
119
126
  }
@@ -143,22 +150,24 @@
143
150
  color: $character-counter-color;
144
151
  }
145
152
  .submit-button {
146
- width: 88px;
147
153
  height: 32px;
148
- border-radius: 18px;
149
- color: $white-color;
154
+ border-radius: 4px;
155
+ color: white;
150
156
  text-align: center;
151
- font-size: 15px;
157
+ font-size: 14px;
152
158
  font-weight: bold;
153
- background-color: $submit-button-color;
159
+ background-color: #006EFA;
160
+ padding-left: 12px;
161
+ padding-right: 12px;
154
162
  border: none;
155
163
  outline: none !important; // overwrites player styles
156
164
  cursor: pointer;
157
165
  &.disabled {
158
- background-color: $semigray-color;
159
- }
160
- &:hover:not(.disabled) {
161
- background-color: darken($color: $submit-button-color, $amount: 10);
166
+ background-color: rgba(0,0,0,0);
167
+ padding-left: 11px;
168
+ padding-right: 11px;
169
+ color: #888888;
170
+ border: 1px solid #888888;
162
171
  }
163
172
  &:focus {
164
173
  box-shadow: 0px 0px 0px 1px $focus-color;
@@ -166,6 +175,12 @@
166
175
  }
167
176
  }
168
177
  }
178
+
179
+ // TODO: remove once player fix the font
180
+ * {
181
+ font-family: sans-serif;
182
+ font-style: normal;
183
+ }
169
184
  }
170
185
 
171
186
  :global {
@@ -193,3 +208,9 @@
193
208
  }
194
209
  }
195
210
  }
211
+
212
+ // TODO: remove once core team fix alignment of plugin icons
213
+ :global(.playkit-player .playkit-top-bar .playkit-right-controls) {
214
+ display: flex;
215
+ flex-direction: row;
216
+ }
@@ -1,16 +1,13 @@
1
1
  import {h, Component, Fragment} from 'preact';
2
- import {getContribLogger, ObjectUtils} from '@playkit-js-contrib/common';
3
- import {
4
- KeyboardKeys,
5
- Popover,
6
- PopoverHorizontalPositions,
7
- PopoverVerticalPositions,
8
- } from '@playkit-js-contrib/ui';
9
- import {KalturaModerationFlagType} from 'kaltura-typescript-client/api/types';
2
+ import {KeyboardKeys, Popover, PopoverHorizontalPositions, PopoverVerticalPositions} from '../popover';
10
3
  import {PopoverMenu, PopoverMenuItem} from '../popover-menu';
4
+ import {OnClick, A11yWrapper} from '@playkit-js/common';
5
+ import {icons} from '../icons';
11
6
  import * as styles from './moderation.scss';
12
- const {get} = ObjectUtils;
13
- const {Tooltip} = KalturaPlayer.ui.components;
7
+ import {DownIcon} from './down-icon';
8
+
9
+ const {Tooltip, Icon} = KalturaPlayer.ui.components;
10
+ const {withText, Text} = KalturaPlayer.ui.preacti18n;
14
11
 
15
12
  export interface ModerateOption {
16
13
  id: number;
@@ -18,13 +15,18 @@ export interface ModerateOption {
18
15
  }
19
16
 
20
17
  interface ModerationProps {
21
- onClick: () => void;
22
- onSubmit: (contentType: KalturaModerationFlagType, content: string, callBack: () => void) => void;
18
+ onClick: OnClick;
19
+ onSubmit: (contentType: number, content: string, callBack: () => void) => void;
23
20
  reportLength: number;
24
21
  moderateOptions: ModerateOption[];
25
22
  subtitle: string;
26
23
  tooltipMessage: string;
27
24
  closeButtonSelected: boolean;
25
+ sendReportLabel?: string;
26
+ closeLabel?: string;
27
+ reportPlaceholder?: string;
28
+ defaultContentType?: string;
29
+ reportTitle?: string;
28
30
  }
29
31
 
30
32
  interface ModerationState {
@@ -33,28 +35,27 @@ interface ModerationState {
33
35
  isTextareaActive: boolean;
34
36
  }
35
37
 
36
- const logger = getContribLogger({
37
- class: 'Info',
38
- module: 'info-plugin',
39
- });
40
-
41
- const DEFAULT_CONTENT_TYPE = 'Choose a reason for reporting this content';
42
-
43
38
  const initialState: ModerationState = {
44
39
  reportContent: '',
45
40
  reportContentType: -1,
46
- isTextareaActive: false,
41
+ isTextareaActive: false
42
+ };
43
+
44
+ const translates = {
45
+ sendReportLabel: <Text id="moderation.send_report">Report</Text>,
46
+ closeLabel: <Text id="moderation.close">Close</Text>,
47
+ reportPlaceholder: <Text id="moderation.report_placeholder">Describe what you saw...</Text>,
48
+ defaultContentType: <Text id="moderation.default_content_type">Choose a reason for reporting this content</Text>,
49
+ reportTitle: <Text id="moderation.report_title">What’s wrong with this content?</Text>
47
50
  };
48
51
 
52
+ @withText(translates)
49
53
  export class Moderation extends Component<ModerationProps, ModerationState> {
50
- _closeButtonNode: null | HTMLDivElement = null;
54
+ _closeButtonNode: null | HTMLButtonElement = null;
51
55
 
52
- state: ModerationState = { ...initialState };
56
+ state: ModerationState = {...initialState};
53
57
 
54
58
  componentDidMount(): void {
55
- logger.trace('Moderation plugin mount', {
56
- method: 'componentDidMount',
57
- });
58
59
  if (this._closeButtonNode && this.props.closeButtonSelected) {
59
60
  this._closeButtonNode.focus();
60
61
  }
@@ -62,38 +63,32 @@ export class Moderation extends Component<ModerationProps, ModerationState> {
62
63
 
63
64
  private _onContentTypeChange = (id: number) => {
64
65
  this.setState({
65
- reportContentType: id,
66
+ reportContentType: id
66
67
  });
67
68
  };
68
69
 
69
70
  private _onContentChange = (event: any) => {
70
71
  this.setState({
71
- reportContent: event.target.value,
72
+ reportContent: event.target.value
72
73
  });
73
74
  };
74
75
 
75
76
  private _handleFocus = () => {
76
77
  this.setState({
77
- isTextareaActive: true,
78
+ isTextareaActive: true
78
79
  });
79
80
  };
80
81
 
81
82
  private _handleBlur = () => {
82
83
  this.setState((state: ModerationState) => ({
83
- isTextareaActive: state.reportContent.length > 0,
84
+ isTextareaActive: state.reportContent.length > 0
84
85
  }));
85
86
  };
86
87
 
87
88
  private _handleSubmit = (event: any) => {
88
89
  event.preventDefault();
89
90
  const {reportContent, reportContentType} = this.state;
90
- logger.trace('Moderation plugin submit click', {
91
- method: 'handleSubmit',
92
- });
93
91
  if (reportContentType === -1) {
94
- logger.trace('Moderation User did not select reason', {
95
- method: 'handleSubmit',
96
- });
97
92
  return;
98
93
  }
99
94
  this.props.onSubmit(reportContentType, reportContent, () => {
@@ -107,7 +102,7 @@ export class Moderation extends Component<ModerationProps, ModerationState> {
107
102
  e.stopPropagation();
108
103
  }
109
104
  switch (e.keyCode) {
110
- case 13: // Enter pressed
105
+ case KeyboardKeys.Enter: // Enter pressed
111
106
  callBack();
112
107
  break;
113
108
  }
@@ -127,64 +122,43 @@ export class Moderation extends Component<ModerationProps, ModerationState> {
127
122
  private _getPopoverMenuOptions = () => {
128
123
  return this.props.moderateOptions.map(({label, id}: ModerateOption) => ({
129
124
  label: label || '',
130
- onMenuChosen: () => this._onContentTypeChange(id || -1),
125
+ onMenuChosen: () => this._onContentTypeChange(id || -1)
131
126
  }));
132
127
  };
133
128
 
134
129
  private _popoverContent = () => {
135
- return (
136
- <PopoverMenu
137
- itemRenderer={this._popoverMenuItemRenderer}
138
- options={this._getPopoverMenuOptions()}
139
- />
140
- );
141
- };
142
-
143
- private _getContentType = () => {
144
- return (
145
- this.props.moderateOptions.find(
146
- (moderateOption: ModerateOption) =>
147
- moderateOption.id === this.state.reportContentType
148
- ) || {}
149
- );
130
+ return <PopoverMenu itemRenderer={this._popoverMenuItemRenderer} options={this._getPopoverMenuOptions()} />;
150
131
  };
151
132
 
152
- private _handleClose = (event: MouseEvent | KeyboardEvent) => {
153
- if (
154
- event.type === 'keypress' &&
155
- get(event, 'keyCode', null) !== KeyboardKeys.Enter
156
- ) {
157
- return;
158
- }
159
- this.props.onClick();
133
+ private _getContentType = (): any => {
134
+ return this.props.moderateOptions.find((moderateOption: ModerateOption) => moderateOption.id === this.state.reportContentType) || {};
160
135
  };
161
136
 
162
137
  render(props: ModerationProps) {
163
- const {reportLength, subtitle, tooltipMessage} = props;
138
+ const {reportLength, subtitle, tooltipMessage, onClick, closeLabel} = props;
164
139
  const {reportContent, reportContentType, isTextareaActive} = this.state;
165
140
  return (
166
141
  <div className={[styles.root, 'kaltura-moderation__root'].join(' ')}>
167
- <div
168
- className={[
169
- styles.closeButton,
170
- 'kaltura-moderation__close-button',
171
- ].join(' ')}
172
- role="button"
173
- tabIndex={1}
174
- onClick={this._handleClose}
175
- onKeyPress={this._handleClose}
176
- ref={(node: HTMLDivElement | null) => {
177
- this._closeButtonNode = node;
178
- }}
179
- />
142
+ <A11yWrapper onClick={onClick}>
143
+ <button
144
+ aria-label={closeLabel}
145
+ className={[styles.closeButton, 'kaltura-moderation__close-button'].join(' ')}
146
+ tabIndex={1}
147
+ ref={node => {
148
+ this._closeButtonNode = node;
149
+ }}>
150
+ <Icon
151
+ id="moderation-plugin-close-button"
152
+ height={icons.BigSize}
153
+ width={icons.BigSize}
154
+ viewBox={`0 0 ${icons.BigSize} ${icons.BigSize}`}
155
+ path={icons.CLOSE_ICON}
156
+ />
157
+ </button>
158
+ </A11yWrapper>
180
159
  <div className={styles.mainWrapper}>
181
- <div
182
- className={[styles.title, 'kaltura-moderation__title'].join(' ')}>
183
- What’s wrong with this content?
184
- </div>
185
- {subtitle ? (
186
- <div className={[styles.subtitle].join(' ')}>{subtitle}</div>
187
- ) : null}
160
+ <div className={[styles.title, 'kaltura-moderation__title'].join(' ')}>{this.props.reportTitle}</div>
161
+ {subtitle ? <div className={[styles.subtitle].join(' ')}>{subtitle}</div> : null}
188
162
  <Popover
189
163
  className={styles.reportPopover}
190
164
  verticalPosition={PopoverVerticalPositions.Bottom}
@@ -192,43 +166,32 @@ export class Moderation extends Component<ModerationProps, ModerationState> {
192
166
  content={this._popoverContent()}>
193
167
  <Fragment>
194
168
  <button className={styles.selectWrapper} tabIndex={1}>
195
- <div className={styles.select}>
196
- {reportContentType > -1
197
- ? get(this._getContentType(), 'label', '')
198
- : DEFAULT_CONTENT_TYPE}
169
+ <div className={styles.select}>{reportContentType > -1 ? this._getContentType()?.label || '' : this.props.defaultContentType}</div>
170
+ <div className={styles.downArrow}>
171
+ <DownIcon />
199
172
  </div>
200
- <div className={styles.downArrow} />
201
173
  </button>
202
174
  </Fragment>
203
175
  </Popover>
204
- <form onSubmit={this._handleSubmit}>
176
+ <form>
205
177
  <textarea
206
- className={[
207
- styles.textarea,
208
- isTextareaActive ? styles.active : '',
209
- ].join(' ')}
178
+ className={[styles.textarea, isTextareaActive ? styles.active : ''].join(' ')}
210
179
  onInput={this._onContentChange}
211
180
  onFocus={this._handleFocus}
212
181
  onBlur={this._handleBlur}
213
182
  tabIndex={1}
214
- placeholder="Describe what you saw..."
183
+ placeholder={this.props.reportPlaceholder}
215
184
  value={reportContent}
216
185
  maxLength={reportLength}
217
186
  />
218
187
  <div className={styles.submitWrapper}>
219
- <div className={styles.characterCounter}>
220
- {`${reportContent.length}/${reportLength}`}
221
- </div>
188
+ <div className={styles.characterCounter}>{`${reportContent.length}/${reportLength}`}</div>
222
189
  <Tooltip label={tooltipMessage} classNames={styles.tooltip}>
223
- <button
224
- className={[
225
- styles.submitButton,
226
- reportContentType === -1 ? styles.disabled : '',
227
- ].join(' ')}
228
- tabIndex={1}
229
- type="submit">
230
- Report
231
- </button>
190
+ <A11yWrapper onClick={this._handleSubmit}>
191
+ <button className={[styles.submitButton, reportContentType === -1 ? styles.disabled : ''].join(' ')} tabIndex={1}>
192
+ {this.props.sendReportLabel}
193
+ </button>
194
+ </A11yWrapper>
232
195
  </Tooltip>
233
196
  </div>
234
197
  </form>
@@ -1,14 +1,14 @@
1
- .moderation-icon {
2
- background-image: url("../../assets/flag.svg");
3
- width: 32px;
4
- height: 32px;
5
- opacity: 0.8;
6
- cursor: pointer;
7
- background-color: inherit;
8
- border: none;
9
- padding: 0;
10
- &:hover,
11
- &:focus {
12
- opacity: 1;
13
- }
14
- }
1
+ .pluginButton {
2
+ display: flex;
3
+ width: 36px;
4
+ height: 36px;
5
+ padding: 0;
6
+ background: transparent;
7
+ border: none;
8
+ border-radius: 4px;
9
+ cursor: pointer;
10
+ }
11
+
12
+ :global(.playkit-player .playkit-top-bar .playkit-right-controls) {
13
+ display: flex;
14
+ }
@@ -1,6 +1,29 @@
1
1
  import {h} from 'preact';
2
2
  import * as styles from './plugin-button.scss';
3
+ import {icons} from '../icons';
4
+ import {A11yWrapper, OnClick} from '@playkit-js/common';
3
5
 
4
- export const PluginButton = () => (
5
- <button className={styles.moderationIcon} tabIndex={1} />
6
- );
6
+ const {Tooltip, Icon} = KalturaPlayer.ui.components;
7
+
8
+ interface PluginButtonProps {
9
+ onClick: OnClick;
10
+ label?: string;
11
+ }
12
+
13
+ export const PluginButton = ({onClick, label}: PluginButtonProps) => {
14
+ return (
15
+ <Tooltip label={label} type="bottom">
16
+ <A11yWrapper onClick={onClick}>
17
+ <button aria-label={label} className={styles.pluginButton}>
18
+ <Icon
19
+ id="moderation-plugin-button"
20
+ height={icons.BigSize}
21
+ width={icons.BigSize}
22
+ viewBox={`0 0 ${icons.BigSize} ${icons.BigSize}`}
23
+ path={icons.PLUGIN_ICON}
24
+ />
25
+ </button>
26
+ </A11yWrapper>
27
+ </Tooltip>
28
+ );
29
+ };