@playkit-js/transcript 3.0.1-canary.44-4c445bb → 3.0.1-canary.46-b1e939d

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playkit-js/transcript",
3
- "version": "3.0.1-canary.44-4c445bb",
3
+ "version": "3.0.1-canary.46-b1e939d",
4
4
  "main": "dist/playkit-transcript.js",
5
5
  "license": "AGPL-3.0",
6
6
  "private": false,
@@ -75,7 +75,7 @@
75
75
  "html5 player"
76
76
  ],
77
77
  "dependencies": {
78
- "@playkit-js/common": "^1.0.7",
78
+ "@playkit-js/common": "^1.0.2",
79
79
  "stream-browserify": "^3.0.0"
80
80
  },
81
81
  "kaltura": {
@@ -1,8 +1,10 @@
1
- import {Component, h} from 'preact';
2
- import {A11yWrapper, OnClickEvent} from '@playkit-js/common';
1
+ import * as styles from './caption.scss';
3
2
  import {secontsToTime} from '../../utils';
4
3
  import {CuePointData} from '../../types';
5
- import * as styles from './caption.scss';
4
+
5
+ const {ENTER, Space} = KalturaPlayer.ui.utils.KeyMap;
6
+
7
+ import {Component, h} from 'preact';
6
8
 
7
9
  export interface CaptionProps {
8
10
  showTime: boolean;
@@ -55,10 +57,12 @@ export class Caption extends Component<ExtendedCaptionProps> {
55
57
  return false;
56
58
  }
57
59
 
58
- private _handleKeyDown = (event: OnClickEvent, byKeyboard?: boolean) => {
59
- if (byKeyboard) {
60
+ private _handleKeyPress = (event: KeyboardEvent) => {
61
+ const keyCode = event.which || event.keyCode;
62
+ if (keyCode === ENTER || keyCode === Space) {
60
63
  event.preventDefault();
61
64
  this._gotoCurrentTime();
65
+ return;
62
66
  }
63
67
  };
64
68
 
@@ -113,23 +117,23 @@ export class Caption extends Component<ExtendedCaptionProps> {
113
117
  const isHighlighted = Object.keys(highlighted)[0] === id;
114
118
 
115
119
  return (
116
- <A11yWrapper onClick={this._handleKeyDown}>
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>}
117
129
  <div
118
- className={styles.caption}
119
- tabIndex={1}
120
- area-label={caption.text}
121
- ref={node => {
122
- this._hotspotRef = node;
123
- }}
124
- role="listitem">
125
- {showTime && <div className={styles.captionTime}>{secontsToTime(startTime, longerThanHour)}</div>}
126
- <div
127
- onClick={this._handleClick}
128
- className={`${styles.captionContent} ${isHighlighted ? styles.highlighted : ''} ${showTime ? '' : styles.withoutTime}`}>
129
- {this._renderText(caption.text)}
130
- </div>
130
+ onClick={this._handleClick}
131
+ className={`${styles.captionContent} ${isHighlighted ? styles.highlighted : ''} ${showTime ? '' : styles.withoutTime}`}
132
+ role="button"
133
+ >
134
+ {this._renderText(caption.text)}
131
135
  </div>
132
- </A11yWrapper>
136
+ </div>
133
137
  );
134
138
  }
135
139
  }
@@ -4,7 +4,7 @@ import {Caption} from '../caption';
4
4
  import * as styles from './captionList.scss';
5
5
  import {HighlightedMap, CuePointData} from '../../types';
6
6
 
7
- const {END, HOME} = KalturaPlayer.ui.utils.KeyMap;
7
+ const {End, Home} = KalturaPlayer.ui.utils.KeyMap;
8
8
 
9
9
  export interface CaptionProps {
10
10
  showTime: boolean;
@@ -95,9 +95,9 @@ export class CaptionList extends Component<Props> {
95
95
  };
96
96
 
97
97
  private _handleKeyUp = (event: KeyboardEvent) => {
98
- if (event.keyCode === END) {
98
+ if (event.keyCode === End) {
99
99
  this._lastCaptionRef?._hotspotRef?.focus();
100
- } else if (event.keyCode === HOME) {
100
+ } else if (event.keyCode === Home) {
101
101
  this._firstCaptionRef?._hotspotRef?.focus();
102
102
  }
103
103
  };
@@ -105,7 +105,7 @@ export class CaptionList extends Component<Props> {
105
105
  render() {
106
106
  const {data} = this.props;
107
107
  return (
108
- <div className={styles.transcriptWrapper} onKeyUp={this._handleKeyUp} role="list">
108
+ <div className={styles.transcriptWrapper} onKeyUp={this._handleKeyUp}>
109
109
  {data.map((captionData, index) => {
110
110
  const captionProps = this._getCaptionProps(captionData);
111
111
  return (
@@ -116,7 +116,7 @@ export class CaptionList extends Component<Props> {
116
116
  } else if (index === data.length - 1) {
117
117
  this._lastCaptionRef = node;
118
118
  }
119
- if (captionProps.highlighted[captionData.id]) {
119
+ if (captionProps.highlighted) {
120
120
  this._currentCaptionRef = node;
121
121
  }
122
122
  }}
@@ -3,20 +3,14 @@ import * as styles from './close-button.scss';
3
3
  import {A11yWrapper} from '@playkit-js/common';
4
4
  import {icons} from '../icons';
5
5
  const {Icon} = KalturaPlayer.ui.components;
6
- const {withText, Text} = KalturaPlayer.ui.preacti18n;
7
-
8
- const translates = {
9
- closeLabel: <Text id="transcript.hide_plugin">Hide Transcript</Text>
10
- };
11
6
 
12
7
  interface CloseButtonProps {
13
8
  onClick: () => void;
14
- closeLabel?: string;
15
9
  }
16
10
 
17
- export const CloseButton = withText(translates)((props: CloseButtonProps) => (
11
+ export const CloseButton = (props: CloseButtonProps) => (
18
12
  <A11yWrapper onClick={props.onClick}>
19
- <button className={styles.closeBtn} tabIndex={1} aria-label={props.closeLabel}>
13
+ <button className={styles.closeBtn} tabIndex={1}>
20
14
  <Icon
21
15
  id="transcript-plugin-close-button"
22
16
  height={icons.BigSize}
@@ -26,4 +20,4 @@ export const CloseButton = withText(translates)((props: CloseButtonProps) => (
26
20
  />
27
21
  </button>
28
22
  </A11yWrapper>
29
- ));
23
+ );
@@ -26,3 +26,19 @@
26
26
  background-size: cover;
27
27
  }
28
28
  }
29
+ .popover-menu-item {
30
+ display: flex;
31
+ align-items: center;
32
+ padding: 9px 24px 9px 16px;
33
+ white-space: nowrap;
34
+ min-height: 30px;
35
+ line-height: 18px;
36
+ font-size: 15px;
37
+ &:hover {
38
+ cursor: pointer;
39
+ background-color: $semigray-color;
40
+ }
41
+ &:focus {
42
+ outline: 1px solid $focus-color;
43
+ }
44
+ }
@@ -1,11 +1,10 @@
1
- import {h, Component, VNode} from 'preact';
2
- import {A11yWrapper} from '@playkit-js/common';
3
- import {Popover, PopoverMenuItem} from '../popover';
1
+ import {h, Component, ComponentChild, VNode} from 'preact';
2
+ import {Popover, PopoverHorizontalPositions, PopoverVerticalPositions} from '../../utils';
3
+ import {PopoverMenu, PopoverMenuItem} from '../popover-menu';
4
4
  import * as styles from './download-print-menu.scss';
5
5
  import {DownloadIcon, PrintIcon} from './download-print-icons';
6
6
 
7
- const {Tooltip} = KalturaPlayer.ui.components;
8
- const {withText, Text} = KalturaPlayer.ui.preacti18n;
7
+ const {ENTER, Esc} = KalturaPlayer.ui.utils.KeyMap;
9
8
 
10
9
  export function downloadContent(content: string, name: string): void {
11
10
  const blob = new Blob([content], {type: 'text/plain;charset=utf-8;'});
@@ -30,6 +29,7 @@ export function downloadContent(content: string, name: string): void {
30
29
  anchor.click();
31
30
  anchor.remove();
32
31
  }
32
+
33
33
  export function printContent(content: string): void {
34
34
  const printWindow = window.open('', '', 'width=400,height=600');
35
35
  if (printWindow) {
@@ -42,9 +42,9 @@ export function printContent(content: string): void {
42
42
  }
43
43
 
44
44
  interface DownloadPrintMenuProps {
45
- printDownloadAreaLabel?: string;
46
- printTranscript?: string;
47
- downloadTranscript?: string;
45
+ dropdownAriaLabel: string;
46
+ printButtonAriaLabel: string;
47
+ downloadButtonAriaLabel: string;
48
48
  onDownload: () => void;
49
49
  onPrint: () => void;
50
50
  downloadDisabled: boolean;
@@ -52,77 +52,113 @@ interface DownloadPrintMenuProps {
52
52
  }
53
53
 
54
54
  interface ButtonProperties {
55
- ['aria-label']?: string;
55
+ ['aria-label']: string;
56
+ buttonStyles: string;
57
+ onClick?: () => void;
56
58
  tabIndex?: number;
59
+ iconStyles: string;
57
60
  icon: VNode;
58
61
  }
59
62
 
60
- const translates = () => ({
61
- printDownloadAreaLabel: <Text id="transcript.print_download_area_label">Download or print current transcript</Text>,
62
- printTranscript: <Text id="transcript.print_transcript">Print current transcript</Text>,
63
- downloadTranscript: <Text id="transcript.download_transcript">Download current transcript</Text>
64
- });
63
+ interface DownloadPrintMenuState {
64
+ popoverOpen: boolean;
65
+ }
66
+
67
+ export class DownloadPrintMenu extends Component<DownloadPrintMenuProps, DownloadPrintMenuState> {
68
+ state: DownloadPrintMenuState = {
69
+ popoverOpen: false
70
+ };
71
+
72
+ private _onDownloadClicked = () => {
73
+ this.props.onDownload();
74
+ };
75
+
76
+ private _onPrintClicked = () => {
77
+ this.props.onPrint();
78
+ };
79
+ private _onKeyDown = (e: KeyboardEvent, callBack: Function) => {
80
+ if (e.keyCode !== ENTER && e.keyCode !== Esc) {
81
+ // don't stopPropagation on ESC and Enter pressed as it prevent the popup closing
82
+ e.stopPropagation();
83
+ }
84
+ switch (e.keyCode) {
85
+ case 13: // Enter pressed
86
+ callBack();
87
+ break;
88
+ }
89
+ };
90
+ private _popoverMenuItemRenderer = (el: PopoverMenuItem) => (
91
+ <div
92
+ tabIndex={1}
93
+ role="button"
94
+ onClick={() => el.onMenuChosen()}
95
+ onKeyDown={(e: KeyboardEvent) => this._onKeyDown(e, el.onMenuChosen)}
96
+ className={styles.popoverMenuItem}>
97
+ {el.label}
98
+ </div>
99
+ );
65
100
 
66
- export class DownloadPrintMenuComponent extends Component<DownloadPrintMenuProps> {
67
- private _getPopoverMenuOptions = (): Array<PopoverMenuItem> => {
101
+ private _getPopoverMenuOptions = () => {
68
102
  return [
69
103
  {
70
- label: this.props.downloadTranscript,
71
- onMenuChosen: this.props.onDownload
104
+ label: this.props.downloadButtonAriaLabel,
105
+ onMenuChosen: this._onDownloadClicked
72
106
  },
73
107
  {
74
- label: this.props.printTranscript,
75
- onMenuChosen: this.props.onPrint
108
+ label: this.props.printButtonAriaLabel,
109
+ onMenuChosen: this._onPrintClicked
76
110
  }
77
111
  ];
78
112
  };
79
113
 
80
- private _renderIcon = ({tabIndex = 0, icon, ...props}: ButtonProperties): VNode => {
114
+ private _renderIcon = ({buttonStyles, tabIndex = 0, iconStyles, icon, ...props}: ButtonProperties): ComponentChild => {
81
115
  return (
82
- <button className={styles.downloadPrintButton} tabIndex={tabIndex} {...props}>
83
- <div className={styles.icon}>{icon}</div>
116
+ <button className={buttonStyles} tabIndex={tabIndex} {...props}>
117
+ <div className={iconStyles}>{icon}</div>
84
118
  </button>
85
119
  );
86
120
  };
87
121
 
122
+ private _popoverContent = () => {
123
+ return <PopoverMenu itemRenderer={this._popoverMenuItemRenderer} options={this._getPopoverMenuOptions()} />;
124
+ };
125
+
88
126
  render(props: DownloadPrintMenuProps) {
89
- const {downloadDisabled, printDisabled, printDownloadAreaLabel, printTranscript, downloadTranscript} = props;
127
+ const {downloadDisabled, printDisabled} = props;
90
128
  if (!downloadDisabled && !printDisabled) {
91
129
  return (
92
- <Popover label={printDownloadAreaLabel!} options={this._getPopoverMenuOptions()}>
130
+ <Popover
131
+ className="download-print-popover"
132
+ verticalPosition={PopoverVerticalPositions.Bottom}
133
+ horizontalPosition={PopoverHorizontalPositions.Left}
134
+ content={this._popoverContent()}>
93
135
  {this._renderIcon({
94
- ['aria-label']: printDownloadAreaLabel,
136
+ ['aria-label']: props.dropdownAriaLabel,
137
+ buttonStyles: styles.downloadPrintButton,
138
+ iconStyles: styles.icon,
95
139
  icon: <DownloadIcon />
96
140
  })}
97
141
  </Popover>
98
142
  );
99
143
  }
100
144
  if (!downloadDisabled && printDisabled) {
101
- return (
102
- <Tooltip label={downloadTranscript} type="bottom">
103
- <A11yWrapper onClick={this.props.onDownload}>
104
- {this._renderIcon({
105
- ['aria-label']: downloadTranscript,
106
- icon: <DownloadIcon />
107
- })}
108
- </A11yWrapper>
109
- </Tooltip>
110
- );
145
+ return this._renderIcon({
146
+ ['aria-label']: props.downloadButtonAriaLabel,
147
+ buttonStyles: styles.downloadPrintButton,
148
+ iconStyles: styles.icon,
149
+ onClick: this._onDownloadClicked,
150
+ icon: <DownloadIcon />
151
+ });
111
152
  }
112
153
  if (downloadDisabled && !printDisabled) {
113
- return (
114
- <Tooltip label={printTranscript} type="bottom">
115
- <A11yWrapper onClick={this.props.onPrint}>
116
- {this._renderIcon({
117
- ['aria-label']: printTranscript,
118
- icon: <PrintIcon />
119
- })}
120
- </A11yWrapper>
121
- </Tooltip>
122
- );
154
+ return this._renderIcon({
155
+ ['aria-label']: props.printButtonAriaLabel,
156
+ buttonStyles: styles.downloadPrintButton,
157
+ iconStyles: styles.icon,
158
+ onClick: this._onPrintClicked,
159
+ icon: <PrintIcon />
160
+ });
123
161
  }
124
162
  return null;
125
163
  }
126
164
  }
127
-
128
- export const DownloadPrintMenu = withText(translates)(DownloadPrintMenuComponent);
@@ -2,15 +2,7 @@ import {h} from 'preact';
2
2
  import * as styles from './plugin-button.scss';
3
3
  import {icons} from '../icons';
4
4
  import {A11yWrapper, OnClick} from '@playkit-js/common';
5
-
6
5
  const {Tooltip, Icon} = KalturaPlayer.ui.components;
7
- const {withText, Text} = KalturaPlayer.ui.preacti18n;
8
-
9
- const translates = ({isActive}: PluginButtonProps) => {
10
- return {
11
- label: isActive ? <Text id="transcript.hide_plugin">Hide Transcript</Text> : <Text id="transcript.show_plugin">Show Transcript</Text>
12
- };
13
- };
14
6
 
15
7
  interface PluginButtonProps {
16
8
  isActive: boolean;
@@ -18,7 +10,7 @@ interface PluginButtonProps {
18
10
  label?: string;
19
11
  }
20
12
 
21
- export const PluginButton = withText(translates)(({isActive, onClick, label}: PluginButtonProps) => {
13
+ export const PluginButton = ({isActive, onClick, label}: PluginButtonProps) => {
22
14
  return (
23
15
  <Tooltip label={label} type="bottom">
24
16
  <A11yWrapper onClick={onClick}>
@@ -34,4 +26,4 @@ export const PluginButton = withText(translates)(({isActive, onClick, label}: Pl
34
26
  </A11yWrapper>
35
27
  </Tooltip>
36
28
  );
37
- });
29
+ };
@@ -0,0 +1 @@
1
+ export * from './popover-menu';
@@ -0,0 +1,6 @@
1
+ @import '../../variables.scss';
2
+
3
+ .popover-menu {
4
+ padding-top: 6px;
5
+ padding-bottom: 6px;
6
+ }
@@ -0,0 +1,52 @@
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 className="popover-menu-item" onClick={() => el.onMenuChosen(el)}>
45
+ {el.label}
46
+ </div>
47
+ );
48
+ })}
49
+ </div>
50
+ );
51
+ }
52
+ }