@playkit-js/transcript 2.1.4 → 2.1.5-canary.16-1ac3e09

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 (61) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +5 -5
  3. package/README.md +122 -24
  4. package/dist/1501adfdf5c835667ce7.svg +9 -0
  5. package/dist/301e7a199b2cd06c2edf.svg +9 -0
  6. package/dist/33bce27c0f546e80478c.svg +36 -0
  7. package/dist/6a4867d3d9170cc2a24d.svg +9 -0
  8. package/dist/73bab0af28a1c7aed29f.svg +9 -0
  9. package/dist/84087eb1cff72e5e6bd3.svg +9 -0
  10. package/dist/95d7192dc427afb678d0.svg +9 -0
  11. package/dist/cea5d6a7f050cbd199a1.svg +9 -0
  12. package/dist/d93f06ff32cdfcd016df.svg +9 -0
  13. package/dist/e5496f4c01207db44ffc.svg +9 -0
  14. package/dist/playkit-transcript.js +1 -31
  15. package/dist/playkit-transcript.js.map +1 -1
  16. package/package.json +53 -50
  17. package/src/components/a11y-wrapper/a11y-wrapper.ts +26 -0
  18. package/src/components/a11y-wrapper/index.ts +1 -0
  19. package/src/components/caption/caption.scss +1 -1
  20. package/src/components/caption/caption.tsx +118 -140
  21. package/src/components/caption/index.ts +1 -1
  22. package/src/components/caption-list/captionList.scss +8 -8
  23. package/src/components/caption-list/captionList.tsx +115 -117
  24. package/src/components/caption-list/index.ts +1 -1
  25. package/src/components/close-button/close-button.scss +11 -0
  26. package/src/components/close-button/index.tsx +23 -0
  27. package/src/components/download-print-menu/download-print-menu.scss +49 -48
  28. package/src/components/download-print-menu/download-print-menu.tsx +147 -125
  29. package/src/components/download-print-menu/index.ts +1 -1
  30. package/src/components/icons/index.ts +11 -0
  31. package/src/components/plugin-button/plugin-button.scss +26 -0
  32. package/src/components/plugin-button/plugin-button.tsx +29 -0
  33. package/src/components/popover-menu/index.ts +1 -1
  34. package/src/components/popover-menu/popover-menu.scss +3 -3
  35. package/src/components/popover-menu/popover-menu.tsx +25 -25
  36. package/src/components/search/index.ts +1 -1
  37. package/src/components/search/search.scss +1 -1
  38. package/src/components/search/search.tsx +137 -144
  39. package/src/components/spinner/index.ts +1 -1
  40. package/src/components/spinner/spinner.scss +58 -50
  41. package/src/components/spinner/spinner.tsx +9 -9
  42. package/src/components/transcript/index.ts +1 -1
  43. package/src/components/transcript/transcript.scss +9 -33
  44. package/src/components/transcript/transcript.tsx +333 -454
  45. package/src/global.d.ts +6 -6
  46. package/src/index.ts +13 -1
  47. package/src/transcript-plugin.scss +3 -3
  48. package/src/transcript-plugin.tsx +210 -391
  49. package/src/types/index.ts +3 -0
  50. package/src/types/transcript-config.ts +11 -0
  51. package/src/types/transcript-item-data.ts +29 -0
  52. package/src/types/types-ui.ts +11 -0
  53. package/src/utils/debounce.ts +36 -0
  54. package/src/utils/index.ts +4 -0
  55. package/src/utils/object-utils.ts +34 -0
  56. package/src/utils/popover/popover.scss +30 -0
  57. package/src/utils/popover/popover.tsx +178 -0
  58. package/src/utils/utils.ts +86 -0
  59. package/src/variables.scss +14 -0
  60. package/src/assets/close.svg +0 -10
  61. package/src/utils.ts +0 -192
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@playkit-js/transcript",
3
- "version": "2.1.4",
3
+ "version": "2.1.5-canary.16-1ac3e09",
4
+ "main": "dist/playkit-transcript.js",
4
5
  "license": "AGPL-3.0",
5
6
  "private": false,
6
7
  "bugs": {
@@ -11,67 +12,69 @@
11
12
  "type": "git",
12
13
  "url": "git+https://github.com/kaltura/playkit-js-transcript.git"
13
14
  },
