@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.
- package/CHANGELOG.md +14 -0
- package/LICENSE +5 -5
- package/README.md +174 -8
- package/dist/playkit-moderation.js +1 -23
- package/dist/playkit-moderation.js.map +1 -1
- package/package.json +51 -53
- package/src/components/icons/error-icon.tsx +11 -0
- package/src/components/icons/index.ts +9 -0
- package/src/components/icons/success-icon.tsx +11 -0
- package/src/components/moderation/down-icon.tsx +12 -0
- package/src/components/moderation/moderation.scss +46 -25
- package/src/components/moderation/moderation.tsx +67 -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/global.d.ts +6 -6
- package/src/index.ts +14 -1
- package/src/moderation-plugin.scss +4 -12
- package/src/moderation-plugin.tsx +132 -161
- 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/down.svg +0 -9
- package/src/assets/error.svg +0 -3
- package/src/assets/flag.svg +0 -6
- package/src/assets/report.svg +0 -3
- package/src/components/.gitkeep +0 -0
- 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.
|
|
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
|
-
"@
|
|
27
|
-
"@
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"husky": "
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
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
|
-
"
|
|
49
|
-
"build": "
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
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
|
-
"
|
|
70
|
-
"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
"
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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:
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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 {
|
|
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 {
|
|
118
|
+
&::-ms-input-placeholder {
|
|
119
|
+
/* Microsoft Edge */
|
|
114
120
|
color: $gray-color;
|
|
115
121
|
}
|
|
116
|
-
&::placeholder {
|
|
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:
|
|
149
|
-
color:
|
|
154
|
+
border-radius: 4px;
|
|
155
|
+
color: white;
|
|
150
156
|
text-align: center;
|
|
151
|
-
font-size:
|
|
157
|
+
font-size: 14px;
|
|
152
158
|
font-weight: bold;
|
|
153
|
-
background-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:
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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 {
|
|
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
|
-
|
|
13
|
-
|
|
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:
|
|
22
|
-
onSubmit: (contentType:
|
|
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 |
|
|
54
|
+
_closeButtonNode: null | HTMLButtonElement = null;
|
|
51
55
|
|
|
52
|
-
state: ModerationState = {
|
|
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
|
|
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
|
|
153
|
-
|
|
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
|
-
<
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
'kaltura-moderation__close-button'
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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
|
-
|
|
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
|
-
|
|
197
|
-
|
|
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
|
|
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=
|
|
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
|
-
<
|
|
224
|
-
className={[
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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
|
-
.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
5
|
-
|
|
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
|
+
};
|