@24i/bigscreen-sdk 1.0.4 → 1.0.5-4.alpha-2832
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/README.md +2 -3
- package/ci/is_ci_job_skippable.sh +153 -0
- package/package.json +55 -34
- package/packages/adobe-heartbeat/src/AdobeHeartbeat.ts +9 -9
- package/packages/analytics/README.md +8 -0
- package/packages/analytics/src/A.ts +1 -0
- package/packages/analytics/src/Analytics.ts +1 -0
- package/packages/analytics/src/analyticsOnScroll.ts +1 -0
- package/packages/analytics/src/clients/ConsoleAnalytics/ConsoleAnalytics.ts +1 -0
- package/packages/analytics/src/clients/ConsoleAnalytics/index.ts +1 -0
- package/packages/analytics/src/clients/GoogleAnalytics/GoogleAnalytics.ts +196 -0
- package/packages/analytics/src/clients/GoogleAnalytics/constants.ts +126 -0
- package/packages/analytics/src/clients/GoogleAnalytics/getUrl.ts +17 -0
- package/packages/analytics/src/clients/GoogleAnalytics/index.ts +2 -0
- package/packages/analytics/src/clients/GoogleAnalytics/interface.ts +82 -0
- package/packages/analytics/src/clients/GoogleAnalytics/mapPayload.ts +51 -0
- package/packages/analytics/src/clients/GoogleAnalytics/prepareBody.ts +14 -0
- package/packages/analytics/src/clients/TealiumAnalytics/TealiumAnalytics.ts +181 -0
- package/packages/analytics/src/clients/TealiumAnalytics/constants.ts +106 -0
- package/packages/analytics/src/clients/TealiumAnalytics/findForLanguage.ts +9 -0
- package/packages/analytics/src/clients/TealiumAnalytics/index.ts +4 -0
- package/packages/analytics/src/clients/TealiumAnalytics/interface.ts +35 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/__mocks__/mediaPayload.ts +72 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/helper.ts +36 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapAppError.ts +13 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapAppOpen.ts +13 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapFavoriteAdd.ts +11 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapFavoriteRemove.ts +11 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapPlayerClose.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapPlayerOpen.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSceneView.ts +18 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearch.ts +18 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearchFailed.ts +8 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearchSuccess.ts +8 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoPause.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoProgress.ts +18 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoResume.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoStart.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoStop.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/types.ts +161 -0
- package/packages/analytics/src/clients/TwentyFourIQ/TwentyFourIQClient.ts +107 -0
- package/packages/analytics/src/clients/TwentyFourIQ/constants.ts +111 -0
- package/packages/analytics/src/clients/TwentyFourIQ/helper.ts +34 -0
- package/packages/analytics/src/clients/TwentyFourIQ/index.ts +2 -0
- package/packages/analytics/src/clients/TwentyFourIQ/interface.ts +34 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapAdEvent.ts +20 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapBase.ts +24 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapBuffering.ts +15 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapPlayerClose.ts +25 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapPlayerOpen.ts +17 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapSceneView.ts +15 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapScroll.ts +17 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoComplete.ts +22 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoPause.ts +25 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoProgress.ts +25 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoStart.ts +34 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoStop.ts +32 -0
- package/packages/analytics/src/clients/TwentyFourIQ/types.ts +132 -0
- package/packages/analytics/src/constants.ts +1 -0
- package/packages/analytics/src/index.ts +3 -0
- package/packages/analytics/src/interface.ts +1 -0
- package/packages/analytics/src/utils/generateSessionId.ts +8 -0
- package/packages/async-image/src/AsyncImage.tsx +15 -10
- package/packages/developer-tools/PlayerDebugWindow/README.md +1 -1
- package/packages/developer-tools/src/DeveloperConsole/DeveloperConsole.tsx +1 -0
- package/packages/developer-tools/src/DeveloperToolsService/DeveloperToolsList.tsx +11 -0
- package/packages/developer-tools/src/PlayerDebugWindow/PlayerDebugWindow.tsx +5 -5
- package/packages/developer-tools/src/PlayerDebugWindow/constants.ts +15 -0
- package/packages/developer-tools/src/TechnicalInfo/TechnicalInfo.tsx +2 -0
- package/packages/developer-tools/src/TechnicalInfo/TechnicalInfoDetail.tsx +2 -1
- package/packages/developer-tools/src/TechnicalInfo/TechnicalInfoProvider.ts +57 -5
- package/packages/developer-tools/src/TechnicalInfo/__mocks__/Device.ts +12 -0
- package/packages/developer-tools/src/TechnicalInfo/translations.ts +8 -0
- package/packages/device/src/driver/index.android.tv.ts +1 -0
- package/packages/device/src/driver/index.firetv.ts +1 -0
- package/packages/device/src/driver/index.smartcast.tv.ts +1 -0
- package/packages/device/src/getKeyDigit.ts +2 -2
- package/packages/device/src/resolver/resolver.ts +19 -0
- package/packages/digital-clock/src/DigitalClock.tsx +15 -4
- package/packages/driver-androidtv/src/DeviceAndroidTV.ts +262 -0
- package/packages/driver-androidtv/src/__mocks__/javaScriptBridge.ts +45 -0
- package/packages/driver-androidtv/src/formatUserAgent.ts +11 -0
- package/packages/driver-androidtv/src/index.ts +2 -0
- package/packages/driver-androidtv/src/keymap.ts +27 -0
- package/packages/driver-androidtv/src/types.ts +155 -0
- package/packages/driver-base/src/DeviceBase.ts +73 -2
- package/packages/driver-base/src/KeyMap/Key.ts +8 -1
- package/packages/driver-base/src/KeyMap/KeyMap.ts +4 -0
- package/packages/driver-base/src/KeyMap/interface.ts +1 -0
- package/packages/driver-base/src/KeyMap/overrideValues.ts +2 -1
- package/packages/driver-base/src/__mocks__/DeviceBase.ts +24 -0
- package/packages/driver-base/src/__mocks__/keyMap.ts +1 -0
- package/packages/driver-base/src/index.ts +3 -0
- package/packages/driver-base/src/types/AdInfo.ts +5 -0
- package/packages/driver-base/src/types/DeviceEvent.ts +2 -0
- package/packages/driver-base/src/types/InAppPurchase.ts +20 -0
- package/packages/driver-base/src/types/KeycodeKeyMap.ts +1 -0
- package/packages/driver-browser/src/DeviceBrowser.ts +26 -0
- package/packages/driver-browser/src/keymap.ts +8 -0
- package/packages/driver-entone/src/DeviceEntone.ts +31 -1
- package/packages/driver-entone/src/keymap.ts +1 -0
- package/packages/driver-firetv/src/DeviceFireTV.ts +86 -0
- package/packages/driver-firetv/src/__mocks__/javaScriptBridge.ts +45 -0
- package/packages/driver-firetv/src/index.ts +1 -0
- package/packages/driver-firetv/src/types.ts +1 -0
- package/packages/driver-hbbtv/src/DeviceHbbTV.ts +26 -0
- package/packages/driver-kreatv/src/DeviceKreaTV.ts +26 -0
- package/packages/driver-saphi/src/DeviceSaphi.ts +26 -0
- package/packages/driver-smartcast/src/DeviceSmartCast.ts +380 -0
- package/packages/driver-smartcast/src/__mocks__/api.ts +69 -0
- package/packages/driver-smartcast/src/index.ts +1 -0
- package/packages/driver-smartcast/src/keymap.ts +9 -0
- package/packages/driver-smartcast/src/types.ts +102 -0
- package/packages/driver-tizen/src/DeviceTizen.ts +121 -7
- package/packages/driver-tizen/src/ITizen.ts +15116 -202
- package/packages/driver-tizen/src/IWebapis.ts +8643 -87
- package/packages/driver-tizen/src/TizenKeys.ts +4 -2
- package/packages/driver-tizen/src/__mocks__/tizen.ts +7 -8
- package/packages/driver-tizen/src/constants.ts +1 -195
- package/packages/driver-vidaa/src/DeviceVidaa.ts +29 -2
- package/packages/driver-vidaa/src/__mocks__/vidaa.ts +1 -1
- package/packages/driver-vidaa/src/keymap.ts +2 -0
- package/packages/driver-webos/src/DeviceWebos.ts +55 -0
- package/packages/driver-webos/src/__mocks__/webos.ts +33 -0
- package/packages/driver-webos/src/constants.ts +1 -0
- package/packages/driver-webos/src/keymap.ts +2 -1
- package/packages/driver-webos/src/types.ts +30 -0
- package/packages/driver-xbox/src/DeviceXbox.ts +30 -1
- package/packages/driver-xbox/src/keymap.ts +1 -1
- package/packages/epg/README.md +3 -1
- package/packages/epg/src/v2/Cell.tsx +16 -2
- package/packages/epg/src/v2/DataManager.ts +112 -41
- package/packages/epg/src/v2/DatePicker.tsx +9 -3
- package/packages/epg/src/v2/DateToast/DateToast.tsx +12 -9
- package/packages/epg/src/v2/Day.tsx +6 -3
- package/packages/epg/src/v2/Epg.tsx +5 -5
- package/packages/epg/src/v2/MockGenerator/generator.ts +3 -2
- package/packages/epg/src/v2/ProgramInfo/utils.ts +4 -3
- package/packages/epg/src/v2/Row.tsx +3 -1
- package/packages/epg/src/v2/TimelineSection.tsx +4 -1
- package/packages/epg/src/v2/basic/CellsManager.tsx +7 -2
- package/packages/epg/src/v2/basic/RowsManager.tsx +3 -1
- package/packages/epg/src/v2/interface.ts +13 -0
- package/packages/events-manager/src/EventsManager.ts +1 -56
- package/packages/focus/README.md +33 -0
- package/packages/focus/src/IFocusable.ts +1 -0
- package/packages/focus/src/Layout/Base.tsx +41 -6
- package/packages/focus/src/Layout/Matrix.tsx +51 -19
- package/packages/focus/src/focusFirstExisting.ts +7 -1
- package/packages/focus/src/hasFocus.ts +36 -0
- package/packages/focus/src/index.ts +2 -1
- package/packages/gallup/src/Gallup.ts +3 -3
- package/packages/grid/src/Base/Base.tsx +15 -10
- package/packages/grid/src/FirstOnlyGrid/FirstOnlyGrid.tsx +4 -2
- package/packages/grid/src/UnifiedGridController/UnifiedGridController.ts +6 -6
- package/packages/icon/src/Icon.tsx +27 -5
- package/packages/input/README.md +1 -1
- package/packages/input/src/Input.tsx +10 -10
- package/packages/interactable/README.md +2 -1
- package/packages/interactable/src/Interactable.tsx +9 -3
- package/packages/interactable/src/interface.ts +1 -0
- package/packages/jsx/src/index.ts +1 -1
- package/packages/jsx/src/test-utils/index.ts +1 -0
- package/packages/jsx/src/test-utils/keyup.ts +27 -0
- package/packages/keyboard/README.md +2 -0
- package/packages/keyboard/src/Backdrop/Backdrop.scss +2 -0
- package/packages/keyboard/src/KeyboardBase.tsx +16 -4
- package/packages/keyboard/src/WhitelabelKeyboard/Keyboard.scss +10 -0
- package/packages/keyboard/src/WhitelabelKeyboard/Keyboard.tsx +128 -142
- package/packages/keyboard/src/WhitelabelKeyboard/WhitelabelStyles/whitelabel.scss +4 -0
- package/packages/keyboard/src/WhitelabelKeyboard/_sizes.1080.scss +1 -0
- package/packages/keyboard/src/WhitelabelKeyboard/_sizes.scss +1 -0
- package/packages/keyboard/src/WhitelabelKeyboard/icons/key_language.svg +20 -0
- package/packages/keyboard/src/WhitelabelKeyboard/index.ts +1 -1
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/arabic.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/burmese.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/dari.ts +28 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/hebrew.ts +28 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/index.ts +15 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/korean.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/latin.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/pashto.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/persian.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/russian.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/spanish.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/special.ts +28 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/tibetan.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/turkish.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/ukrainian.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/urdu.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/types.ts +22 -2
- package/packages/keyboard/src/types/index.ts +1 -1
- package/packages/keyboard/src/utils/caret.ts +5 -8
- package/packages/keyboard/src/utils/input.ts +5 -6
- package/packages/keyboard/src/utils/setInputSelectionRange.ts +10 -0
- package/packages/l10n/README.md +18 -0
- package/packages/l10n/src/date/common.ts +18 -6
- package/packages/l10n/src/date/cs.ts +2 -8
- package/packages/l10n/src/date/de.ts +97 -0
- package/packages/l10n/src/date/en-001.ts +3 -3
- package/packages/l10n/src/date/en-common.ts +5 -4
- package/packages/l10n/src/date/en-us.ts +3 -3
- package/packages/l10n/src/date/es.ts +71 -0
- package/packages/l10n/src/date/fr.ts +94 -0
- package/packages/l10n/src/date/he.ts +101 -0
- package/packages/l10n/src/date/iso.ts +12 -13
- package/packages/l10n/src/date/types.ts +9 -0
- package/packages/l10n/src/l10n.ts +61 -3
- package/packages/list/src/Base/Base.tsx +19 -9
- package/packages/list/src/Base/interface.ts +2 -2
- package/packages/list/src/BasicList/BasicList.tsx +7 -7
- package/packages/list/src/CenteredList/CenteredList.tsx +2 -2
- package/packages/list/src/CenteredList/controller.ts +0 -1
- package/packages/list/src/EdgeOffsetList/EdgeOffsetList.tsx +10 -10
- package/packages/list/src/FirstOnlyList/FirstOnlyList.tsx +2 -2
- package/packages/list/src/FirstOnlyVariedList/FirstOnlyVariedList.tsx +2 -2
- package/packages/list/src/FixedToEndList/FixedToEndList.tsx +2 -2
- package/packages/list/src/UnifiedListController/UnifiedListController.ts +6 -2
- package/packages/list/src/interface.ts +2 -2
- package/packages/logger/src/loggers/ConsoleLogger/ConsoleLogger.ts +7 -1
- package/packages/logger/src/loggers/SentryLogger/Sentry.ts +1 -0
- package/packages/logger/src/loggers/SentryLogger/SentryLogger.ts +5 -3
- package/packages/menu/src/MenuAndContentContainer/MenuAndContentContainer.tsx +31 -3
- package/packages/menu/src/MenuAndContentContainer/interface.ts +8 -0
- package/packages/modal-service/README.md +4 -1
- package/packages/modal-service/src/ModalService.tsx +29 -5
- package/packages/perf-utils/README.md +1 -120
- package/packages/perf-utils/src/array/filter.ts +1 -54
- package/packages/perf-utils/src/array/find.ts +1 -43
- package/packages/perf-utils/src/array/findIndex.ts +1 -43
- package/packages/perf-utils/src/array/forEach.ts +1 -48
- package/packages/perf-utils/src/array/includes.ts +1 -41
- package/packages/perf-utils/src/array/includesNaN.ts +1 -32
- package/packages/perf-utils/src/array/index.ts +1 -7
- package/packages/perf-utils/src/array/map.ts +1 -52
- package/packages/player-ui/README.md +1 -1
- package/packages/player-ui/src/CurrentTime.tsx +2 -2
- package/packages/player-ui/src/Duration.tsx +2 -2
- package/packages/player-ui/src/PauseButton.tsx +8 -0
- package/packages/player-ui/src/PlayerInteractable.tsx +1 -0
- package/packages/player-ui/src/PlayerTime.tsx +3 -1
- package/packages/player-ui/src/PlayerUI.tsx +68 -35
- package/packages/player-ui/src/RemainingTime.tsx +2 -2
- package/packages/player-ui/src/Seekbar.tsx +110 -18
- package/packages/player-ui/src/Seeking.ts +57 -16
- package/packages/player-ui/src/Subtitles.tsx +2 -2
- package/packages/player-ui/src/index.ts +1 -0
- package/packages/player-ui/src/mocks.ts +32 -8
- package/packages/player-ui/src/timeUtils.ts +3 -3
- package/packages/player-ui/src/types.ts +9 -3
- package/packages/router/README.md +1 -0
- package/packages/router/src/Route.tsx +61 -27
- package/packages/router/src/Router.tsx +63 -14
- package/packages/router/src/history.ts +8 -1
- package/packages/router/src/index.ts +1 -1
- package/packages/router/src/utils.ts +9 -4
- package/packages/sass-utils/src/linear-gradient.scss +9 -4
- package/packages/sass-utils/src/scale.1080.scss +3 -1
- package/packages/sass-utils/src/scale.720.scss +1 -1
- package/packages/time/README.md +4 -1
- package/packages/time/src/Time.ts +35 -13
- package/packages/time/src/adapters/24iMediaTimeApi.ts +47 -0
- package/packages/time/src/constants.ts +1 -0
- package/packages/time/src/services/24iMediaTimeApi/24iMediaTimeApi.ts +43 -0
- package/packages/time/src/services/24iMediaTimeApi/index.ts +6 -0
- package/packages/toast/src/ToastService.scss +1 -0
- package/packages/toast/src/ToastService.tsx +16 -5
- package/packages/types-bigscreen-jsx/README.md +5 -4
- package/packages/types-bigscreen-jsx/index.d.ts +72 -67
- package/packages/utils/README.md +27 -0
- package/packages/utils/src/elementUtils.ts +25 -0
- package/packages/utils/src/forceReflow.ts +14 -0
- package/packages/utils/src/index.ts +8 -0
- package/packages/utils/src/keyPress/index.ts +6 -0
- package/packages/utils/src/keyPress/keyPressSimulator.ts +74 -0
- package/packages/utils/src/keyPress/simulateKeyPress.ts +25 -0
- package/packages/utils/src/scaledImage.ts +6 -3
- package/packages/utils/src/textUtils.ts +46 -14
- package/packages/utils/src/wait.ts +3 -1
- package/packages/utils/src/xhr/xhrSend.ts +3 -1
- package/packages/utils/src/xhr/xhrSendRetry.ts +3 -1
- package/packages/zapping/src/ChannelZapping.ts +9 -0
- package/packages/zapping/src/Zapping.tsx +10 -0
- package/utils/release/release.ts +156 -0
- package/packages/driver-tizen/src/types.ts +0 -14
- package/packages/focus/src/Layout/__test__/Base.spec.ts +0 -180
- package/packages/focus/src/Layout/__test__/Horizontal.spec.ts +0 -94
- package/packages/focus/src/Layout/__test__/Matrix.spec.ts +0 -261
- package/packages/focus/src/Layout/__test__/Vertical.spec.ts +0 -46
- package/packages/focus/src/Layout/__test__/isRtl.spec.ts +0 -23
- package/packages/focus/src/Layout/__test__/shared.ts +0 -19
- package/packages/keyboard/src/WhitelabelKeyboard/focusMatrix.ts +0 -19
|
@@ -1,33 +1,42 @@
|
|
|
1
1
|
import { Component, createRef } from '@24i/bigscreen-sdk/jsx';
|
|
2
2
|
import { IFocusable } from '@24i/bigscreen-sdk/focus';
|
|
3
3
|
import { stopEvent } from '@24i/bigscreen-sdk/utils/stopEvent';
|
|
4
|
-
import { ITimeUpdateEvent, IDurationChangeEvent } from '@24i/
|
|
4
|
+
import { ITimeUpdateEvent, IDurationChangeEvent } from '@24i/bigscreen-players-engine-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
|
-
import { PlayerUICommonProps } from './types';
|
|
10
|
+
import { IPlayerUIWithSeeking, PlayerUICommonProps } from './types';
|
|
10
11
|
|
|
11
12
|
const CONSECUTIVE_TIMEOUT = 500;
|
|
12
13
|
const FAST_TRESHOLD = 5;
|
|
13
14
|
const SLOW_TIME = 10000;
|
|
14
|
-
const FAST_TIME =
|
|
15
|
+
const FAST_TIME = 30000;
|
|
16
|
+
const SAFE_END_MARGIN = 10000;
|
|
15
17
|
const TO_PERCENT = 100;
|
|
16
18
|
|
|
17
|
-
type Props =
|
|
19
|
+
type Props = {
|
|
20
|
+
ui: IPlayerUIWithSeeking;
|
|
21
|
+
children?: JSX.Element;
|
|
22
|
+
} & PlayerUICommonProps;
|
|
18
23
|
|
|
19
24
|
export class Seekbar extends Component<Props> implements IFocusable {
|
|
20
25
|
wrap = createRef<HTMLDivElement>();
|
|
21
26
|
|
|
27
|
+
seekBarWrap = createRef<HTMLDivElement>();
|
|
28
|
+
|
|
22
29
|
seekBar = createRef<HTMLDivElement>();
|
|
23
30
|
|
|
24
31
|
seekPoint = createRef<HTMLDivElement>();
|
|
25
32
|
|
|
26
33
|
seekTime = createRef<PlayerTime>();
|
|
27
34
|
|
|
28
|
-
|
|
35
|
+
displaySeekPoint = getDisplayToggler(this.seekPoint);
|
|
36
|
+
|
|
37
|
+
leftConsecutiveness = 0;
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
rightConsecutiveness = 0;
|
|
31
40
|
|
|
32
41
|
leftConsecutiveTimeout = createTimeout();
|
|
33
42
|
|
|
@@ -37,6 +46,10 @@ export class Seekbar extends Component<Props> implements IFocusable {
|
|
|
37
46
|
|
|
38
47
|
duration = 0;
|
|
39
48
|
|
|
49
|
+
isMouseDownPressed = false;
|
|
50
|
+
|
|
51
|
+
seekingDisabled = false;
|
|
52
|
+
|
|
40
53
|
static defaultProps = {
|
|
41
54
|
className: '',
|
|
42
55
|
};
|
|
@@ -45,18 +58,59 @@ export class Seekbar extends Component<Props> implements IFocusable {
|
|
|
45
58
|
const { ui } = this.props;
|
|
46
59
|
const playerInstance = ui.getPlayer();
|
|
47
60
|
this.duration = playerInstance.duration;
|
|
61
|
+
document.addEventListener('mouseup', this.onMouseUp);
|
|
62
|
+
document.addEventListener('mousemove', this.onMouseMove);
|
|
48
63
|
ui.seeking.addEventListener('seektimeupdate', this.onSeekTimeUpdate);
|
|
64
|
+
ui.seeking.addEventListener('stopautomaticseek', this.onStopAutomaticSeek);
|
|
49
65
|
ui.getPlayer().addEventListener('timeupdate', this.onTimeUpdate);
|
|
50
66
|
ui.getPlayer().addEventListener('durationchange', this.onDurationUpdate);
|
|
51
67
|
}
|
|
52
68
|
|
|
53
69
|
componentWillUnmount() {
|
|
54
70
|
const { ui } = this.props;
|
|
71
|
+
document.removeEventListener('mouseup', this.onMouseUp);
|
|
72
|
+
document.removeEventListener('mousemove', this.onMouseMove);
|
|
55
73
|
ui.seeking.removeEventListener('seektimeupdate', this.onSeekTimeUpdate);
|
|
74
|
+
ui.seeking.removeEventListener('stopautomaticseek', this.onStopAutomaticSeek);
|
|
56
75
|
ui.getPlayer().removeEventListener('timeupdate', this.onTimeUpdate);
|
|
57
76
|
ui.getPlayer().removeEventListener('durationchange', this.onDurationUpdate);
|
|
58
77
|
}
|
|
59
78
|
|
|
79
|
+
onMouseMove = (event: MouseEvent) => {
|
|
80
|
+
if (!this.isMouseDownPressed || this.seekingDisabled) return;
|
|
81
|
+
const { ui: { seeking } } = this.props;
|
|
82
|
+
const wrapRect = this.wrap.current!.getBoundingClientRect();
|
|
83
|
+
const clientX = event.clientX - wrapRect.left;
|
|
84
|
+
const wrapRight = wrapRect.right - wrapRect.left;
|
|
85
|
+
let percentage = (TO_PERCENT * clientX) / wrapRight;
|
|
86
|
+
percentage = Math.max(0, Math.min(TO_PERCENT, percentage));
|
|
87
|
+
const seekTo = Math.round((this.duration / TO_PERCENT) * percentage);
|
|
88
|
+
seeking.setSeekTime(seekTo);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
onMouseClick = (event: MouseEvent) => {
|
|
92
|
+
if (this.seekingDisabled) return;
|
|
93
|
+
const { ui: { seeking } } = this.props;
|
|
94
|
+
const wrapWidth = this.wrap.current!.offsetWidth;
|
|
95
|
+
const percentage = (TO_PERCENT * event.offsetX) / wrapWidth;
|
|
96
|
+
const seekTo = Math.round((this.duration / TO_PERCENT) * percentage);
|
|
97
|
+
seeking.setSeekTime(seekTo);
|
|
98
|
+
seeking.confirmSeek();
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
onMouseDown = () => {
|
|
102
|
+
const { ui } = this.props;
|
|
103
|
+
this.isMouseDownPressed = true;
|
|
104
|
+
ui.disableHiding();
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
onMouseUp = () => {
|
|
108
|
+
const { ui } = this.props;
|
|
109
|
+
this.isMouseDownPressed = false;
|
|
110
|
+
ui.seeking.confirmSeek();
|
|
111
|
+
ui.enableHiding();
|
|
112
|
+
};
|
|
113
|
+
|
|
60
114
|
onKeyDown = (event: KeyboardEvent) => {
|
|
61
115
|
const processed = switchByKey(event, {
|
|
62
116
|
LEFT: this.onLeft,
|
|
@@ -72,34 +126,50 @@ export class Seekbar extends Component<Props> implements IFocusable {
|
|
|
72
126
|
};
|
|
73
127
|
|
|
74
128
|
onLeft = () => {
|
|
129
|
+
if (this.seekingDisabled) return true;
|
|
75
130
|
const { ui } = this.props;
|
|
76
|
-
this.
|
|
131
|
+
this.leftConsecutiveness += 1;
|
|
77
132
|
if (ui.seeking.isAutomaticallySeeking()) {
|
|
78
133
|
ui.seeking.stopAutomaticSeek();
|
|
79
134
|
}
|
|
80
|
-
ui.seeking.seekBackward(this.
|
|
135
|
+
ui.seeking.seekBackward(this.leftConsecutiveness >= FAST_TRESHOLD ? FAST_TIME : SLOW_TIME);
|
|
81
136
|
this.leftConsecutiveTimeout.set(() => {
|
|
82
|
-
this.
|
|
137
|
+
this.leftConsecutiveness = 0;
|
|
83
138
|
}, CONSECUTIVE_TIMEOUT);
|
|
84
139
|
return true;
|
|
85
140
|
};
|
|
86
141
|
|
|
87
142
|
onRight = () => {
|
|
143
|
+
if (this.seekingDisabled) return true;
|
|
88
144
|
const { ui } = this.props;
|
|
89
|
-
|
|
145
|
+
const { seekTime } = ui.seeking;
|
|
146
|
+
if (seekTime == null && this.currentTime + SLOW_TIME >= this.duration) return true;
|
|
147
|
+
this.rightConsecutiveness += 1;
|
|
90
148
|
if (ui.seeking.isAutomaticallySeeking()) {
|
|
91
149
|
ui.seeking.stopAutomaticSeek();
|
|
92
150
|
}
|
|
93
|
-
|
|
151
|
+
const isFastSeeking = this.rightConsecutiveness >= FAST_TRESHOLD;
|
|
152
|
+
if (
|
|
153
|
+
(seekTime != null
|
|
154
|
+
&& (seekTime + SLOW_TIME >= this.duration - SAFE_END_MARGIN
|
|
155
|
+
|| (isFastSeeking && seekTime + FAST_TIME >= this.duration - SAFE_END_MARGIN)))
|
|
156
|
+
|| (seekTime == null && this.currentTime >= this.duration - SAFE_END_MARGIN)
|
|
157
|
+
) {
|
|
158
|
+
ui.seeking.setSeekTime(this.duration - SAFE_END_MARGIN);
|
|
159
|
+
} else {
|
|
160
|
+
ui.seeking.seekForward(isFastSeeking ? FAST_TIME : SLOW_TIME);
|
|
161
|
+
}
|
|
94
162
|
this.rightConsecutiveTimeout.set(() => {
|
|
95
|
-
this.
|
|
163
|
+
this.rightConsecutiveness = 0;
|
|
96
164
|
}, CONSECUTIVE_TIMEOUT);
|
|
97
165
|
return true;
|
|
98
166
|
};
|
|
99
167
|
|
|
100
168
|
onEnter = () => {
|
|
101
|
-
const { ui } = this.props;
|
|
102
|
-
|
|
169
|
+
const { ui: { seeking, getPlayer } } = this.props;
|
|
170
|
+
const player = getPlayer();
|
|
171
|
+
if (!player.playing) player.play();
|
|
172
|
+
return seeking.confirmSeek();
|
|
103
173
|
};
|
|
104
174
|
|
|
105
175
|
onSeekTimeUpdate = (seekTime: number) => {
|
|
@@ -108,6 +178,11 @@ export class Seekbar extends Component<Props> implements IFocusable {
|
|
|
108
178
|
this.updateSeekBar();
|
|
109
179
|
};
|
|
110
180
|
|
|
181
|
+
onStopAutomaticSeek = () => {
|
|
182
|
+
const { ui } = this.props;
|
|
183
|
+
ui.enableHiding();
|
|
184
|
+
};
|
|
185
|
+
|
|
111
186
|
onTimeUpdate = ({ currentTime }: ITimeUpdateEvent) => {
|
|
112
187
|
const { ui } = this.props;
|
|
113
188
|
this.currentTime = currentTime;
|
|
@@ -121,7 +196,7 @@ export class Seekbar extends Component<Props> implements IFocusable {
|
|
|
121
196
|
const { ui } = this.props;
|
|
122
197
|
const player = ui.getPlayer();
|
|
123
198
|
if (player.live) {
|
|
124
|
-
const { programStart = 0, programEnd = 0 } = player.
|
|
199
|
+
const { programStart = 0, programEnd = 0 } = player.metadata;
|
|
125
200
|
this.duration = programEnd - programStart || Date.now();
|
|
126
201
|
} else {
|
|
127
202
|
this.duration = duration;
|
|
@@ -133,7 +208,7 @@ export class Seekbar extends Component<Props> implements IFocusable {
|
|
|
133
208
|
const { ui } = this.props;
|
|
134
209
|
const player = ui.getPlayer();
|
|
135
210
|
if (player.live) {
|
|
136
|
-
const { programStart = 0, programEnd = 0 } = player.
|
|
211
|
+
const { programStart = 0, programEnd = 0 } = player.metadata;
|
|
137
212
|
const { start, end } = player.seekableRange;
|
|
138
213
|
return getLiveProgressBasedOnCurrentTime(
|
|
139
214
|
programStart,
|
|
@@ -160,17 +235,34 @@ export class Seekbar extends Component<Props> implements IFocusable {
|
|
|
160
235
|
this.seekPoint.current!.style.left = `${percentTime}%`;
|
|
161
236
|
}
|
|
162
237
|
|
|
238
|
+
disableSeeking() {
|
|
239
|
+
this.seekingDisabled = true;
|
|
240
|
+
this.displaySeekPoint.hide();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
enableSeeking() {
|
|
244
|
+
this.seekingDisabled = false;
|
|
245
|
+
this.displaySeekPoint.show();
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
isSeekingDisabled() {
|
|
249
|
+
return this.seekingDisabled;
|
|
250
|
+
}
|
|
251
|
+
|
|
163
252
|
render() {
|
|
164
|
-
const { className } = this.props;
|
|
253
|
+
const { children, className } = this.props;
|
|
165
254
|
return (
|
|
166
255
|
<div
|
|
167
256
|
className={`seek-bar ${className}`}
|
|
168
257
|
ref={this.wrap}
|
|
169
258
|
tabIndex={0}
|
|
170
259
|
onKeyDown={this.onKeyDown}
|
|
260
|
+
onMouseDown={this.onMouseDown}
|
|
261
|
+
onClick={this.onMouseClick}
|
|
171
262
|
onBlur={this.onBlur}
|
|
172
263
|
>
|
|
173
|
-
|
|
264
|
+
{children}
|
|
265
|
+
<div className="bar" ref={this.seekBarWrap}>
|
|
174
266
|
<div className="bg" ref={this.seekBar} />
|
|
175
267
|
</div>
|
|
176
268
|
<div className="point" ref={this.seekPoint}>
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { IEvents, EventMapType, EventsManager } from '@24i/bigscreen-sdk/events-manager';
|
|
2
|
-
import { createInterval } from '@24i/bigscreen-sdk/utils/timers';
|
|
3
|
-
import { PlayerBase } from '@24i/
|
|
2
|
+
import { createInterval, createTimeout } from '@24i/bigscreen-sdk/utils/timers';
|
|
3
|
+
import { PlayerBase } from '@24i/bigscreen-players-engine-base';
|
|
4
4
|
|
|
5
|
-
const DEFAULT_SEEK_TIME =
|
|
5
|
+
const DEFAULT_SEEK_TIME = 10000;
|
|
6
|
+
const FAST_SEEK_TIME = 30000;
|
|
6
7
|
const AUTOMATIC_SEEK_INTERVAL = 300;
|
|
8
|
+
const FAST_THRESHOLD = 5;
|
|
9
|
+
const CONSECUTIVE_TIMEOUT = 500;
|
|
7
10
|
|
|
8
11
|
interface SeekingEventsMap extends EventMapType {
|
|
9
12
|
'seektimeupdate': (payload: number) => void,
|
|
@@ -23,13 +26,21 @@ export class Seeking implements IEvents<SeekingEventsMap> {
|
|
|
23
26
|
|
|
24
27
|
automaticSeekInterval = createInterval();
|
|
25
28
|
|
|
26
|
-
player: PlayerBase
|
|
29
|
+
player: PlayerBase | null;
|
|
27
30
|
|
|
28
31
|
isAutomaticallySeekingForward = false;
|
|
29
32
|
|
|
30
33
|
isAutomaticallySeekingBackward = false;
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
ffConsecutiveness = 0;
|
|
36
|
+
|
|
37
|
+
rewConsecutiveness = 0;
|
|
38
|
+
|
|
39
|
+
ffConsecutiveTimeout = createTimeout();
|
|
40
|
+
|
|
41
|
+
rewConsecutiveTimeout = createTimeout();
|
|
42
|
+
|
|
43
|
+
constructor(player: PlayerBase | null = null) {
|
|
33
44
|
this.player = player;
|
|
34
45
|
}
|
|
35
46
|
|
|
@@ -41,7 +52,7 @@ export class Seeking implements IEvents<SeekingEventsMap> {
|
|
|
41
52
|
this.player!.removeEventListener('seeked', this.nullSeekTime);
|
|
42
53
|
}
|
|
43
54
|
|
|
44
|
-
setPlayer(player: PlayerBase
|
|
55
|
+
setPlayer(player: PlayerBase) {
|
|
45
56
|
this.player = player;
|
|
46
57
|
}
|
|
47
58
|
|
|
@@ -76,28 +87,53 @@ export class Seeking implements IEvents<SeekingEventsMap> {
|
|
|
76
87
|
this.triggerEvent('seektimeupdate', this.seekTime!);
|
|
77
88
|
}
|
|
78
89
|
|
|
79
|
-
|
|
80
|
-
this.
|
|
90
|
+
automaticSeekForward() {
|
|
91
|
+
if (this.isAutomaticallySeekingForward) {
|
|
92
|
+
this.ffConsecutiveTimeout.set(() => {
|
|
93
|
+
this.ffConsecutiveness = 0;
|
|
94
|
+
}, CONSECUTIVE_TIMEOUT);
|
|
95
|
+
this.ffConsecutiveness += 1;
|
|
96
|
+
if (this.ffConsecutiveness === FAST_THRESHOLD) {
|
|
97
|
+
this.automaticSeekInterval.set(
|
|
98
|
+
() => this.seekForward(FAST_SEEK_TIME),
|
|
99
|
+
AUTOMATIC_SEEK_INTERVAL,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
81
104
|
this.isAutomaticallySeekingForward = true;
|
|
105
|
+
this.ffConsecutiveness += 1;
|
|
82
106
|
this.seekForward();
|
|
83
|
-
this.automaticSeekInterval.set(() =>
|
|
84
|
-
this.seekForward();
|
|
85
|
-
}, AUTOMATIC_SEEK_INTERVAL);
|
|
107
|
+
this.automaticSeekInterval.set(() => this.seekForward(), AUTOMATIC_SEEK_INTERVAL);
|
|
86
108
|
}
|
|
87
109
|
|
|
88
|
-
|
|
89
|
-
this.
|
|
110
|
+
automaticSeekBackward() {
|
|
111
|
+
if (this.isAutomaticallySeekingBackward) {
|
|
112
|
+
this.rewConsecutiveTimeout.set(() => {
|
|
113
|
+
this.rewConsecutiveness = 0;
|
|
114
|
+
}, CONSECUTIVE_TIMEOUT);
|
|
115
|
+
this.rewConsecutiveness += 1;
|
|
116
|
+
if (this.rewConsecutiveness === FAST_THRESHOLD) {
|
|
117
|
+
this.automaticSeekInterval.set(
|
|
118
|
+
() => this.seekBackward(FAST_SEEK_TIME),
|
|
119
|
+
AUTOMATIC_SEEK_INTERVAL,
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
90
124
|
this.isAutomaticallySeekingBackward = true;
|
|
125
|
+
this.rewConsecutiveness += 1;
|
|
91
126
|
this.seekBackward();
|
|
92
|
-
this.automaticSeekInterval.set(() =>
|
|
93
|
-
this.seekBackward();
|
|
94
|
-
}, AUTOMATIC_SEEK_INTERVAL);
|
|
127
|
+
this.automaticSeekInterval.set(() => this.seekBackward(), AUTOMATIC_SEEK_INTERVAL);
|
|
95
128
|
}
|
|
96
129
|
|
|
97
130
|
stopAutomaticSeek() {
|
|
131
|
+
if (this.isAutomaticallySeeking()) this.triggerEvent('stopautomaticseek');
|
|
98
132
|
this.automaticSeekInterval.clear();
|
|
99
133
|
this.isAutomaticallySeekingForward = false;
|
|
100
134
|
this.isAutomaticallySeekingBackward = false;
|
|
135
|
+
this.ffConsecutiveness = 0;
|
|
136
|
+
this.rewConsecutiveness = 0;
|
|
101
137
|
}
|
|
102
138
|
|
|
103
139
|
cancelSeek() {
|
|
@@ -110,6 +146,11 @@ export class Seeking implements IEvents<SeekingEventsMap> {
|
|
|
110
146
|
this.triggerEvent('seektimeupdate', this.seekTime!);
|
|
111
147
|
};
|
|
112
148
|
|
|
149
|
+
setSeekTime = (seekTime: number) => {
|
|
150
|
+
this.seekTime = seekTime;
|
|
151
|
+
this.triggerEvent('seektimeupdate', this.seekTime!);
|
|
152
|
+
};
|
|
153
|
+
|
|
113
154
|
confirmSeek() {
|
|
114
155
|
if (!this.player) return false;
|
|
115
156
|
this.stopAutomaticSeek();
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { PlayerBase, ITimeUpdateEvent } from '@24i/
|
|
1
|
+
import { PlayerBase, ITimeUpdateEvent } from '@24i/bigscreen-players-engine-base';
|
|
2
2
|
import { Component, createRef, DeclareProps, setText } from '@24i/bigscreen-sdk/jsx';
|
|
3
3
|
import { getDisplayToggler } from '@24i/bigscreen-sdk/utils';
|
|
4
4
|
import { SubtitlesType } from '@24i/smartapps-datalayer/src/models';
|
|
5
5
|
import { timeToMs } from './timeUtils';
|
|
6
6
|
|
|
7
7
|
type Props = {
|
|
8
|
-
player: PlayerBase
|
|
8
|
+
player: PlayerBase,
|
|
9
9
|
className?: string,
|
|
10
10
|
};
|
|
11
11
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { PlayerUI } from './PlayerUI';
|
|
2
2
|
export type { PlayerUIState } from './PlayerUI';
|
|
3
|
+
export type { IPlayerUIWithSeeking } from './types';
|
|
3
4
|
export { BackwardButton } from './BackwardButton';
|
|
4
5
|
export { CurrentTime } from './CurrentTime';
|
|
5
6
|
export { Duration } from './Duration';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { PlayerBase, PlayerBaseMock } from '@24i/
|
|
1
|
+
import { IPlayerProperties, PlayerBase, PlayerBaseMock } from '@24i/bigscreen-players-engine-base';
|
|
2
2
|
import { EventsManager } from '@24i/bigscreen-sdk/events-manager';
|
|
3
|
-
import {
|
|
3
|
+
import { IPlayerUIWithSeeking } from './types';
|
|
4
4
|
|
|
5
|
-
const getSeekingMock = (): jest.Mocked<
|
|
5
|
+
const getSeekingMock = (): jest.Mocked<IPlayerUIWithSeeking['seeking']> => ({
|
|
6
6
|
events: {} as EventsManager<{}>,
|
|
7
7
|
addEventListener: jest.fn(),
|
|
8
8
|
removeEventListener: jest.fn(),
|
|
@@ -13,12 +13,16 @@ const getSeekingMock = (): jest.Mocked<IPlayerUI['seeking']> => ({
|
|
|
13
13
|
isAutomaticallySeeking: jest.fn(),
|
|
14
14
|
isAutomaticallySeekingForward: false,
|
|
15
15
|
isAutomaticallySeekingBackward: false,
|
|
16
|
+
ffConsecutiveness: 0,
|
|
17
|
+
rewConsecutiveness: 0,
|
|
18
|
+
ffConsecutiveTimeout: null!,
|
|
19
|
+
rewConsecutiveTimeout: null!,
|
|
16
20
|
isSeeking: jest.fn(),
|
|
17
21
|
startSeeking: jest.fn(),
|
|
18
22
|
seekForward: jest.fn(),
|
|
19
23
|
seekBackward: jest.fn(),
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
automaticSeekForward: jest.fn(),
|
|
25
|
+
automaticSeekBackward: jest.fn(),
|
|
22
26
|
stopAutomaticSeek: jest.fn(),
|
|
23
27
|
cancelSeek: jest.fn(),
|
|
24
28
|
confirmSeek: jest.fn(),
|
|
@@ -26,16 +30,36 @@ const getSeekingMock = (): jest.Mocked<IPlayerUI['seeking']> => ({
|
|
|
26
30
|
unsubscribeEvents: jest.fn(),
|
|
27
31
|
setPlayer: jest.fn(),
|
|
28
32
|
nullSeekTime: jest.fn(),
|
|
33
|
+
setSeekTime: jest.fn(),
|
|
29
34
|
});
|
|
30
35
|
|
|
31
|
-
|
|
36
|
+
const PLAYER_MOCK_DURATION = 60000;
|
|
32
37
|
|
|
33
|
-
export const
|
|
38
|
+
export const getPlayerMock = (): PlayerBase => {
|
|
39
|
+
const initialConfig: IPlayerProperties = {
|
|
40
|
+
source: {
|
|
41
|
+
url: '',
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
const parentElement = document.createElement('div');
|
|
45
|
+
|
|
46
|
+
const playerMock = new PlayerBaseMock(initialConfig, parentElement);
|
|
47
|
+
playerMock.source = initialConfig.source;
|
|
48
|
+
jest.spyOn(playerMock, 'duration', 'get').mockReturnValue(PLAYER_MOCK_DURATION);
|
|
49
|
+
|
|
50
|
+
return playerMock;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const getUiMock = (): { ui: jest.Mocked<IPlayerUIWithSeeking> } => ({
|
|
34
54
|
ui: {
|
|
35
|
-
getPlayer: jest.fn((): PlayerBase
|
|
55
|
+
getPlayer: jest.fn((): PlayerBase => getPlayerMock()),
|
|
36
56
|
heartbeat: jest.fn(),
|
|
37
57
|
trigger: jest.fn(),
|
|
38
58
|
isPlaying: jest.fn(),
|
|
59
|
+
enableHiding: jest.fn(),
|
|
60
|
+
disableHiding: jest.fn(),
|
|
61
|
+
enableSeeking: jest.fn(),
|
|
62
|
+
disableSeeking: jest.fn(),
|
|
39
63
|
seeking: getSeekingMock(),
|
|
40
64
|
},
|
|
41
65
|
});
|
|
@@ -63,9 +63,9 @@ export const formatTime = (duration: number, pattern: string) => {
|
|
|
63
63
|
const unitValues = calculateUnitValues(duration, units);
|
|
64
64
|
let result: string = pattern;
|
|
65
65
|
forEach(matches, (match) => {
|
|
66
|
-
const formatedValue = Number.isNaN(unitValues[match.unit])
|
|
67
|
-
'--'
|
|
68
|
-
unitValues[match.unit]!.toString().padStart(match.count, '0');
|
|
66
|
+
const formatedValue = Number.isNaN(unitValues[match.unit])
|
|
67
|
+
? '--'
|
|
68
|
+
: unitValues[match.unit]!.toString().padStart(match.count, '0');
|
|
69
69
|
result = result.replace(
|
|
70
70
|
match.completeMatch,
|
|
71
71
|
formatedValue,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PlayerBase } from '@24i/
|
|
1
|
+
import { PlayerBase } from '@24i/bigscreen-players-engine-base';
|
|
2
2
|
import { Seeking } from './Seeking';
|
|
3
3
|
|
|
4
4
|
export enum PlayerAction {
|
|
@@ -20,8 +20,12 @@ export interface ActionsWithPayloadMap {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export interface IPlayerUI {
|
|
23
|
-
seeking
|
|
24
|
-
getPlayer: () => PlayerBase
|
|
23
|
+
seeking?: Seeking;
|
|
24
|
+
getPlayer: () => PlayerBase,
|
|
25
|
+
disableHiding: () => void,
|
|
26
|
+
enableHiding: () => void,
|
|
27
|
+
disableSeeking: () => void,
|
|
28
|
+
enableSeeking: () => void,
|
|
25
29
|
heartbeat: () => void,
|
|
26
30
|
trigger<K extends keyof ActionsWithoutPayloadMap>(action: K): void,
|
|
27
31
|
trigger<K extends keyof ActionsWithPayloadMap>(
|
|
@@ -30,6 +34,8 @@ export interface IPlayerUI {
|
|
|
30
34
|
isPlaying: () => boolean,
|
|
31
35
|
}
|
|
32
36
|
|
|
37
|
+
export type IPlayerUIWithSeeking = Required<IPlayerUI>;
|
|
38
|
+
|
|
33
39
|
export type PlayerUICommonProps = {
|
|
34
40
|
ui: IPlayerUI,
|
|
35
41
|
className?: string,
|
|
@@ -16,6 +16,7 @@ It will take care of route switching based on hash changes. It also supports par
|
|
|
16
16
|
- `children` - Routes
|
|
17
17
|
- `defaultPath` - optional path to which go after Router is mounted (default: `/`)
|
|
18
18
|
- `detachInactiveRoutes` - optional flag if routes should detach from DOM entirely during route switching (default: `true`)
|
|
19
|
+
- `canBack` - optional function whether the router can route back
|
|
19
20
|
|
|
20
21
|
### Interface
|
|
21
22
|
- `getActiveRoute()`*: Route | null* - Returns active route component
|
|
@@ -3,36 +3,38 @@ import {
|
|
|
3
3
|
Component,
|
|
4
4
|
createRef,
|
|
5
5
|
detachNode,
|
|
6
|
+
Reference,
|
|
6
7
|
replaceNode,
|
|
7
8
|
} from '@24i/bigscreen-sdk/jsx';
|
|
8
9
|
import { filter, forEach } from '@24i/bigscreen-sdk/perf-utils/array';
|
|
10
|
+
import { addClass, removeClass } from '@24i/bigscreen-sdk/utils';
|
|
11
|
+
import { ModalService } from '@24i/bigscreen-sdk/modal-service';
|
|
12
|
+
import { menuService } from '@24i/bigscreen-sdk/menu';
|
|
9
13
|
import { getCurrentHash } from './utils';
|
|
10
14
|
import { IRoute, RouteParams } from './types';
|
|
11
15
|
|
|
12
16
|
type Props = {
|
|
13
17
|
path: string,
|
|
18
|
+
domParent?: Reference<HTMLElement>;
|
|
14
19
|
regexpPath?: RegExp,
|
|
15
20
|
paramNames?: string[],
|
|
16
|
-
isDetachable?: boolean;
|
|
17
21
|
Component: Function,
|
|
18
22
|
};
|
|
19
23
|
|
|
24
|
+
const MRCU_DISABLED = 'mrcu-disabled';
|
|
25
|
+
|
|
20
26
|
export class Route extends Component<Props> {
|
|
21
27
|
wasCreated = false;
|
|
22
28
|
|
|
23
29
|
isDetached = false;
|
|
24
30
|
|
|
25
|
-
domParent: HTMLElement | null = null;
|
|
26
|
-
|
|
27
31
|
domRef = createRef<HTMLDivElement>();
|
|
28
32
|
|
|
29
33
|
component = createRef<IRoute | null>();
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (isDetachable) this.detach();
|
|
35
|
-
}
|
|
35
|
+
modalService = createRef<ModalService>();
|
|
36
|
+
|
|
37
|
+
shouldCallReactivateOnCloseModal = false;
|
|
36
38
|
|
|
37
39
|
getParams(): RouteParams {
|
|
38
40
|
const { regexpPath, paramNames } = this.props;
|
|
@@ -49,21 +51,50 @@ export class Route extends Component<Props> {
|
|
|
49
51
|
return {};
|
|
50
52
|
}
|
|
51
53
|
|
|
54
|
+
onMenuVisibilityChange = (isVisible: boolean) => {
|
|
55
|
+
if (isVisible) {
|
|
56
|
+
addClass(this.domRef, MRCU_DISABLED);
|
|
57
|
+
} else {
|
|
58
|
+
removeClass(this.domRef, MRCU_DISABLED);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
onCloseModalService = () => {
|
|
63
|
+
if (this.shouldCallReactivateOnCloseModal) {
|
|
64
|
+
this.component.current?.reactivate(this.getParams());
|
|
65
|
+
}
|
|
66
|
+
this.shouldCallReactivateOnCloseModal = false;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
getModalService() {
|
|
70
|
+
if (!this.modalService.current) {
|
|
71
|
+
this.appendMount(
|
|
72
|
+
<ModalService
|
|
73
|
+
ref={this.modalService}
|
|
74
|
+
onCloseLastModal={this.onCloseModalService}
|
|
75
|
+
/>,
|
|
76
|
+
this.domRef,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
return this.modalService;
|
|
80
|
+
}
|
|
81
|
+
|
|
52
82
|
show() {
|
|
53
|
-
this.
|
|
83
|
+
menuService.addEventListener('visibilitychange', this.onMenuVisibilityChange);
|
|
54
84
|
if (!this.wasCreated) {
|
|
55
85
|
this.mountRoute();
|
|
56
86
|
this.component.current?.activate(this.getParams());
|
|
87
|
+
} else if (this.modalService.current?.isOpen()) {
|
|
88
|
+
this.focusModal();
|
|
89
|
+
this.shouldCallReactivateOnCloseModal = true;
|
|
57
90
|
} else {
|
|
58
91
|
this.component.current?.reactivate(this.getParams());
|
|
59
92
|
}
|
|
60
93
|
}
|
|
61
94
|
|
|
62
95
|
hide() {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this.hideRoute();
|
|
66
|
-
}
|
|
96
|
+
menuService.removeEventListener('visibilitychange', this.onMenuVisibilityChange);
|
|
97
|
+
this.deactivate();
|
|
67
98
|
}
|
|
68
99
|
|
|
69
100
|
replace(newRoute: Route) {
|
|
@@ -75,8 +106,9 @@ export class Route extends Component<Props> {
|
|
|
75
106
|
}
|
|
76
107
|
|
|
77
108
|
attach() {
|
|
109
|
+
const { domParent } = this.props;
|
|
78
110
|
if (this.isDetached) {
|
|
79
|
-
attachNode(this.domRef,
|
|
111
|
+
attachNode(this.domRef, domParent!);
|
|
80
112
|
this.isDetached = false;
|
|
81
113
|
}
|
|
82
114
|
}
|
|
@@ -94,20 +126,27 @@ export class Route extends Component<Props> {
|
|
|
94
126
|
}
|
|
95
127
|
}
|
|
96
128
|
|
|
129
|
+
private focusModal() {
|
|
130
|
+
const mountedComponent = this.modalService.current!.getMountedComponent();
|
|
131
|
+
mountedComponent.current?.focus();
|
|
132
|
+
}
|
|
133
|
+
|
|
97
134
|
focus() {
|
|
98
135
|
if (this.wasCreated) {
|
|
99
|
-
this.
|
|
136
|
+
if (this.modalService.current?.isOpen()) {
|
|
137
|
+
this.focusModal();
|
|
138
|
+
} else {
|
|
139
|
+
this.component.current?.focus();
|
|
140
|
+
}
|
|
100
141
|
}
|
|
101
142
|
}
|
|
102
143
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (!isDetachable) this.domRef.current!.style.display = 'block';
|
|
144
|
+
showRoute() {
|
|
145
|
+
this.domRef.current!.style.display = 'block';
|
|
106
146
|
}
|
|
107
147
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (!isDetachable) this.domRef.current!.style.display = 'none';
|
|
148
|
+
hideRoute() {
|
|
149
|
+
this.domRef.current!.style.display = 'none';
|
|
111
150
|
}
|
|
112
151
|
|
|
113
152
|
private mountRoute() {
|
|
@@ -120,13 +159,8 @@ export class Route extends Component<Props> {
|
|
|
120
159
|
}
|
|
121
160
|
|
|
122
161
|
render() {
|
|
123
|
-
const { isDetachable } = this.props;
|
|
124
162
|
return (
|
|
125
|
-
<div
|
|
126
|
-
className="route"
|
|
127
|
-
style={!isDetachable ? { display: 'none' } : {}}
|
|
128
|
-
ref={this.domRef}
|
|
129
|
-
/>
|
|
163
|
+
<div className="route" ref={this.domRef} />
|
|
130
164
|
);
|
|
131
165
|
}
|
|
132
166
|
}
|