14
- "dependencies": {
15
- "@playkit-js-contrib/cli": "1.1.0",
16
- "@playkit-js-contrib/common": "^4.1.10",
17
- "@playkit-js-contrib/plugin": "^4.1.13",
18
- "@playkit-js-contrib/ui": "^4.1.13",
19
- "classnames": "2.2.6",
20
- "kaltura-typescript-client": "file:libs/kaltura-typescript-client-7.0.2-v20201028-171103.tgz",
21
- "xml-js": "^1.6.11"
22
- },
23
15
  "devDependencies": {
24
- "@commitlint/cli": "8.3.5",
25
- "@commitlint/config-conventional": "8.3.4",
26
- "@types/classnames": "2.2.9",
27
- "@types/node": "13.7.6",
28
- "@typescript-eslint/eslint-plugin": "2.21.0",
29
- "@typescript-eslint/parser": "2.21.0",
30
- "conventional-github-releaser": "^3.1.3",
31
- "husky": "3.1.0",
16
+ "@typescript-eslint/eslint-plugin": "^5.23.0",
17
+ "@typescript-eslint/parser": "^5.23.0",
18
+ "conventional-github-releaser": "3.1.3",
19
+ "cross-env": "^7.0.3",
20
+ "css-loader": "^6.7.1",
21
+ "documentation": "^13.2.5",
22
+ "husky": "^8.0.1",
23
+ "jest": "^28.1.0",
24
+ "kaltura-player-js": "https://github.com/kaltura/kaltura-player-js.git#master",
25
+ "lint-staged": "^12.4.1",
26
+ "node-sass": "^7.0.1",
32
27
  "preact": "^10.4.1",
33
- "tslint": "5.20.1",
34
- "typescript": "3.8.2"
28
+ "prettier": "^2.6.2",
29
+ "sass-loader": "^12.6.0",
30
+ "standard-version": "^9.3.2",
31
+ "style-loader": "1.3.0",
32
+ "ts-loader": "^9.3.0",
33
+ "tslint": "^6.1.3",
34
+ "typescript": "^4.6.4",
35
+ "uglifyjs-webpack-plugin": "^2.2.0",
36
+ "webpack": "^5.72.1",
37
+ "webpack-cli": "^4.9.2",
38
+ "webpack-dev-server": "^4.9.0"
39
+ },
40
+ "peerDependencies": {
41
+ "kaltura-player-js": "https://github.com/kaltura/kaltura-player-js.git#master"
35
42
  },
36
43
  "scripts": {
37
- "clean": "rm -rf dist",
38
- "reset": "npm run clean && rm -rf node_modules",
39
- "build": "kcontrib build",
40
- "build:dev": "kcontrib build --dev",
41
- "bump-canary": "standard-version --prerelease canary --skip.commit=true --skip.tag=true",
42
- "serve": "kcontrib serve",
43
- "analyze": "npm run build && npx source-map-explorer dist/playkit-transcript.js",
44
- "lint": "tsc --noEmit && eslint ./src --ext .ts,.tsx",
45
- "lint:fix": "tsc --noEmit && eslint ./src --ext .ts,.tsx --fix",
46
- "husky:pre-commit": "lint-staged",
47
- "husky:commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
48
- "deploy:prepare": "kcontrib deploy --prepare",
49
- "contrib:latest": "kcontrib contrib --type=latest",
50
- "infra:latest": "kcontrib infra --type=latest",
51
- "infra:next": "kcontrib infra --type=next",
52
- "infra:local": "kcontrib infra --type=local",
53
- "infra:add": "kcontrib infra --add"
44
+ "clean": "rm -rf ./dist",
45
+ "prebuild": "npm run clean",
46
+ "build": "webpack --mode production",
47
+ "dev": "webpack-dev-server --mode development",
48
+ "watch": "webpack --progress --color --watch --mode development",
49
+ "test": "jest",
50
+ "release": "standard-version",
51
+ "pushTaggedRelease": "git push --follow-tags --no-verify origin master",
52
+ "eslint": "eslint . --color",
53
+ "commit:dist": "git add --force --all dist && (git commit -m 'chore: update dist' || exit 0)",
54
+ "docs:generate": "documentation build flow-typed/** src/** -f md -o docs/configuration.md",
55
+ "docs:serve": "documentation serve flow-typed/** src/** --watch",
56
+ "precommit": "lint-staged",
57
+ "prettier:fix": "prettier --write ."
54
58
  },
55
59
  "publishConfig": {
56
60
  "access": "public"
57
61
  },
