@24i/bigscreen-sdk 1.0.10 → 1.0.11-alpha.2229
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 +2 -2
- package/packages/developer-tools/src/TechnicalInfo/TechnicalInfoProvider.ts +25 -3
- package/packages/developer-tools/src/TechnicalInfo/__mocks__/Device.ts +4 -0
- package/packages/developer-tools/src/TechnicalInfo/translations.ts +2 -0
- package/packages/driver-androidtv/src/DeviceAndroidTV.ts +7 -1
- package/packages/driver-androidtv/src/__mocks__/javaScriptBridge.ts +4 -0
- package/packages/driver-androidtv/src/types.ts +19 -1
- package/packages/epg/src/v2/DataManager.ts +99 -51
- package/packages/player-ui/src/Seekbar.tsx +23 -1
- package/packages/utils/src/xhr/xhrSend.ts +3 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@24i/bigscreen-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11-alpha.2229",
|
|
4
4
|
"description": "SmartApps BIGscreen SDK monorepo",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"homepage": "https://github.com/24i/smartapps-bigscreen-sdk#readme",
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@24i/player-base": "6.10.0",
|
|
41
|
-
"@24i/smartapps-datalayer": "3.0.
|
|
41
|
+
"@24i/smartapps-datalayer": "3.0.6-alpha.978",
|
|
42
42
|
"@sentry/browser": "^7.12.1",
|
|
43
43
|
"@types/gtag.js": "^0.0.12",
|
|
44
44
|
"@types/prop-types": "^15.7.5",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DeviceBase } from '@24i/bigscreen-sdk/driver-base';
|
|
2
|
+
import { DeviceAndroidTV } from '@24i/bigscreen-sdk/driver-androidtv';
|
|
2
3
|
import { IStorage } from '@24i/bigscreen-sdk/storage/interface';
|
|
3
4
|
import { getUsedJSHeapSize, getTotalJSHeapSize } from '@24i/bigscreen-sdk/utils/memoryInfo';
|
|
4
5
|
import { ipify } from '@24i/bigscreen-sdk/ipify';
|
|
@@ -270,14 +271,23 @@ class TechnicalInfoProvider implements ITechnicalInfoProvider {
|
|
|
270
271
|
return this.props.appCoreVersions || unknown;
|
|
271
272
|
}
|
|
272
273
|
|
|
273
|
-
|
|
274
|
+
async getWrapperVersion() {
|
|
275
|
+
let value;
|
|
276
|
+
const { unknown } = this.translations;
|
|
277
|
+
try {
|
|
278
|
+
value = await (this.props.device as DeviceAndroidTV).getWrapperVersion();
|
|
279
|
+
} catch (e) {}
|
|
280
|
+
return value || unknown;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
async getSourceDataLayout() {
|
|
274
284
|
const {
|
|
275
285
|
username, profile, appVersion, firmwareVersion, deviceModel,
|
|
276
286
|
deviceManufacturer, platform, player, serialNumber, localIpAddress,
|
|
277
287
|
publicIpAddress, connectionType, macAddress, memoryHeapSize,
|
|
278
288
|
usedLocalStorage, timeZone, dateAndTime, flavour, userAgent,
|
|
279
289
|
emeSupport, emeDrmSystems, mseSupport, fourKSupport, resolution, baseUrl,
|
|
280
|
-
appCoreVersions,
|
|
290
|
+
appCoreVersions, androidWrapperVersion,
|
|
281
291
|
} = this.translations;
|
|
282
292
|
const dataLayout: SourceDataLayout = [
|
|
283
293
|
{ label: username, getter: this.getUserName },
|
|
@@ -307,9 +317,21 @@ class TechnicalInfoProvider implements ITechnicalInfoProvider {
|
|
|
307
317
|
{ label: resolution, getter: this.getAppResolution },
|
|
308
318
|
{ label: baseUrl, getter: this.getBackendBaseUrl },
|
|
309
319
|
];
|
|
320
|
+
|
|
321
|
+
if (await this.isAndroidTV()) {
|
|
322
|
+
dataLayout.push(
|
|
323
|
+
{ label: androidWrapperVersion, getter: this.getWrapperVersion },
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
|
|
310
327
|
return dataLayout;
|
|
311
328
|
}
|
|
312
329
|
|
|
330
|
+
async isAndroidTV() {
|
|
331
|
+
const platformName = await this.props.device.getPlatformName();
|
|
332
|
+
return platformName === 'AndroidTV';
|
|
333
|
+
}
|
|
334
|
+
|
|
313
335
|
async loadDataLayout(dataLayout: SourceDataLayout) {
|
|
314
336
|
const promises = map(dataLayout, async (item) => item.getter.call(this));
|
|
315
337
|
const values = await Promise.all(promises);
|
|
@@ -319,7 +341,7 @@ class TechnicalInfoProvider implements ITechnicalInfoProvider {
|
|
|
319
341
|
}
|
|
320
342
|
|
|
321
343
|
async getInfoData() {
|
|
322
|
-
const sourceDataLayout = this.getSourceDataLayout();
|
|
344
|
+
const sourceDataLayout = await this.getSourceDataLayout();
|
|
323
345
|
return this.loadDataLayout(sourceDataLayout);
|
|
324
346
|
}
|
|
325
347
|
}
|
|
@@ -3,6 +3,7 @@ export type Translations = TranslationKeys | { [K in keyof TranslationKeys]?: ne
|
|
|
3
3
|
export type TranslationKeys = {
|
|
4
4
|
unknown: string
|
|
5
5
|
anonymous: string,
|
|
6
|
+
androidWrapperVersion: string,
|
|
6
7
|
yes: string,
|
|
7
8
|
no: string,
|
|
8
9
|
prefixed: string,
|
|
@@ -41,6 +42,7 @@ export type TranslationKeys = {
|
|
|
41
42
|
export const defaultTranslations = {
|
|
42
43
|
unknown: 'UNKNOWN',
|
|
43
44
|
anonymous: 'ANONYMOUS',
|
|
45
|
+
androidWrapperVersion: 'Android wrapper version',
|
|
44
46
|
yes: 'Yes',
|
|
45
47
|
no: 'No',
|
|
46
48
|
prefixed: 'prefixed',
|
|
@@ -154,6 +154,10 @@ export class DeviceAndroidTV extends DeviceBase {
|
|
|
154
154
|
return VolumeRange.UNSUPPORTED;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
async getWrapperVersion(): Promise<string> {
|
|
158
|
+
return this.platformInfo.appVersion;
|
|
159
|
+
}
|
|
160
|
+
|
|
157
161
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
158
162
|
async setVolume(volumePercentage: number): Promise<void> {
|
|
159
163
|
// not supported on AndroidTV platform
|
|
@@ -195,7 +199,9 @@ export class DeviceAndroidTV extends DeviceBase {
|
|
|
195
199
|
}
|
|
196
200
|
|
|
197
201
|
async getLocalIP(): Promise<string> {
|
|
198
|
-
|
|
202
|
+
const ipv4RegExp = /\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/;
|
|
203
|
+
const ip = this.platformInfo.ipLocal.toString().match(ipv4RegExp);
|
|
204
|
+
if (ip) return ip.toString();
|
|
199
205
|
return '';
|
|
200
206
|
}
|
|
201
207
|
|
|
@@ -7,6 +7,10 @@ export const mockJavaScriptBridge: IJavaScriptBridge = {
|
|
|
7
7
|
deviceBrand: 'Sony',
|
|
8
8
|
deviceModel: 'BRAVIA 4K 2015',
|
|
9
9
|
osVersion: '8.0.0',
|
|
10
|
+
appVersion: '0.0.1',
|
|
11
|
+
appFlavor: 'appstage-bigscreen',
|
|
12
|
+
drmKeySystems: '["W3C Clear Key", "Google Widevine"]',
|
|
13
|
+
ipLocal: '127.0.0.1',
|
|
10
14
|
})
|
|
11
15
|
),
|
|
12
16
|
bridgeJavaScriptToAndroid_Back: () => {},
|
|
@@ -2,7 +2,9 @@ interface JavaScriptBridge {
|
|
|
2
2
|
/**
|
|
3
3
|
* It returns a JSON string with device info.
|
|
4
4
|
* @return JSON string with the information about the device brand, model and Android version.
|
|
5
|
-
* Ex. '{"deviceBrand": "Sony", "deviceModel": "BRAVIA 4K 2015", "osVersion": "7.0"
|
|
5
|
+
* Ex. '{"deviceBrand": "Sony", "deviceModel": "BRAVIA 4K 2015", "osVersion": "7.0",
|
|
6
|
+
* "appFlavor": "appstage-bigscreen", "drmKeySystems": ["Widewine", "W3C ClearKey"],
|
|
7
|
+
* "ipLocal": "fe80::475:3045:2928:3a32%wlan0127.0.0.1", "appVersion": '0.0.1' }'
|
|
6
8
|
*/
|
|
7
9
|
bridgeJavaScriptToAndroid_GetDeviceInfo: () => string,
|
|
8
10
|
/**
|
|
@@ -24,6 +26,22 @@ export type DeviceInfo = {
|
|
|
24
26
|
* Android version. Ex. "7.0"
|
|
25
27
|
*/
|
|
26
28
|
osVersion: string,
|
|
29
|
+
/**
|
|
30
|
+
* Android wrapper version. Ex. "0.0.1"
|
|
31
|
+
*/
|
|
32
|
+
appVersion: string,
|
|
33
|
+
/**
|
|
34
|
+
* Android flavor. Ex. "appstage-bigscreen"
|
|
35
|
+
*/
|
|
36
|
+
appFlavor: string,
|
|
37
|
+
/**
|
|
38
|
+
* Android DRM key systems. Ex. ["Widewine", "W3C ClearKey"]
|
|
39
|
+
*/
|
|
40
|
+
drmKeySystems: Array<string>,
|
|
41
|
+
/**
|
|
42
|
+
* Android local IP adress in array Ex. "fe80::475:3045:2928:3a32%wlan0127.0.0.1"
|
|
43
|
+
*/
|
|
44
|
+
ipLocal: string,
|
|
27
45
|
};
|
|
28
46
|
|
|
29
47
|
export interface IJavaScriptBridge {
|
|
@@ -84,67 +84,115 @@ export class DataManager implements IDataManager {
|
|
|
84
84
|
return [data[0].program!.startTime, data[data.length - 1].program!.endTime] as DataRange;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
private isInterceptingDataRanges = (firstDataRange: DataRange, secondDataRange: DataRange) => (
|
|
88
|
+
(firstDataRange[START] < secondDataRange[END]
|
|
89
|
+
&& firstDataRange[START] > secondDataRange[START])
|
|
90
|
+
|| (secondDataRange[START] < firstDataRange[END]
|
|
91
|
+
&& secondDataRange[START] > firstDataRange[START])
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
private findRangeBeforeAndAfter = (currentRange: DataRange) => {
|
|
95
|
+
const rangeAfterIndex = findIndex(
|
|
96
|
+
this.dataRanges,
|
|
97
|
+
(dataRange) => dataRange[END] >= currentRange[END],
|
|
98
|
+
);
|
|
99
|
+
if (rangeAfterIndex === -1) {
|
|
100
|
+
return {
|
|
101
|
+
rangeAfter: undefined,
|
|
102
|
+
rangeBefore: this.dataRanges[this.dataRanges.length - 1],
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const rangeAfter = this.dataRanges[rangeAfterIndex];
|
|
106
|
+
const rangeBefore = this.dataRanges[rangeAfterIndex - 1];
|
|
107
|
+
return { rangeAfter, rangeBefore };
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
private generateDataRangesForward = (start: number, end: number, cellSize: number) => {
|
|
111
|
+
const dataRanges: DataRange[] = [[start, start + cellSize]];
|
|
112
|
+
let currentStart = start + cellSize;
|
|
113
|
+
let currentEnd = currentStart + cellSize;
|
|
114
|
+
while (currentStart < end) {
|
|
115
|
+
if (currentEnd >= end) {
|
|
116
|
+
dataRanges.push([currentStart, end]);
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
dataRanges.push([currentStart, currentEnd]);
|
|
120
|
+
currentStart += cellSize;
|
|
121
|
+
currentEnd += cellSize;
|
|
122
|
+
}
|
|
123
|
+
return dataRanges;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
private generateDataRangesBackward = (start: number, end: number, cellSize: number) => {
|
|
127
|
+
const dataRanges: DataRange[] = [[start - cellSize, start]];
|
|
128
|
+
let currentEnd = start - cellSize;
|
|
129
|
+
let currentStart = currentEnd - cellSize;
|
|
130
|
+
while (currentEnd > start) {
|
|
131
|
+
if (currentStart <= start) {
|
|
132
|
+
dataRanges.push([start, currentEnd]);
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
dataRanges.push([currentStart, currentEnd]);
|
|
136
|
+
currentStart -= cellSize;
|
|
137
|
+
currentEnd -= cellSize;
|
|
138
|
+
}
|
|
139
|
+
return dataRanges;
|
|
140
|
+
};
|
|
141
|
+
|
|
88
142
|
/* eslint-disable complexity */
|
|
89
143
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
90
144
|
private getRangesMissingFromDataInRange([start, end]: DataRange) {
|
|
91
|
-
const
|
|
145
|
+
const currentRange = [start, end] as DataRange;
|
|
92
146
|
const cellSize = TIMELINE_WIDTHS_TO_FETCH * this.timelineWidthMs;
|
|
93
|
-
if (this.dataRanges.length === 0) return [
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
] as DataRange[];
|
|
101
|
-
}
|
|
102
|
-
const lastRangeFrom = this.dataRanges[rangesLength - 1][START];
|
|
103
|
-
const lastRangeTo = this.dataRanges[rangesLength - 1][END];
|
|
104
|
-
if (end > lastRangeTo && start <= lastRangeTo) {
|
|
105
|
-
return [
|
|
106
|
-
[lastRangeTo, lastRangeTo + cellSize],
|
|
107
|
-
] as DataRange[];
|
|
108
|
-
}
|
|
109
|
-
if (start >= lastRangeTo && end >= lastRangeTo && start - lastRangeTo >= cellSize) {
|
|
110
|
-
return [
|
|
111
|
-
[start, end],
|
|
112
|
-
] as DataRange[];
|
|
113
|
-
}
|
|
114
|
-
const ranges: DataRange[] = [];
|
|
115
|
-
let newRange: DataRange = [start, end];
|
|
116
|
-
for (let i = 0; i < rangesLength; i++) {
|
|
117
|
-
const [rangeFrom, rangeTo] = this.dataRanges[i];
|
|
118
|
-
if (start >= rangeTo) {
|
|
119
|
-
if (start - rangeTo <= cellSize) {
|
|
120
|
-
newRange[START] = rangeTo;
|
|
121
|
-
} else {
|
|
122
|
-
const newStart = lastRangeFrom - cellSize;
|
|
123
|
-
newRange[START] = newStart;
|
|
147
|
+
if (this.dataRanges.length === 0) return [currentRange] as DataRange[];
|
|
148
|
+
const { rangeBefore, rangeAfter } = this.findRangeBeforeAndAfter(currentRange);
|
|
149
|
+
if (rangeAfter == null) {
|
|
150
|
+
const lastDataRange = this.dataRanges[this.dataRanges.length - 1];
|
|
151
|
+
if (this.isInterceptingDataRanges(lastDataRange, currentRange)) {
|
|
152
|
+
if (end > lastDataRange[END]) {
|
|
153
|
+
return this.generateDataRangesForward(lastDataRange[END], end, cellSize);
|
|
124
154
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
if (start < rangeFrom) {
|
|
129
|
-
if (end <= rangeFrom) {
|
|
130
|
-
if (newRange[START] !== newRange[END]) ranges.push(newRange);
|
|
131
|
-
return ranges;
|
|
155
|
+
if (start < lastDataRange[START]) {
|
|
156
|
+
return this.generateDataRangesBackward(start, lastDataRange[START], cellSize);
|
|
132
157
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
158
|
+
}
|
|
159
|
+
return [currentRange] as DataRange[];
|
|
160
|
+
}
|
|
161
|
+
if (rangeBefore == null) {
|
|
162
|
+
const firstDataRange = this.dataRanges[0];
|
|
163
|
+
if (this.isInterceptingDataRanges(firstDataRange, currentRange)) {
|
|
164
|
+
if (end > firstDataRange[END]) {
|
|
165
|
+
return this.generateDataRangesForward(firstDataRange[END], end, cellSize);
|
|
137
166
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (end <= rangeTo) {
|
|
141
|
-
return ranges;
|
|
167
|
+
if (start < firstDataRange[START]) {
|
|
168
|
+
return this.generateDataRangesBackward(firstDataRange[START], start, cellSize);
|
|
142
169
|
}
|
|
143
|
-
newRange = [rangeTo, end];
|
|
144
170
|
}
|
|
171
|
+
return [currentRange] as DataRange[];
|
|
172
|
+
}
|
|
173
|
+
const rangeAfterFrom = rangeAfter[START];
|
|
174
|
+
const rangeBeforeTo = rangeBefore[END];
|
|
175
|
+
// Ranges are collapsed
|
|
176
|
+
if (rangeBeforeTo === rangeAfterFrom) return [];
|
|
177
|
+
// Both are not null and don't intercept
|
|
178
|
+
if (
|
|
179
|
+
!this.isInterceptingDataRanges(rangeAfter, currentRange)
|
|
180
|
+
&& !this.isInterceptingDataRanges(rangeBefore, currentRange)
|
|
181
|
+
) {
|
|
182
|
+
return [currentRange];
|
|
183
|
+
}
|
|
184
|
+
// Left intercepts
|
|
185
|
+
if (this.isInterceptingDataRanges(rangeBefore, currentRange)) {
|
|
186
|
+
return [rangeBefore, ...this.generateDataRangesForward(rangeBeforeTo, end, cellSize)];
|
|
187
|
+
}
|
|
188
|
+
// Right intercepts
|
|
189
|
+
if (this.isInterceptingDataRanges(rangeAfter, currentRange)) {
|
|
190
|
+
return [
|
|
191
|
+
...this.generateDataRangesBackward(rangeAfterFrom, start, cellSize),
|
|
192
|
+
rangeAfter,
|
|
193
|
+
];
|
|
145
194
|
}
|
|
146
|
-
|
|
147
|
-
return ranges;
|
|
195
|
+
return [currentRange] as DataRange[];
|
|
148
196
|
}
|
|
149
197
|
|
|
150
198
|
private getMissingRanges(range: DataRange) {
|
|
@@ -4,6 +4,7 @@ import { stopEvent } from '@24i/bigscreen-sdk/utils/stopEvent';
|
|
|
4
4
|
import { ITimeUpdateEvent, IDurationChangeEvent } from '@24i/player-base';
|
|
5
5
|
import { createTimeout } from '@24i/bigscreen-sdk/utils/timers';
|
|
6
6
|
import { switchByKey } from '@24i/bigscreen-sdk/device/keymap';
|
|
7
|
+
import { getDisplayToggler } from '@24i/bigscreen-sdk/utils/displayToggler';
|
|
7
8
|
import { PlayerTime } from './PlayerTime';
|
|
8
9
|
import { getLiveProgressBasedOnCurrentTime } from './timeUtils';
|
|
9
10
|
import { PlayerUICommonProps } from './types';
|
|
@@ -26,6 +27,8 @@ export class Seekbar extends Component<Props> implements IFocusable {
|
|
|
26
27
|
|
|
27
28
|
seekTime = createRef<PlayerTime>();
|
|
28
29
|
|
|
30
|
+
displaySeekPoint = getDisplayToggler(this.seekPoint);
|
|
31
|
+
|
|
29
32
|
leftConsecutiveness = 0;
|
|
30
33
|
|
|
31
34
|
rightConsecutiveness = 0;
|
|
@@ -40,6 +43,8 @@ export class Seekbar extends Component<Props> implements IFocusable {
|
|
|
40
43
|
|
|
41
44
|
isMouseDownPressed = false;
|
|
42
45
|
|
|
46
|
+
seekingDisabled = false;
|
|
47
|
+
|
|
43
48
|
static defaultProps = {
|
|
44
49
|
className: '',
|
|
45
50
|
};
|
|
@@ -67,7 +72,7 @@ export class Seekbar extends Component<Props> implements IFocusable {
|
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
onMouseMove = (event: MouseEvent) => {
|
|
70
|
-
if (!this.isMouseDownPressed) return;
|
|
75
|
+
if (!this.isMouseDownPressed || this.seekingDisabled) return;
|
|
71
76
|
const { ui: { seeking } } = this.props;
|
|
72
77
|
const wrapRect = this.wrap.current!.getBoundingClientRect();
|
|
73
78
|
const clientX = event.clientX - wrapRect.left;
|
|
@@ -79,6 +84,7 @@ export class Seekbar extends Component<Props> implements IFocusable {
|
|
|
79
84
|
};
|
|
80
85
|
|
|
81
86
|
onMouseClick = (event: MouseEvent) => {
|
|
87
|
+
if (this.seekingDisabled) return;
|
|
82
88
|
const { ui: { seeking } } = this.props;
|
|
83
89
|
const wrapWidth = this.wrap.current!.offsetWidth;
|
|
84
90
|
const percentage = (TO_PERCENT * event.offsetX) / wrapWidth;
|
|
@@ -115,6 +121,7 @@ export class Seekbar extends Component<Props> implements IFocusable {
|
|
|
115
121
|
};
|
|
116
122
|
|
|
117
123
|
onLeft = () => {
|
|
124
|
+
if (this.seekingDisabled) return true;
|
|
118
125
|
const { ui } = this.props;
|
|
119
126
|
this.leftConsecutiveness += 1;
|
|
120
127
|
if (ui.seeking.isAutomaticallySeeking()) {
|
|
@@ -128,6 +135,7 @@ export class Seekbar extends Component<Props> implements IFocusable {
|
|
|
128
135
|
};
|
|
129
136
|
|
|
130
137
|
onRight = () => {
|
|
138
|
+
if (this.seekingDisabled) return true;
|
|
131
139
|
const { ui } = this.props;
|
|
132
140
|
const { seekTime } = ui.seeking;
|
|
133
141
|
if (seekTime == null && this.currentTime + SLOW_TIME >= this.duration) return true;
|
|
@@ -222,6 +230,20 @@ export class Seekbar extends Component<Props> implements IFocusable {
|
|
|
222
230
|
this.seekPoint.current!.style.left = `${percentTime}%`;
|
|
223
231
|
}
|
|
224
232
|
|
|
233
|
+
disableSeeking() {
|
|
234
|
+
this.seekingDisabled = true;
|
|
235
|
+
this.displaySeekPoint.hide();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
enableSeeking() {
|
|
239
|
+
this.seekingDisabled = false;
|
|
240
|
+
this.displaySeekPoint.show();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
isSeekingDisabled() {
|
|
244
|
+
return this.seekingDisabled;
|
|
245
|
+
}
|
|
246
|
+
|
|
225
247
|
render() {
|
|
226
248
|
const { className } = this.props;
|
|
227
249
|
return (
|
|
@@ -84,7 +84,9 @@ function xhrSend(url: string, options: Partial<XhrOptions> = {}): Promise<XhrRes
|
|
|
84
84
|
const xhr = new XMLHttpRequest();
|
|
85
85
|
|
|
86
86
|
function onLoad() {
|
|
87
|
-
const dataText = 'response' in xhr
|
|
87
|
+
const dataText = 'response' in (xhr as XMLHttpRequest)
|
|
88
|
+
? xhr.response
|
|
89
|
+
: xhr.responseText;
|
|
88
90
|
const dataJson = parseJson(dataText);
|
|
89
91
|
const status = xhr.status === undefined ? HttpStatusCode.OK : xhr.status;
|
|
90
92
|
const statusText = xhr.statusText === undefined ? 'OK' : xhr.statusText;
|