@playkit-js/moderation 2.0.9
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 +50 -0
- package/LICENSE +661 -0
- package/README.md +12 -0
- package/dist/playkit-moderation.js +24 -0
- package/dist/playkit-moderation.js.map +1 -0
- package/package.json +77 -0
- package/src/assets/.gitkeep +0 -0
- package/src/assets/close.svg +10 -0
- package/src/assets/down.svg +9 -0
- package/src/assets/error.svg +3 -0
- package/src/assets/flag.svg +6 -0
- package/src/assets/report.svg +3 -0
- package/src/components/.gitkeep +0 -0
- package/src/components/moderation/assets/down.svg +9 -0
- package/src/components/moderation/index.ts +1 -0
- package/src/components/moderation/moderation.scss +195 -0
- package/src/components/moderation/moderation.tsx +239 -0
- package/src/components/plugin-button/index.ts +1 -0
- package/src/components/plugin-button/plugin-button.scss +14 -0
- package/src/components/plugin-button/plugin-button.tsx +6 -0
- package/src/components/popover-menu/index.ts +1 -0
- package/src/components/popover-menu/popover-menu.scss +4 -0
- package/src/components/popover-menu/popover-menu.tsx +52 -0
- package/src/global.d.ts +11 -0
- package/src/index.ts +1 -0
- package/src/moderation-plugin.scss +13 -0
- package/src/moderation-plugin.tsx +241 -0
- package/src/variables.scss +8 -0
|
@@ -0,0 +1,13 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import {h, ComponentChild} from 'preact';
|
|
2
|
+
import {
|
|
3
|
+
ContribPluginManager,
|
|
4
|
+
CorePlugin,
|
|
5
|
+
OnMediaLoad,
|
|
6
|
+
OnMediaUnload,
|
|
7
|
+
OnPluginSetup,
|
|
8
|
+
ContribServices,
|
|
9
|
+
ContribPluginData,
|
|
10
|
+
ContribPluginConfigs,
|
|
11
|
+
} from '@playkit-js-contrib/plugin';
|
|
12
|
+
import {
|
|
13
|
+
UpperBarItem,
|
|
14
|
+
OverlayItem,
|
|
15
|
+
OverlayPositions,
|
|
16
|
+
ToastSeverity,
|
|
17
|
+
} from '@playkit-js-contrib/ui';
|
|
18
|
+
import {getContribLogger} from '@playkit-js-contrib/common';
|
|
19
|
+
import {KalturaModerationFlagType} from 'kaltura-typescript-client/api/types/KalturaModerationFlagType';
|
|
20
|
+
import {BaseEntryFlagAction} from 'kaltura-typescript-client/api/types/BaseEntryFlagAction';
|
|
21
|
+
import {KalturaClient} from 'kaltura-typescript-client';
|
|
22
|
+
import {KalturaModerationFlag} from 'kaltura-typescript-client/api/types/KalturaModerationFlag';
|
|
23
|
+
import {Moderation, ModerateOption} from './components/moderation';
|
|
24
|
+
import {PluginButton} from './components/plugin-button';
|
|
25
|
+
import * as styles from './moderation-plugin.scss';
|
|
26
|
+
|
|
27
|
+
const pluginName = `playkit-js-moderation`;
|
|
28
|
+
|
|
29
|
+
const logger = getContribLogger({
|
|
30
|
+
class: 'ModerationPlugin',
|
|
31
|
+
module: 'moderation-plugin',
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
interface ModerationPluginConfig {
|
|
35
|
+
reportLength: number;
|
|
36
|
+
onReportSentMessage: string;
|
|
37
|
+
onReportErrorMessage: string;
|
|
38
|
+
notificatonDuration: number;
|
|
39
|
+
moderateOptions: ModerateOption[];
|
|
40
|
+
subtitle: string;
|
|
41
|
+
tooltipMessage: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class ModerationPlugin
|
|
45
|
+
implements OnMediaLoad, OnMediaUnload, OnPluginSetup {
|
|
46
|
+
private _upperBarItem: UpperBarItem | null = null;
|
|
47
|
+
private _moderationOverlay: OverlayItem | null = null;
|
|
48
|
+
private _wasPlayed = false; // keep state of the player so we can resume if needed
|
|
49
|
+
private _kalturaClient = new KalturaClient();
|
|
50
|
+
|
|
51
|
+
constructor(
|
|
52
|
+
private _corePlugin: CorePlugin,
|
|
53
|
+
private _contribServices: ContribServices,
|
|
54
|
+
private _configs: ContribPluginConfigs<ModerationPluginConfig>,
|
|
55
|
+
private _player: KalturaPlayerTypes.Player
|
|
56
|
+
) {}
|
|
57
|
+
|
|
58
|
+
onPluginSetup(): void {
|
|
59
|
+
const {playerConfig} = this._configs;
|
|
60
|
+
|
|
61
|
+
this._kalturaClient.setOptions({
|
|
62
|
+
clientTag: 'playkit-js-transcript',
|
|
63
|
+
endpointUrl: playerConfig.provider.env.serviceUrl,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
this._kalturaClient.setDefaultRequestOptions({
|
|
67
|
+
ks: playerConfig.session.ks,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
onMediaLoad(): void {
|
|
72
|
+
logger.trace('Moderation plugin loaded', {
|
|
73
|
+
method: 'onMediaLoad',
|
|
74
|
+
});
|
|
75
|
+
this._addPluginIcon();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
onMediaUnload(): void {
|
|
79
|
+
if (this._upperBarItem) {
|
|
80
|
+
logger.trace('Moderation plugin unloaded', {
|
|
81
|
+
method: 'onMediaUnload',
|
|
82
|
+
});
|
|
83
|
+
this._moderationOverlay = null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private _sentReport = (
|
|
88
|
+
contentType: KalturaModerationFlagType,
|
|
89
|
+
content: string,
|
|
90
|
+
callback?: () => void
|
|
91
|
+
) => {
|
|
92
|
+
const {
|
|
93
|
+
playerConfig,
|
|
94
|
+
pluginConfig: {onReportSentMessage, onReportErrorMessage},
|
|
95
|
+
} = this._configs;
|
|
96
|
+
const request = new BaseEntryFlagAction({
|
|
97
|
+
moderationFlag: new KalturaModerationFlag({
|
|
98
|
+
flaggedEntryId: playerConfig.sources.id,
|
|
99
|
+
flagType: contentType,
|
|
100
|
+
comments: content,
|
|
101
|
+
}),
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
this._kalturaClient.request(request).then(
|
|
105
|
+
() => {
|
|
106
|
+
logger.trace('Moderation plugin submit OK', {
|
|
107
|
+
method: 'handleSubmit',
|
|
108
|
+
});
|
|
109
|
+
this._toggleOverlay();
|
|
110
|
+
this._displayToast({
|
|
111
|
+
text: onReportSentMessage,
|
|
112
|
+
icon: (
|
|
113
|
+
<div className={[styles.toastIcon, styles.success].join(' ')} />
|
|
114
|
+
),
|
|
115
|
+
severity: ToastSeverity.Success,
|
|
116
|
+
});
|
|
117
|
+
if (this._wasPlayed) {
|
|
118
|
+
this._player.play();
|
|
119
|
+
}
|
|
120
|
+
if (callback) {
|
|
121
|
+
callback();
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
error => {
|
|
125
|
+
logger.trace('Moderation plugin submit failed', {
|
|
126
|
+
method: 'handleSubmit',
|
|
127
|
+
data: error,
|
|
128
|
+
});
|
|
129
|
+
this._toggleOverlay();
|
|
130
|
+
this._displayToast({
|
|
131
|
+
text: onReportErrorMessage,
|
|
132
|
+
icon: <div className={[styles.toastIcon, styles.error].join(' ')} />,
|
|
133
|
+
severity: ToastSeverity.Error,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
private _displayToast = (options: {
|
|
140
|
+
text: string;
|
|
141
|
+
icon: ComponentChild;
|
|
142
|
+
severity: ToastSeverity;
|
|
143
|
+
}): void => {
|
|
144
|
+
const {notificatonDuration} = this._configs.pluginConfig;
|
|
145
|
+
//display toast
|
|
146
|
+
this._contribServices.toastManager.add({
|
|
147
|
+
title: 'Report Content',
|
|
148
|
+
text: options.text,
|
|
149
|
+
icon: options.icon,
|
|
150
|
+
duration: notificatonDuration,
|
|
151
|
+
severity: ToastSeverity.Success || ToastSeverity.Error,
|
|
152
|
+
onClick: () => {
|
|
153
|
+
logger.trace(`Moderation clicked on toast`, {
|
|
154
|
+
method: '_displayToast',
|
|
155
|
+
});
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
private _toggleOverlay = (event?: MouseEvent) => {
|
|
161
|
+
let closeButtonSelected = false;
|
|
162
|
+
if (event && event.x === 0 && event.y === 0) {
|
|
163
|
+
// triggered by keyboard
|
|
164
|
+
closeButtonSelected = true;
|
|
165
|
+
}
|
|
166
|
+
const {reportLength, moderateOptions, subtitle, tooltipMessage} = this._configs.pluginConfig;
|
|
167
|
+
const isPlaying = !(this._player as any).paused;
|
|
168
|
+
logger.trace(`Moderation toggle overlay player`, {
|
|
169
|
+
method: '_toggleOverlay',
|
|
170
|
+
});
|
|
171
|
+
if (this._moderationOverlay) {
|
|
172
|
+
this._contribServices.overlayManager.remove(this._moderationOverlay);
|
|
173
|
+
this._moderationOverlay = null;
|
|
174
|
+
if (this._wasPlayed) {
|
|
175
|
+
logger.trace(`Moderation plugin paused player`, {
|
|
176
|
+
method: '_toggleOverlay',
|
|
177
|
+
});
|
|
178
|
+
this._wasPlayed = false;
|
|
179
|
+
this._player.play();
|
|
180
|
+
}
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (isPlaying) {
|
|
184
|
+
this._wasPlayed = true;
|
|
185
|
+
this._player.pause();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
this._moderationOverlay = this._contribServices.overlayManager.add({
|
|
189
|
+
label: 'moderation-overlay',
|
|
190
|
+
position: OverlayPositions.PlayerArea,
|
|
191
|
+
renderContent: () => (
|
|
192
|
+
<Moderation
|
|
193
|
+
onClick={this._toggleOverlay}
|
|
194
|
+
onSubmit={this._sentReport}
|
|
195
|
+
reportLength={reportLength}
|
|
196
|
+
subtitle={subtitle}
|
|
197
|
+
tooltipMessage={tooltipMessage}
|
|
198
|
+
moderateOptions={moderateOptions}
|
|
199
|
+
closeButtonSelected={closeButtonSelected}
|
|
200
|
+
/>
|
|
201
|
+
),
|
|
202
|
+
});
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
private _addPluginIcon(): void {
|
|
206
|
+
const {} = this._configs.pluginConfig;
|
|
207
|
+
this._upperBarItem = this._contribServices.upperBarManager.add({
|
|
208
|
+
label: 'Moderation',
|
|
209
|
+
onClick: this._toggleOverlay,
|
|
210
|
+
renderItem: () => <PluginButton />,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
ContribPluginManager.registerPlugin(
|
|
216
|
+
pluginName,
|
|
217
|
+
(data: ContribPluginData<ModerationPluginConfig>) => {
|
|
218
|
+
return new ModerationPlugin(
|
|
219
|
+
data.corePlugin,
|
|
220
|
+
data.contribServices,
|
|
221
|
+
data.configs,
|
|
222
|
+
data.player
|
|
223
|
+
);
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
defaultConfig: {
|
|
227
|
+
reportLength: 500,
|
|
228
|
+
onReportSentMessage: 'Send report',
|
|
229
|
+
onReportErrorMessage: 'The report failed to send',
|
|
230
|
+
subtitle: '',
|
|
231
|
+
notificatonDuration: 5000,
|
|
232
|
+
tooltipMessage: 'Send report',
|
|
233
|
+
moderateOptions: [
|
|
234
|
+
{id: 1, label: 'Sexual Content'},
|
|
235
|
+
{id: 2, label: 'Violent Or Repulsive'},
|
|
236
|
+
{id: 3, label: 'Harmful Or Dangerous Act'},
|
|
237
|
+
{id: 4, label: 'Spam / Commercials'},
|
|
238
|
+
],
|
|
239
|
+
},
|
|
240
|
+
}
|
|
241
|
+
);
|