@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,6 +1,7 @@
|
|
|
1
1
|
import { filter, find, findIndex, map } from '@24i/bigscreen-sdk/perf-utils/array';
|
|
2
2
|
import { Asset } from '@24i/smartapps-datalayer/models';
|
|
3
3
|
import { i18n } from '@24i/bigscreen-sdk/i18n';
|
|
4
|
+
import { MINUTE_IN_MS } from '@24i/bigscreen-sdk/utils/timeConstants';
|
|
4
5
|
import { isStartVisible, isEndVisible, isOverFullWidth } from './utils';
|
|
5
6
|
import {
|
|
6
7
|
DataRange,
|
|
@@ -14,6 +15,7 @@ const START = 0;
|
|
|
14
15
|
const END = 1;
|
|
15
16
|
|
|
16
17
|
const TIMELINE_WIDTHS_TO_FETCH = 3;
|
|
18
|
+
const MINIMUM_BREAK_LENGTH = MINUTE_IN_MS;
|
|
17
19
|
|
|
18
20
|
export class DataManager implements IDataManager {
|
|
19
21
|
private readonly data: Asset[] = [];
|
|
@@ -84,50 +86,115 @@ export class DataManager implements IDataManager {
|
|
|
84
86
|
return [data[0].program!.startTime, data[data.length - 1].program!.endTime] as DataRange;
|
|
85
87
|
}
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
]
|
|
89
|
+
private isInterceptingDataRanges = (firstDataRange: DataRange, secondDataRange: DataRange) => (
|
|
90
|
+
(firstDataRange[START] < secondDataRange[END]
|
|
91
|
+
&& firstDataRange[START] > secondDataRange[START])
|
|
92
|
+
|| (secondDataRange[START] < firstDataRange[END]
|
|
93
|
+
&& secondDataRange[START] > firstDataRange[START])
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
private findRangeBeforeAndAfter = (currentRange: DataRange) => {
|
|
97
|
+
const rangeAfterIndex = findIndex(
|
|
98
|
+
this.dataRanges,
|
|
99
|
+
(dataRange) => dataRange[END] >= currentRange[END],
|
|
100
|
+
);
|
|
101
|
+
if (rangeAfterIndex === -1) {
|
|
102
|
+
return {
|
|
103
|
+
rangeAfter: undefined,
|
|
104
|
+
rangeBefore: this.dataRanges[this.dataRanges.length - 1],
|
|
105
|
+
};
|
|
98
106
|
}
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
107
|
+
const rangeAfter = this.dataRanges[rangeAfterIndex];
|
|
108
|
+
const rangeBefore = this.dataRanges[rangeAfterIndex - 1];
|
|
109
|
+
return { rangeAfter, rangeBefore };
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
private generateDataRangesForward = (start: number, end: number, cellSize: number) => {
|
|
113
|
+
const dataRanges: DataRange[] = [[start, start + cellSize]];
|
|
114
|
+
let currentStart = start + cellSize;
|
|
115
|
+
let currentEnd = currentStart + cellSize;
|
|
116
|
+
while (currentStart < end) {
|
|
117
|
+
if (currentEnd >= end) {
|
|
118
|
+
dataRanges.push([currentStart, end]);
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
dataRanges.push([currentStart, currentEnd]);
|
|
122
|
+
currentStart += cellSize;
|
|
123
|
+
currentEnd += cellSize;
|
|
104
124
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
125
|
+
return dataRanges;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
private generateDataRangesBackward = (start: number, end: number, cellSize: number) => {
|
|
129
|
+
const dataRanges: DataRange[] = [[start - cellSize, start]];
|
|
130
|
+
let currentEnd = start - cellSize;
|
|
131
|
+
let currentStart = currentEnd - cellSize;
|
|
132
|
+
while (currentEnd > start) {
|
|
133
|
+
if (currentStart <= start) {
|
|
134
|
+
dataRanges.push([start, currentEnd]);
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
dataRanges.push([currentStart, currentEnd]);
|
|
138
|
+
currentStart -= cellSize;
|
|
139
|
+
currentEnd -= cellSize;
|
|
140
|
+
}
|
|
141
|
+
return dataRanges;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/* eslint-disable complexity */
|
|
145
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
146
|
+
private getRangesMissingFromDataInRange([start, end]: DataRange) {
|
|
147
|
+
const currentRange = [start, end] as DataRange;
|
|
148
|
+
const cellSize = TIMELINE_WIDTHS_TO_FETCH * this.timelineWidthMs;
|
|
149
|
+
if (this.dataRanges.length === 0) return [currentRange] as DataRange[];
|
|
150
|
+
const { rangeBefore, rangeAfter } = this.findRangeBeforeAndAfter(currentRange);
|
|
151
|
+
if (rangeAfter == null) {
|
|
152
|
+
const lastDataRange = this.dataRanges[this.dataRanges.length - 1];
|
|
153
|
+
if (this.isInterceptingDataRanges(lastDataRange, currentRange)) {
|
|
154
|
+
if (end > lastDataRange[END]) {
|
|
155
|
+
return this.generateDataRangesForward(lastDataRange[END], end, cellSize);
|
|
156
|
+
}
|
|
157
|
+
if (start < lastDataRange[START]) {
|
|
158
|
+
return this.generateDataRangesBackward(start, lastDataRange[START], cellSize);
|
|
115
159
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
160
|
+
}
|
|
161
|
+
return [currentRange] as DataRange[];
|
|
162
|
+
}
|
|
163
|
+
if (rangeBefore == null) {
|
|
164
|
+
const firstDataRange = this.dataRanges[0];
|
|
165
|
+
if (this.isInterceptingDataRanges(firstDataRange, currentRange)) {
|
|
166
|
+
if (end > firstDataRange[END]) {
|
|
167
|
+
return this.generateDataRangesForward(firstDataRange[END], end, cellSize);
|
|
120
168
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (end <= rangeTo) {
|
|
124
|
-
return ranges;
|
|
169
|
+
if (start < firstDataRange[START]) {
|
|
170
|
+
return this.generateDataRangesBackward(firstDataRange[START], start, cellSize);
|
|
125
171
|
}
|
|
126
|
-
newRange = [rangeTo, end];
|
|
127
172
|
}
|
|
173
|
+
return [currentRange] as DataRange[];
|
|
174
|
+
}
|
|
175
|
+
const rangeAfterFrom = rangeAfter[START];
|
|
176
|
+
const rangeBeforeTo = rangeBefore[END];
|
|
177
|
+
// Ranges are collapsed
|
|
178
|
+
if (rangeBeforeTo === rangeAfterFrom) return [];
|
|
179
|
+
// Both are not null and don't intercept
|
|
180
|
+
if (
|
|
181
|
+
!this.isInterceptingDataRanges(rangeAfter, currentRange)
|
|
182
|
+
&& !this.isInterceptingDataRanges(rangeBefore, currentRange)
|
|
183
|
+
) {
|
|
184
|
+
return [currentRange];
|
|
185
|
+
}
|
|
186
|
+
// Left intercepts
|
|
187
|
+
if (this.isInterceptingDataRanges(rangeBefore, currentRange)) {
|
|
188
|
+
return [rangeBefore, ...this.generateDataRangesForward(rangeBeforeTo, end, cellSize)];
|
|
189
|
+
}
|
|
190
|
+
// Right intercepts
|
|
191
|
+
if (this.isInterceptingDataRanges(rangeAfter, currentRange)) {
|
|
192
|
+
return [
|
|
193
|
+
...this.generateDataRangesBackward(rangeAfterFrom, start, cellSize),
|
|
194
|
+
rangeAfter,
|
|
195
|
+
];
|
|
128
196
|
}
|
|
129
|
-
|
|
130
|
-
return ranges;
|
|
197
|
+
return [currentRange] as DataRange[];
|
|
131
198
|
}
|
|
132
199
|
|
|
133
200
|
private getMissingRanges(range: DataRange) {
|
|
@@ -211,7 +278,7 @@ export class DataManager implements IDataManager {
|
|
|
211
278
|
try {
|
|
212
279
|
fetchedData = await this.fetchPrograms(this.channel, start, end);
|
|
213
280
|
} catch (e) {
|
|
214
|
-
|
|
281
|
+
fetchedData = [];
|
|
215
282
|
}
|
|
216
283
|
this.fillInSpaces([start, end], fetchedData);
|
|
217
284
|
if (fetchedData.length === 0) return null;
|
|
@@ -290,11 +357,15 @@ export class DataManager implements IDataManager {
|
|
|
290
357
|
for (let i = data.length - 1; i > 0; i--) {
|
|
291
358
|
const current = data[i];
|
|
292
359
|
const previous = data[i - 1];
|
|
293
|
-
|
|
294
|
-
|
|
360
|
+
const breakLength = current.program!.startTime - previous.program!.endTime;
|
|
361
|
+
if (breakLength > 0 && breakLength >= MINIMUM_BREAK_LENGTH) {
|
|
362
|
+
data.splice(
|
|
363
|
+
i,
|
|
364
|
+
0,
|
|
295
365
|
this.generateNoDataProgram(
|
|
296
366
|
previous.program!.endTime, current.program!.startTime,
|
|
297
|
-
)
|
|
367
|
+
),
|
|
368
|
+
);
|
|
298
369
|
}
|
|
299
370
|
}
|
|
300
371
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Component, createRef, DeclareProps } from '@24i/bigscreen-sdk/jsx';
|
|
2
|
+
import { time } from '@24i/bigscreen-sdk/time';
|
|
2
3
|
import { Picker } from '@24i/bigscreen-sdk/picker';
|
|
3
4
|
import { DatePicker as NativeDatePicker } from '@24i/bigscreen-sdk/picker/DatePicker';
|
|
4
5
|
import { DAY_IN_MS, HOUR_IN_MS, MINUTE_IN_MS, SECOND_IN_MS } from '@24i/bigscreen-sdk/utils';
|
|
@@ -44,9 +45,14 @@ const prepareDateData = ({
|
|
|
44
45
|
return { selectedValue, from, to, overrides };
|
|
45
46
|
};
|
|
46
47
|
|
|
47
|
-
const defaultFormat = (date: Date) =>
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
const defaultFormat = (date: Date) => {
|
|
49
|
+
const locale = i18n.getLanguage();
|
|
50
|
+
return l10n
|
|
51
|
+
.date(date.getTime() + time.getTimezoneOffsetMs(), locale)
|
|
52
|
+
.toLocaleDateString({
|
|
53
|
+
weekday: 'short', day: 'numeric', month: 'short', formatType: 'dateFormatShort',
|
|
54
|
+
});
|
|
55
|
+
};
|
|
50
56
|
|
|
51
57
|
export class DatePicker extends Component<Props> implements IDatePicker {
|
|
52
58
|
datePicker = createRef<Picker<number>>();
|
|
@@ -6,28 +6,31 @@ import { time } from '@24i/bigscreen-sdk/time';
|
|
|
6
6
|
import { HOUR_IN_MS } from '@24i/bigscreen-sdk/utils/timeConstants';
|
|
7
7
|
import { InternalEpg, Plugin } from '../interface';
|
|
8
8
|
|
|
9
|
-
const formatTime = (
|
|
10
|
-
{ hour: 'numeric', minute: '2-digit' },
|
|
9
|
+
const formatTime = (localTimestamp: number) => l10n.date(localTimestamp).toLocaleTimeString(
|
|
10
|
+
{ hour: 'numeric', minute: '2-digit', formatType: 'timeFormat' },
|
|
11
11
|
);
|
|
12
12
|
|
|
13
|
-
const formatDate = (
|
|
14
|
-
if (time.isToday(
|
|
13
|
+
const formatDate = (localTimestamp: number) => {
|
|
14
|
+
if (time.isToday(localTimestamp)) {
|
|
15
15
|
return i18n.t('date.today');
|
|
16
16
|
}
|
|
17
|
-
if (time.isYesterday(
|
|
17
|
+
if (time.isYesterday(localTimestamp)) {
|
|
18
18
|
return i18n.t('date.yesterday');
|
|
19
19
|
}
|
|
20
|
-
if (time.isTomorrow(
|
|
20
|
+
if (time.isTomorrow(localTimestamp)) {
|
|
21
21
|
return i18n.t('date.tomorrow');
|
|
22
22
|
}
|
|
23
|
-
return l10n.date(
|
|
23
|
+
return l10n.date(localTimestamp).toLocaleString({
|
|
24
24
|
weekday: 'short',
|
|
25
25
|
day: 'numeric',
|
|
26
26
|
month: 'short',
|
|
27
|
+
formatType: 'dateFormatShort',
|
|
27
28
|
});
|
|
28
29
|
};
|
|
29
30
|
|
|
30
|
-
const formatDatetime = (
|
|
31
|
+
const formatDatetime = (localTimestamp: number) => (
|
|
32
|
+
`${formatDate(localTimestamp)} • ${formatTime(localTimestamp)}`
|
|
33
|
+
);
|
|
31
34
|
|
|
32
35
|
type Props = {
|
|
33
36
|
epg: InternalEpg<any, any, any, any>,
|
|
@@ -44,7 +47,7 @@ export class DateToast extends Component<Props> implements Plugin {
|
|
|
44
47
|
|
|
45
48
|
onScrolledToTimestamp(timestamp: number) {
|
|
46
49
|
const { epg } = this.props;
|
|
47
|
-
const day = formatDatetime(timestamp);
|
|
50
|
+
const day = formatDatetime(timestamp + time.getTimezoneOffsetMs());
|
|
48
51
|
if (this.lastDay === null) { // we do not want to display it after render and first move
|
|
49
52
|
this.lastDay = day;
|
|
50
53
|
return;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Component, createRef, setText } from '@24i/bigscreen-sdk/jsx';
|
|
2
|
+
import { time } from '@24i/bigscreen-sdk/time';
|
|
2
3
|
import { l10n } from '@24i/bigscreen-sdk/l10n';
|
|
3
4
|
import { DayProps as Props, Day as IDay } from './interface';
|
|
4
5
|
|
|
@@ -15,9 +16,11 @@ export class Day extends Component<Props> implements IDay {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
private formatCurrentTimestamp() {
|
|
18
|
-
return l10n
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
return l10n
|
|
20
|
+
.date(this.timestamp + time.getTimezoneOffsetMs())
|
|
21
|
+
.toLocaleDateString({
|
|
22
|
+
weekday: 'long', day: 'numeric', month: 'short', formatType: 'dateFormatShort',
|
|
23
|
+
});
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
render() {
|
|
@@ -83,6 +83,7 @@ export class Epg<
|
|
|
83
83
|
timeProvider: Date.now,
|
|
84
84
|
scrollStepMs: HALF_HOUR_IN_MS,
|
|
85
85
|
timelineSectionWidthMs: HALF_HOUR_IN_MS,
|
|
86
|
+
smallestAllowedCellPx: 0,
|
|
86
87
|
limitFromMs: -Infinity,
|
|
87
88
|
limitToMs: Infinity,
|
|
88
89
|
initialChannelIndex: 0,
|
|
@@ -297,6 +298,8 @@ export class Epg<
|
|
|
297
298
|
return ref;
|
|
298
299
|
}
|
|
299
300
|
|
|
301
|
+
isFocusInRows = () => this.focused === 'epg';
|
|
302
|
+
|
|
300
303
|
focus(options?: FocusOptions) {
|
|
301
304
|
if (this.focused === 'datepicker') {
|
|
302
305
|
this.datePickerComponent.current!.focus(options);
|
|
@@ -376,15 +379,11 @@ export class Epg<
|
|
|
376
379
|
return this.inputEvents.isVerticallyFastScrolling();
|
|
377
380
|
}
|
|
378
381
|
|
|
379
|
-
isFocusInRows = () => {
|
|
380
|
-
return this.focused === 'epg';
|
|
381
|
-
};
|
|
382
|
-
|
|
383
382
|
render() {
|
|
384
383
|
const {
|
|
385
384
|
datePickerProps, timelineWidthPx, channelHeaderWidthPx, scrollStepMs, rowHeightPx,
|
|
386
385
|
timelineSectionWidthMs, timelineWidthMs, initialChannelIndex, plugins,
|
|
387
|
-
navigatableRows, additionalRows, programTextModeResolver,
|
|
386
|
+
navigatableRows, additionalRows, programTextModeResolver, smallestAllowedCellPx,
|
|
388
387
|
renderDay, renderTime, renderProgram, renderChannelHeader, renderNowLineHeader,
|
|
389
388
|
} = this.props;
|
|
390
389
|
return (
|
|
@@ -444,6 +443,7 @@ export class Epg<
|
|
|
444
443
|
renderChannelHeader={renderChannelHeader}
|
|
445
444
|
renderProgram={renderProgram}
|
|
446
445
|
isFocusInRows={this.isFocusInRows}
|
|
446
|
+
smallestAllowedCellPx={smallestAllowedCellPx}
|
|
447
447
|
/>
|
|
448
448
|
<EpgMouseNavigation
|
|
449
449
|
// @ts-ignore - needed to convert fallback (false) to interface
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HOUR_IN_MS } from '@24i/bigscreen-sdk/utils/timeConstants';
|
|
2
2
|
import {
|
|
3
|
-
Asset, ID, UIElement, UIElementType,
|
|
3
|
+
Asset, AssetType, ID, UIElement, UIElementType,
|
|
4
4
|
} from '@24i/smartapps-datalayer/models';
|
|
5
5
|
import {
|
|
6
6
|
randomFromRange, getRandomItemFromArray, shuffleArray, getProgramImageUrl,
|
|
@@ -56,9 +56,10 @@ const generateChannels = (count: number): Asset[] => {
|
|
|
56
56
|
uiElements: [
|
|
57
57
|
{
|
|
58
58
|
type: UIElementType.IMAGE,
|
|
59
|
-
url: getChannelImageUrl(),
|
|
59
|
+
url: getChannelImageUrl() ?? '',
|
|
60
60
|
} as UIElement,
|
|
61
61
|
],
|
|
62
|
+
type: AssetType.CHANNEL,
|
|
62
63
|
});
|
|
63
64
|
}
|
|
64
65
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { l10n } from '@24i/bigscreen-sdk/l10n';
|
|
2
|
+
import { time } from '@24i/bigscreen-sdk/time';
|
|
2
3
|
import { Asset } from '@24i/smartapps-datalayer/models';
|
|
3
4
|
|
|
4
5
|
export const cutString = (string: string, length: number) => {
|
|
@@ -16,9 +17,9 @@ export const getSubtitle = (asset: Asset) => (
|
|
|
16
17
|
: ''
|
|
17
18
|
);
|
|
18
19
|
|
|
19
|
-
const toLocaleTimeString = (timestamp: number) => l10n
|
|
20
|
-
|
|
21
|
-
);
|
|
20
|
+
const toLocaleTimeString = (timestamp: number) => l10n
|
|
21
|
+
.date(timestamp + time.getTimezoneOffsetMs())
|
|
22
|
+
.toLocaleTimeString({ hour: 'numeric', minute: '2-digit', formatType: 'timeFormat' });
|
|
22
23
|
|
|
23
24
|
export const getBroadcastTime = (asset: Asset) => {
|
|
24
25
|
const start = toLocaleTimeString(asset.program!.startTime);
|
|
@@ -109,7 +109,8 @@ export class Row<
|
|
|
109
109
|
|
|
110
110
|
render() {
|
|
111
111
|
const {
|
|
112
|
-
timelineWidthMs,
|
|
112
|
+
timelineWidthMs, timestamp, time,
|
|
113
|
+
pixelInMs, timelineWidthPx, smallestAllowedCellPx,
|
|
113
114
|
programTextModeResolver, onMouseEnter, renderProgram,
|
|
114
115
|
} = this.props;
|
|
115
116
|
return (
|
|
@@ -126,6 +127,7 @@ export class Row<
|
|
|
126
127
|
onItemPress={this.onItemPress}
|
|
127
128
|
onMouseEnter={onMouseEnter}
|
|
128
129
|
renderProgram={renderProgram}
|
|
130
|
+
smallestAllowedCellPx={smallestAllowedCellPx}
|
|
129
131
|
/>
|
|
130
132
|
);
|
|
131
133
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Component, createRef, setText } from '@24i/bigscreen-sdk/jsx';
|
|
2
|
+
import { time } from '@24i/bigscreen-sdk/time';
|
|
2
3
|
import { l10n } from '@24i/bigscreen-sdk/l10n';
|
|
3
4
|
import { offsetPosition } from '@24i/bigscreen-sdk/utils';
|
|
4
5
|
import { TimelineSectionProps as Props, TimelineSection as ITimelineSection } from './interface';
|
|
@@ -23,7 +24,9 @@ export class TimelineSection extends Component<Props> implements ITimelineSectio
|
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
private formatCurrentTimestamp() {
|
|
26
|
-
return l10n
|
|
27
|
+
return l10n
|
|
28
|
+
.date(this.timestamp + time.getTimezoneOffsetMs())
|
|
29
|
+
.toLocaleTimeString({ hour: 'numeric', minute: '2-digit', formatType: 'timeFormat' });
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
render() {
|
|
@@ -180,7 +180,8 @@ export class CellsManager<
|
|
|
180
180
|
|
|
181
181
|
private addCell(item: Asset) {
|
|
182
182
|
const {
|
|
183
|
-
time,
|
|
183
|
+
time, smallestAllowedCellPx,
|
|
184
|
+
programTextModeResolver, onMouseEnter, onItemPress, onFocusChange, renderProgram,
|
|
184
185
|
} = this.props;
|
|
185
186
|
const cell = createRef<ICell<T>>();
|
|
186
187
|
this.mountBefore((
|
|
@@ -195,6 +196,7 @@ export class CellsManager<
|
|
|
195
196
|
onFocusChange={onFocusChange}
|
|
196
197
|
onMouseEnter={onMouseEnter}
|
|
197
198
|
renderProgram={renderProgram}
|
|
199
|
+
smallestAllowedCellPx={smallestAllowedCellPx}
|
|
198
200
|
/>
|
|
199
201
|
), this.endLoadingCell.current!.div);
|
|
200
202
|
this.cells.push(cell);
|
|
@@ -241,7 +243,7 @@ export class CellsManager<
|
|
|
241
243
|
|
|
242
244
|
render() {
|
|
243
245
|
const {
|
|
244
|
-
timelineWidthPx, time, dataGetter, programTextModeResolver,
|
|
246
|
+
timelineWidthPx, smallestAllowedCellPx, time, dataGetter, programTextModeResolver,
|
|
245
247
|
onMouseEnter, onItemPress, onFocusChange, renderProgram,
|
|
246
248
|
} = this.props;
|
|
247
249
|
const visibleData = dataGetter(this.getRange());
|
|
@@ -257,6 +259,7 @@ export class CellsManager<
|
|
|
257
259
|
onFocusChange={onFocusChange}
|
|
258
260
|
onMouseEnter={onMouseEnter}
|
|
259
261
|
renderProgram={renderProgram}
|
|
262
|
+
smallestAllowedCellPx={smallestAllowedCellPx}
|
|
260
263
|
isLoading
|
|
261
264
|
/>
|
|
262
265
|
{map(visibleData, (item) => {
|
|
@@ -274,6 +277,7 @@ export class CellsManager<
|
|
|
274
277
|
onFocusChange={onFocusChange}
|
|
275
278
|
onMouseEnter={onMouseEnter}
|
|
276
279
|
renderProgram={renderProgram}
|
|
280
|
+
smallestAllowedCellPx={smallestAllowedCellPx}
|
|
277
281
|
/>
|
|
278
282
|
);
|
|
279
283
|
})}
|
|
@@ -288,6 +292,7 @@ export class CellsManager<
|
|
|
288
292
|
onMouseEnter={onMouseEnter}
|
|
289
293
|
renderProgram={renderProgram}
|
|
290
294
|
isLoading
|
|
295
|
+
smallestAllowedCellPx={smallestAllowedCellPx}
|
|
291
296
|
/>
|
|
292
297
|
</div>
|
|
293
298
|
);
|
|
@@ -465,7 +465,8 @@ export class RowsManager<
|
|
|
465
465
|
|
|
466
466
|
render() {
|
|
467
467
|
const {
|
|
468
|
-
timelineWidthMs,
|
|
468
|
+
timelineWidthMs, timestamp, time, scrollStepMs,
|
|
469
|
+
pixelInMs, timelineWidthPx, smallestAllowedCellPx,
|
|
469
470
|
programTextModeResolver, onItemPress, onMouseEnter, renderProgram, renderChannelHeader,
|
|
470
471
|
} = this.props;
|
|
471
472
|
const visibleData = this.getVisibleChannels();
|
|
@@ -492,6 +493,7 @@ export class RowsManager<
|
|
|
492
493
|
onFocusChange={this.onFocusChange}
|
|
493
494
|
onMouseEnter={onMouseEnter}
|
|
494
495
|
renderProgram={renderProgram}
|
|
496
|
+
smallestAllowedCellPx={smallestAllowedCellPx}
|
|
495
497
|
/>
|
|
496
498
|
))}
|
|
497
499
|
</Scroller>
|
|
@@ -241,6 +241,14 @@ type ScrollStepMsProp = {
|
|
|
241
241
|
scrollStepMs: number,
|
|
242
242
|
};
|
|
243
243
|
|
|
244
|
+
type SmallestAllowedCellPxProp = {
|
|
245
|
+
/**
|
|
246
|
+
* If the width of the cell is smaller than this the cell will have a special
|
|
247
|
+
* class `too-small`. Value in pixels.
|
|
248
|
+
*/
|
|
249
|
+
smallestAllowedCellPx: number,
|
|
250
|
+
};
|
|
251
|
+
|
|
244
252
|
type IdleTimerMsProp = {
|
|
245
253
|
/**
|
|
246
254
|
* The number of milliseconds of inactivity (no input) after which EPG starts jumps
|
|
@@ -823,6 +831,7 @@ export type RowsManagerProps<
|
|
|
823
831
|
& RenderChannelHeaderProp<T>
|
|
824
832
|
& RenderProgramProp<U>
|
|
825
833
|
& IsFocusInRowsProp
|
|
834
|
+
& SmallestAllowedCellPxProp
|
|
826
835
|
);
|
|
827
836
|
|
|
828
837
|
/**
|
|
@@ -933,6 +942,7 @@ export type RowProps<
|
|
|
933
942
|
& TimestampProp
|
|
934
943
|
& TimeProp
|
|
935
944
|
& ScrollStepMsProp
|
|
945
|
+
& SmallestAllowedCellPxProp
|
|
936
946
|
& ProgramTextModeResolverProp
|
|
937
947
|
& OnItemPressProp<T>
|
|
938
948
|
& OnMouseEnterProp
|
|
@@ -1046,6 +1056,7 @@ export type CellsManagerProps<
|
|
|
1046
1056
|
& ProgramTextModeResolverProp
|
|
1047
1057
|
& OnMouseEnterProp
|
|
1048
1058
|
& RenderProgramProp<T>
|
|
1059
|
+
& SmallestAllowedCellPxProp
|
|
1049
1060
|
);
|
|
1050
1061
|
|
|
1051
1062
|
/**
|
|
@@ -1133,6 +1144,7 @@ export type CellProps<
|
|
|
1133
1144
|
& ProgramTextModeResolverProp
|
|
1134
1145
|
& OnMouseEnterProp
|
|
1135
1146
|
& RenderProgramProp<T>
|
|
1147
|
+
& SmallestAllowedCellPxProp
|
|
1136
1148
|
);
|
|
1137
1149
|
|
|
1138
1150
|
/**
|
|
@@ -1275,6 +1287,7 @@ export type Props<
|
|
|
1275
1287
|
& Partial<InitialTimestampProp>
|
|
1276
1288
|
& Partial<InitialChannelIndexProp>
|
|
1277
1289
|
& Partial<ProgramTextModeResolverProp>
|
|
1290
|
+
& Partial<SmallestAllowedCellPxProp>
|
|
1278
1291
|
& OnItemPressProp<U>
|
|
1279
1292
|
& Partial<OnFocusChangeProp<U>>
|
|
1280
1293
|
& Partial<OnScrolledToTimestampProp>
|
|
@@ -1,56 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
type PayloadOf<T> = T extends (payload: infer Payload) => any ? Payload : never;
|
|
4
|
-
|
|
5
|
-
export type EventMapType = { [key: string]: (payload: any) => void };
|
|
6
|
-
|
|
7
|
-
export interface IEvents<EventMap extends EventMapType> {
|
|
8
|
-
addEventListener: <K extends keyof EventMap>(
|
|
9
|
-
eventName: K,
|
|
10
|
-
listener: EventMap[K],
|
|
11
|
-
) => void,
|
|
12
|
-
removeEventListener: <K extends keyof EventMap>(
|
|
13
|
-
eventName: K,
|
|
14
|
-
listener: EventMap[K],
|
|
15
|
-
) => void,
|
|
16
|
-
triggerEvent: <K extends keyof EventMap>(
|
|
17
|
-
eventName: K,
|
|
18
|
-
payload: PayloadOf<EventMap[K]>,
|
|
19
|
-
) => void,
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export class EventsManager<EventMap extends EventMapType> implements IEvents<EventMap> {
|
|
23
|
-
eventListeners: Partial<{
|
|
24
|
-
[key in keyof EventMap]: EventMap[key][]
|
|
25
|
-
}> = {};
|
|
26
|
-
|
|
27
|
-
addEventListener = <K extends keyof EventMap>(
|
|
28
|
-
eventName: K,
|
|
29
|
-
listener: EventMap[K],
|
|
30
|
-
): void => {
|
|
31
|
-
if (!this.eventListeners[eventName]) this.eventListeners[eventName] = [];
|
|
32
|
-
const listeners = this.eventListeners[eventName] as EventMap[K][];
|
|
33
|
-
listeners.push(listener);
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
removeEventListener = <K extends keyof EventMap>(
|
|
37
|
-
eventName: K,
|
|
38
|
-
listener: EventMap[K],
|
|
39
|
-
): void => {
|
|
40
|
-
const listeners = this.eventListeners[eventName] as EventMap[K][] | undefined;
|
|
41
|
-
if (!listeners) return;
|
|
42
|
-
const index = listeners.indexOf(listener);
|
|
43
|
-
if (index !== -1) listeners.splice(index, 1);
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
triggerEvent = <K extends keyof EventMap>(
|
|
47
|
-
eventName: K,
|
|
48
|
-
payload?: PayloadOf<EventMap[K]>,
|
|
49
|
-
): void => {
|
|
50
|
-
const eventListeners = this.eventListeners[eventName] as EventMap[K][] | undefined;
|
|
51
|
-
if (!eventListeners) return;
|
|
52
|
-
// In case listener removes itself during listening we need loop on a copy
|
|
53
|
-
const listeners = map(eventListeners, (l) => l);
|
|
54
|
-
forEach(listeners, (listener) => listener(payload));
|
|
55
|
-
};
|
|
56
|
-
}
|
|
1
|
+
export * from '@24i/appstage-shared-events-manager/dist/EventsManager';
|
package/packages/focus/README.md
CHANGED
|
@@ -14,11 +14,13 @@ IFocusable is an interface that should be implemented by anything that can be fo
|
|
|
14
14
|
interface IFocusable {
|
|
15
15
|
focus(options?: FocusOptions): void,
|
|
16
16
|
hasDom?(element: HTMLElement): boolean,
|
|
17
|
+
hasFocus?(): boolean,
|
|
17
18
|
}
|
|
18
19
|
```
|
|
19
20
|
- focus is the main function that is called when focusing component/element.
|
|
20
21
|
- hasDom is optional optimization for components to help Layout components locate the currently
|
|
21
22
|
focused child.
|
|
23
|
+
- hasFocus is optional check if the component has focus inside or is itself focused.
|
|
22
24
|
|
|
23
25
|
## Layout components
|
|
24
26
|
- Vertical: Use it to create focus between elements vertically (up/down)
|
|
@@ -40,6 +42,7 @@ to the focused element and its index. Ideal place to change other elements
|
|
|
40
42
|
- onBeforeFocusChange: Optional callback just before focus change. It receives a reference
|
|
41
43
|
to the focused element and its index. Ideal place for preparing for the change
|
|
42
44
|
(e.g. moving the container to fit new element in the screen)
|
|
45
|
+
- circular: makes focus circular, e.g. when pressing left at leftmost element focus will go to rightmost element
|
|
43
46
|
- dir: Optional forceful setting of the component direction. Defaults to `'auto'` which follows
|
|
44
47
|
the direction of the app.
|
|
45
48
|
`'ltr'` always forces left-to-right layout,
|
|
@@ -128,6 +131,16 @@ const matrix = [
|
|
|
128
131
|
];
|
|
129
132
|
```
|
|
130
133
|
|
|
134
|
+
## Prevent blur on long press
|
|
135
|
+
When the user holds a navigation key, he usually scrolls to the boundary of the layout
|
|
136
|
+
and then releases the key. This operation is very quick and most of the time he releases
|
|
137
|
+
the key too late, so the keydown event from the layout will propagate to another component
|
|
138
|
+
or another layout. In some cases, we don't want this behavior and for those situations and
|
|
139
|
+
to have better control above the layout navigation, there is a prop `preventBlurOnLongPress`.
|
|
140
|
+
When the user scrolls to the boundary of the layout while holding a navigation key,
|
|
141
|
+
he needs to release the key and press it again to propagate the event higher and focus
|
|
142
|
+
another component or layout.
|
|
143
|
+
|
|
131
144
|
## Limitations
|
|
132
145
|
For the div to properly receive keydown events it needs to have set `tabIndex`. If you do not set `tabIndex` then it won't receive keydown events and those will not propagate to the Vertical/Horizontal component.
|
|
133
146
|
|
|
@@ -302,6 +315,11 @@ Method to focus between multiple focusable components. The first existing (non-n
|
|
|
302
315
|
const focusFirstExisting = (...toFocus: Reference<IFocusable>[]) => () => void;
|
|
303
316
|
```
|
|
304
317
|
|
|
318
|
+
If you need to enable `preventScroll` in element focus options, wrap your reference with `preventScrollOnFocus` function like this:
|
|
319
|
+
```ts
|
|
320
|
+
focusFirstExisting(this.navigation, preventScrollOnFocus(this.div))
|
|
321
|
+
```
|
|
322
|
+
|
|
305
323
|
## refocusAfterHashChange
|
|
306
324
|
When the hash is changed, the browser automatically blurs the currently focused element and focuses body.
|
|
307
325
|
This can be problematic when the overlay component is active (development tools, modals). Focus is lost and
|
|
@@ -313,3 +331,18 @@ outside of the component and not focused.
|
|
|
313
331
|
```ts
|
|
314
332
|
const refocusAfterHashChange = (focusWrapperOrReference: HTMLElement | Reference<HTMLElement>) => void;
|
|
315
333
|
```
|
|
334
|
+
|
|
335
|
+
## hasFocus
|
|
336
|
+
Test if the element (or element in the reference) has the `activeElement` inside or optionally,
|
|
337
|
+
if the element itself is the `activeElement`.
|
|
338
|
+
|
|
339
|
+
```ts
|
|
340
|
+
const hasFocus = (elementOrReference: HTMLElement | Reference<HTMLElement>, includeElementItself = false) => boolean;
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## isFocused
|
|
344
|
+
Test if the element (or element in the reference) is the `activeElement`.
|
|
345
|
+
|
|
346
|
+
```ts
|
|
347
|
+
const isFocused = (elementOrReference: HTMLElement | Reference<HTMLElement>) => boolean;
|
|
348
|
+
```
|