58
- "browserslist": {
59
- "production": [
60
- ">0.2%",
61
- "not dead",
62
- "not op_mini all"
63
- ],
64
- "development": [
65
- "last 1 chrome version",
66
- "last 1 firefox version",
67
- "last 1 safari version"
68
- ]
69
- },
70
62
  "files": [
71
63
  "dist",
72
64
  "LICENSE",
73
65
  "README.md",
74
66
  "CHANGELOG.md",
75
67
  "src"
76
- ]
68
+ ],
69
+ "keywords": [
70
+ "transcript",
71
+ "kaltura",
72
+ "player",
73
+ "playkit-js",
74
+ "playkit-js-transcript",
75
+ "html5 player"
76
+ ],
77
+ "dependencies": {
78
+ "stream-browserify": "^3.0.0"
79
+ }
77
80
  }
@@ -0,0 +1,26 @@
1
+ import {cloneElement, VNode} from 'preact';
2
+
3
+ const {ENTER, SPACE} = KalturaPlayer.ui.utils.KeyMap;
4
+
5
+ export type OnClickEvent = KeyboardEvent | MouseEvent;
6
+ export type OnClick = (e: OnClickEvent, byKeyboard?: boolean) => void;
7
+
8
+ interface A11yWrapperProps {
9
+ children: VNode;
10
+ onClick: OnClick;
11
+ }
12
+
13
+ export const A11yWrapper = ({children, onClick}: A11yWrapperProps) => {
14
+ return cloneElement(children, {
15
+ onKeyDown: (e: KeyboardEvent) => {
16
+ if ([SPACE, ENTER].includes(e.keyCode)) {
17
+ e.preventDefault();
18
+ onClick(e, true);
19
+ }
20
+ },
21
+ onClick: (e: MouseEvent) => {
22
+ e.stopPropagation();
23
+ onClick(e);
24
+ }
25
+ });
26
+ };
@@ -0,0 +1 @@
1
+ export * from './a11y-wrapper';
@@ -75,4 +75,4 @@
75
75
  }
76
76
  }
77
77
  }
78
- }
78
+ }
@@ -1,161 +1,139 @@
1
- import { h, Component } from "preact";
2
- import { KeyboardKeys } from "@playkit-js-contrib/ui";
3
- import * as styles from "./caption.scss";
4
- import { secontsToTime, CaptionItem } from "../../utils";
1
+ import * as styles from './caption.scss';
2
+ import {secontsToTime} from '../../utils';
3
+ import {CuePointData} from '../../types';
4
+
5
+ const {ENTER, Space} = KalturaPlayer.ui.utils.KeyMap;
6
+
7
+ import {Component, h} from 'preact';
5
8
 
6
9
  export interface CaptionProps {
7
- showTime: boolean;
8
- searchLength: number;
9
- scrollTo(el: HTMLElement): void;
10
- scrollToSearchMatch(el: HTMLElement): void;
11
- videoDuration: number;
10
+ showTime: boolean;
11
+ searchLength: number;
12
+ scrollTo(el: HTMLElement): void;
13
+ scrollToSearchMatch(el: HTMLElement): void;
14
+ videoDuration: number;
12
15
  }
13
16
 
14
17
  interface ExtendedCaptionProps extends CaptionProps {
15
- caption: CaptionItem;
16
- onClick(): void;
17
- highlighted: boolean;
18
- shouldScroll: boolean;
19
- shouldScrollToSearchMatch: boolean;
20
- indexMap: Record<string, number> | undefined;
21
- activeSearchIndex: number;
22
- longerThanHour: boolean;
23
- isAutoScrollEnabled: boolean;
18
+ caption: CuePointData;
19
+ onClick: () => void;
20
+ highlighted: boolean;
21
+ shouldScroll: boolean;
22
+ shouldScrollToSearchMatch: boolean;
23
+ indexMap: Record<string, number> | undefined;
24
+ activeSearchIndex: number;
25
+ longerThanHour: boolean;
26
+ isAutoScrollEnabled: boolean;
24
27
  }
25
28
 
26
29
  export class Caption extends Component<ExtendedCaptionProps> {
27
- private _hotspotRef: HTMLElement | null = null;
30
+ private _hotspotRef: HTMLElement | null = null;
28
31
 
29
- componentDidUpdate() {
30
- if (this._hotspotRef && this.props.shouldScroll) {
31
- this.props.scrollTo(this._hotspotRef);
32
- } else if (this._hotspotRef && this.props.shouldScrollToSearchMatch) {
33
- this.props.scrollToSearchMatch(this._hotspotRef);
34
- }
32
+ componentDidUpdate() {
33
+ if (this._hotspotRef && this.props.shouldScroll) {
34
+ this.props.scrollTo(this._hotspotRef);
35
+ } else if (this._hotspotRef && this.props.shouldScrollToSearchMatch) {
36
+ this.props.scrollToSearchMatch(this._hotspotRef);
35
37
  }
38
+ }
36
39
 
37
- shouldComponentUpdate(nextProps: ExtendedCaptionProps) {
38
- const {
39
- indexMap,
40
- highlighted,
41
- isAutoScrollEnabled,
42
- activeSearchIndex,
43
- longerThanHour,
44
- } = this.props;
45
- if (longerThanHour !== nextProps.longerThanHour) {
46
- return true;
47
- }
48
- if (highlighted !== nextProps.highlighted) {
49
- return true;
50
- }
51
- if (highlighted && isAutoScrollEnabled !== nextProps.isAutoScrollEnabled) {
52
- return true;
53
- }
54
- if (indexMap !== nextProps.indexMap) {
55
- return true;
56
- }
57
- if (indexMap && nextProps.indexMap && indexMap[activeSearchIndex] !== nextProps.indexMap[nextProps.activeSearchIndex]) {
58
- return true;
59
- }
60
- return false;
40
+ shouldComponentUpdate(nextProps: ExtendedCaptionProps) {
41
+ const {indexMap, highlighted, isAutoScrollEnabled, activeSearchIndex, longerThanHour, caption} = this.props;
42
+ if (longerThanHour !== nextProps.longerThanHour) {
43
+ return true;
61
44
  }
62
-
63
- private _handleKeyPress = (event: KeyboardEvent) => {
64
- const keyCode = event.which || event.keyCode;
65
- if (
66
- keyCode === KeyboardKeys.Enter ||
67
- keyCode === KeyboardKeys.Space
68
- ) {
69
- event.preventDefault();
70
- this._gotoCurrentTime();
71
- return;
72
- }
45
+ if (highlighted !== nextProps.highlighted) {
46
+ return true;
73
47
  }
74
-
75
- private _handleClick = (event: MouseEvent) => {
76
- event.stopPropagation();
77
- this._hotspotRef?.focus();
78
- this._gotoCurrentTime();
48
+ if (highlighted && isAutoScrollEnabled !== nextProps.isAutoScrollEnabled) {
49
+ return true;
50
+ }
51
+ if (indexMap !== nextProps.indexMap) {
52
+ return true;
79
53
  }
54
+ if (indexMap && nextProps.indexMap && indexMap[activeSearchIndex] !== nextProps.indexMap[nextProps.activeSearchIndex]) {
55
+ return true;
56
+ }
57
+ return false;
58
+ }
80
59
 
81
- private _gotoCurrentTime = () => {
82
- const { caption, onClick } = this.props;
83
- if (caption.text.length) {
84
- onClick();
85
- }
60
+ private _handleKeyPress = (event: KeyboardEvent) => {
61
+ const keyCode = event.which || event.keyCode;
62
+ if (keyCode === ENTER || keyCode === Space) {
63
+ event.preventDefault();
64
+ this._gotoCurrentTime();
65
+ return;
86
66
  }
67
+ };
87
68
 
88
- private _renderText = (text: string) => {
89
- const { activeSearchIndex, searchLength, indexMap } = this.props;
90
- let indexArray: string[] = [];
91
- if (indexMap) {
92
- indexArray = Object.keys(indexMap).sort((a, b) => Number(a) - Number(b));
93
- }
94
- if (text.length === 0) {
95
- return null;
96
- }
97
- return (
98
- <span className={styles.captionSpan}>
99
- {indexMap
100
- ? indexArray.map((el: string, index: number) => {
101
- const preSelected = index === 0 ? text.substring(0, indexMap[el]) : "";
102
- const selected = text.substring(
103
- indexMap[el],
104
- indexMap[el] + searchLength
105
- );
106
- const postSelected = text.substring(
107
- indexMap[el] + searchLength,
108
- index - 1 === indexArray.length
109
- ? text.length
110
- : indexMap[indexArray[index + 1]]
111
- );
112
- return (
113
- <span>
114
- {preSelected}
115
- <span
116
- className={
117
- Number(el) === activeSearchIndex
118
- ? styles.activeSearch
119
- : styles.highlightSearch
120
- }
121
- >
122
- {selected}
123
- </span>
124
- {postSelected}
125
- </span>
126
- );
127
- })
128
- : text}
129
- </span>
130
- );
131
- };
69
+ private _handleClick = (event: MouseEvent) => {
70
+ event.stopPropagation();
71
+ this._hotspotRef?.focus();
72
+ this._gotoCurrentTime();
73
+ };
132
74
 
133
- render() {
134
- const { caption, highlighted, showTime, longerThanHour } = this.props;
135
- const { text, startTime } = caption;
75
+ private _gotoCurrentTime = () => {
76
+ const {caption, onClick} = this.props;
77
+ if (caption.text.length) {
78
+ onClick();
79
+ }
80
+ };
136
81
 
137
- return (
138
- <div
139
- className={styles.caption}
140
- tabIndex={1}
141
- ref={node => {
142
- this._hotspotRef = node;
143
- }}
144
- onKeyDown={this._handleKeyPress}
145
- >
146
- {showTime && (
147
- <div className={styles.captionTime}>
148
- {secontsToTime(startTime, longerThanHour)}
149
- </div>
150
- )}
151
- <div
152
- onClick={this._handleClick}
153
- className={`${styles.captionContent} ${highlighted ? styles.highlighted : ""} ${showTime ? "" : styles.withoutTime}`}
154
- role="button"
155
- >
156
- {this._renderText(text)}
157
- </div>
158
- </div>
159
- );
82
+ private _renderText = (text: string) => {
83
+ const {activeSearchIndex, searchLength, indexMap} = this.props;
84
+ let indexArray: string[] = [];
85
+ if (indexMap) {
86
+ indexArray = Object.keys(indexMap).sort((a, b) => Number(a) - Number(b));
87
+ }
88
+ if (text?.length === 0) {
89
+ return null;
160
90
  }
91
+ return (
92
+ <span className={styles.captionSpan}>
93
+ {indexMap
94
+ ? indexArray.map((el: string, index: number) => {
95
+ const preSelected = index === 0 ? text.substring(0, indexMap[el]) : '';
96
+ const selected = text.substring(indexMap[el], indexMap[el] + searchLength);
97
+ const postSelected = text.substring(
98
+ indexMap[el] + searchLength,
99
+ index - 1 === indexArray.length ? text.length : indexMap[indexArray[index + 1]]
100
+ );
101
+ return (
102
+ <span>
103
+ {preSelected}
104
+ <span className={Number(el) === activeSearchIndex ? styles.activeSearch : styles.highlightSearch}>{selected}</span>
105
+ {postSelected}
106
+ </span>
107
+ );
108
+ })
109
+ : text}
110
+ </span>
111
+ );
112
+ };
113
+
114
+ render() {
115
+ const {caption, highlighted, showTime, longerThanHour} = this.props;
116
+ const {startTime, id} = caption;
117
+ const isHighlighted = Object.keys(highlighted)[0] === id;
118
+
119
+ return (
120
+ <div
121
+ className={styles.caption}
122
+ tabIndex={1}
123
+ ref={node => {
124
+ this._hotspotRef = node;
125
+ }}
126
+ onKeyDown={this._handleKeyPress}
127
+ >
128
+ {showTime && <div className={styles.captionTime}>{secontsToTime(startTime, longerThanHour)}</div>}
129
+ <div
130
+ onClick={this._handleClick}
131
+ className={`${styles.captionContent} ${isHighlighted ? styles.highlighted : ''} ${showTime ? '' : styles.withoutTime}`}
132
+ role="button"
133
+ >
134
+ {this._renderText(caption.text)}
135
+ </div>
136
+ </div>
137
+ );
138
+ }
161
139
  }
@@ -1 +1 @@
1
- export * from "./caption";
1
+ export * from './caption';
@@ -1,9 +1,9 @@
1
1
  .transcript-wrapper {
2
- position: absolute;
3
- width: 100%;
4
- display: flex;
5
- flex-direction: column;
6
- align-items: center;
7
- justify-content: center;
8
- padding-right: 9px;
9
- }
2
+ position: absolute;
3
+ width: 100%;
4
+ display: flex;
5
+ flex-direction: column;
6
+ align-items: center;
7
+ justify-content: center;
8
+ padding-right: 9px;
9
+ }