@clickview/lite 0.103.0-rc.0 → 0.103.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/.vite/manifest.json +640 -640
  2. package/dist/bundles.json +1 -1
  3. package/dist/en.json +1 -1
  4. package/dist/scripts/{BXosUOUS.chunk.js → 14z5Gy8L.chunk.js} +2 -2
  5. package/dist/scripts/{BXosUOUS.chunk.js.map → 14z5Gy8L.chunk.js.map} +1 -1
  6. package/dist/scripts/{BqkK_0Jk2.chunk.js → B4AZn1xm2.chunk.js} +2 -2
  7. package/dist/scripts/{BqkK_0Jk2.chunk.js.map → B4AZn1xm2.chunk.js.map} +1 -1
  8. package/dist/scripts/{_wBbQ-0z2.chunk.js → BBndy2td2.chunk.js} +2 -2
  9. package/dist/scripts/{_wBbQ-0z2.chunk.js.map → BBndy2td2.chunk.js.map} +1 -1
  10. package/dist/scripts/{BhgNNQjX.chunk.js → BOQck-Qs.chunk.js} +2 -2
  11. package/dist/scripts/{BhgNNQjX.chunk.js.map → BOQck-Qs.chunk.js.map} +1 -1
  12. package/dist/scripts/{BCTM3KG42.chunk.js → BQNOt7_Q2.chunk.js} +2 -2
  13. package/dist/scripts/{BCTM3KG42.chunk.js.map → BQNOt7_Q2.chunk.js.map} +1 -1
  14. package/dist/scripts/{DBdkd4Ag2.chunk.js → BTXOoJko2.chunk.js} +3 -3
  15. package/dist/scripts/{DBdkd4Ag2.chunk.js.map → BTXOoJko2.chunk.js.map} +1 -1
  16. package/dist/scripts/{wmwWqIeA.chunk.js → BTr5dJhb.chunk.js} +2 -2
  17. package/dist/scripts/{wmwWqIeA.chunk.js.map → BTr5dJhb.chunk.js.map} +1 -1
  18. package/dist/scripts/{B-aaIChO2.chunk.js → BTugVIIN2.chunk.js} +2 -2
  19. package/dist/scripts/{B-aaIChO2.chunk.js.map → BTugVIIN2.chunk.js.map} +1 -1
  20. package/dist/scripts/{_eRiDJm1.chunk.js → Ba4uGz_V.chunk.js} +2 -2
  21. package/dist/scripts/{_eRiDJm1.chunk.js.map → Ba4uGz_V.chunk.js.map} +1 -1
  22. package/dist/scripts/{Bx6qaXLc.chunk.js → Bdbe2u0R.chunk.js} +2 -2
  23. package/dist/scripts/{Bx6qaXLc.chunk.js.map → Bdbe2u0R.chunk.js.map} +1 -1
  24. package/dist/scripts/{syYCrnUX.chunk.js → BgoVmaXQ.chunk.js} +2 -2
  25. package/dist/scripts/{syYCrnUX.chunk.js.map → BgoVmaXQ.chunk.js.map} +1 -1
  26. package/dist/scripts/{B5DWwtp0.chunk.js → BjA9XV5y.chunk.js} +2 -2
  27. package/dist/scripts/{B5DWwtp0.chunk.js.map → BjA9XV5y.chunk.js.map} +1 -1
  28. package/dist/scripts/{Dp8z_udC.chunk.js → BoT5D3IL.chunk.js} +2 -2
  29. package/dist/scripts/{Dp8z_udC.chunk.js.map → BoT5D3IL.chunk.js.map} +1 -1
  30. package/dist/scripts/{BYMMqtaN.chunk.js → BqdHoEFM.chunk.js} +2 -2
  31. package/dist/scripts/{BYMMqtaN.chunk.js.map → BqdHoEFM.chunk.js.map} +1 -1
  32. package/dist/scripts/{BIvmcqND2.chunk.js → CCUznsdX2.chunk.js} +2 -2
  33. package/dist/scripts/{BIvmcqND2.chunk.js.map → CCUznsdX2.chunk.js.map} +1 -1
  34. package/dist/scripts/{BsNCh4UD.chunk.js → CFqL2Hm5.chunk.js} +3 -3
  35. package/dist/scripts/{BsNCh4UD.chunk.js.map → CFqL2Hm5.chunk.js.map} +1 -1
  36. package/dist/scripts/{BE8Ze3Fa2.chunk.js → CHmbcl4Y2.chunk.js} +2 -2
  37. package/dist/scripts/{BE8Ze3Fa2.chunk.js.map → CHmbcl4Y2.chunk.js.map} +1 -1
  38. package/dist/scripts/{RuVwpX36.chunk.js → CWCtYUUU.chunk.js} +2 -2
  39. package/dist/scripts/{RuVwpX36.chunk.js.map → CWCtYUUU.chunk.js.map} +1 -1
  40. package/dist/scripts/{CO8EIpI8.chunk.js → CXUrMkZu.chunk.js} +2 -2
  41. package/dist/scripts/{CO8EIpI8.chunk.js.map → CXUrMkZu.chunk.js.map} +1 -1
  42. package/dist/scripts/{DLqG-wwP.chunk.js → CYrelpYt.chunk.js} +2 -2
  43. package/dist/scripts/{DLqG-wwP.chunk.js.map → CYrelpYt.chunk.js.map} +1 -1
  44. package/dist/scripts/{Drx3PvJj.chunk.js → Cc9f2ux0.chunk.js} +2 -2
  45. package/dist/scripts/{Drx3PvJj.chunk.js.map → Cc9f2ux0.chunk.js.map} +1 -1
  46. package/dist/scripts/Cj_F4Lv92.chunk.js +2 -0
  47. package/dist/scripts/{C8l37H7t2.chunk.js.map → Cj_F4Lv92.chunk.js.map} +1 -1
  48. package/dist/scripts/{B5M-3wpn.chunk.js → CjwT65ug.chunk.js} +2 -2
  49. package/dist/scripts/{B5M-3wpn.chunk.js.map → CjwT65ug.chunk.js.map} +1 -1
  50. package/dist/scripts/{Dd23z1_x2.chunk.js → CvSpUZcJ2.chunk.js} +2 -2
  51. package/dist/scripts/{Dd23z1_x2.chunk.js.map → CvSpUZcJ2.chunk.js.map} +1 -1
  52. package/dist/scripts/{QrUfkwZX.chunk.js → DFleEz5_.chunk.js} +2 -2
  53. package/dist/scripts/{QrUfkwZX.chunk.js.map → DFleEz5_.chunk.js.map} +1 -1
  54. package/dist/scripts/{ygwO7HPs2.chunk.js → DIaT_eGy2.chunk.js} +2 -2
  55. package/dist/scripts/{ygwO7HPs2.chunk.js.map → DIaT_eGy2.chunk.js.map} +1 -1
  56. package/dist/scripts/{DXRsxBJw.chunk.js → DTliAJ8L.chunk.js} +2 -2
  57. package/dist/scripts/{DXRsxBJw.chunk.js.map → DTliAJ8L.chunk.js.map} +1 -1
  58. package/dist/scripts/{CfVIZBcI2.chunk.js → DXkvlC_92.chunk.js} +2 -2
  59. package/dist/scripts/{CfVIZBcI2.chunk.js.map → DXkvlC_92.chunk.js.map} +1 -1
  60. package/dist/scripts/{DE5jvfAx2.chunk.js → D_t70KgV2.chunk.js} +2 -2
  61. package/dist/scripts/{DE5jvfAx2.chunk.js.map → D_t70KgV2.chunk.js.map} +1 -1
  62. package/dist/scripts/{Dc01PBv1.chunk.js → Dn2EPvQj.chunk.js} +2 -2
  63. package/dist/scripts/{Dc01PBv1.chunk.js.map → Dn2EPvQj.chunk.js.map} +1 -1
  64. package/dist/scripts/{C4CuJJXy2.chunk.js → Dvl1XgHV2.chunk.js} +2 -2
  65. package/dist/scripts/{C4CuJJXy2.chunk.js.map → Dvl1XgHV2.chunk.js.map} +1 -1
  66. package/dist/scripts/{YzhKditE.chunk.js → ESLgHTNq.chunk.js} +2 -2
  67. package/dist/scripts/{YzhKditE.chunk.js.map → ESLgHTNq.chunk.js.map} +1 -1
  68. package/dist/scripts/{DfSzsD3P.chunk.js → FysETOFv.chunk.js} +2 -2
  69. package/dist/scripts/{DfSzsD3P.chunk.js.map → FysETOFv.chunk.js.map} +1 -1
  70. package/dist/scripts/{OmYpHs7g.chunk.js → _Cm5O72d.chunk.js} +3 -3
  71. package/dist/scripts/{OmYpHs7g.chunk.js.map → _Cm5O72d.chunk.js.map} +1 -1
  72. package/dist/scripts/{app-BzCWmnrr.js → app-k0jrat-b.js} +4 -4
  73. package/dist/scripts/{app-BzCWmnrr.js.map → app-k0jrat-b.js.map} +1 -1
  74. package/dist/scripts/{C46080Xd.chunk.js → dxqgnrOi.chunk.js} +2 -2
  75. package/dist/scripts/{C46080Xd.chunk.js.map → dxqgnrOi.chunk.js.map} +1 -1
  76. package/package.json +1 -1
  77. package/dist/scripts/C8l37H7t2.chunk.js +0 -2
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":[],"ignoreList":[],"sources":["../../src/shared/hooks/useFetchPointsOfInterest.ts","../../src/shared/hooks/usePlayerIntegrations.ts","../../src/shared/constants/LiteConstants.ts","../../src/shared/components/play-page/PlayPageUtils.ts","../../src/shared/components/stream-limit-overlay/StreamLimitOverlay.tsx","../../src/shared/hooks/usePreventKeyboardScroll.ts","../../src/shared/hooks/useGetRelatedVideos.ts","../../src/shared/views/lite-player/LitePlayerViewHooks.tsx","../../src/shared/views/lite-player/LitePlayerView.tsx"],"sourcesContent":["import { Flight } from 'libs/common/flight';\n\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { VideoRequests } from 'libs/shared/flight-requests/VideoRequests';\nimport { useFetchAll } from 'libs/shared/hooks/UseFetchAll';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { EmptySelectAllPagesResult, SelectAllPagesResult, useSelectAllPages } from 'libs/shared/hooks/UseSelectAllPages';\nimport { CurrentUser, PointOfInterest } from 'libs/shared/interfaces';\n\nexport function useFetchPointsOfInterest(\n videoId?: string,\n forceFetch?: boolean\n): SelectAllPagesResult<PointOfInterest> {\n const fetch = Flight.useGetFetch();\n const { hasPermissions } = usePermissions();\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n\n const shouldFetch = (currentUser.data?.isAuthenticated || forceFetch) &&\n hasPermissions(PermissionName.ViewVideoPointsOfInterest);\n\n function getRequest(cursor?: string): Flight.Request {\n return VideoRequests.pointsOfInterest(videoId, cursor);\n }\n \n function fetchNext(cursor?: string): void {\n fetch(getRequest(cursor));\n }\n\n /**\n * This is a big strange, but since we can't conditionally use hooks, instead\n * we null out the videoId so the points of interest never fetch for students.\n */\n if (!shouldFetch)\n videoId = null;\n\n useFetchAll(!!videoId && getRequest, !!videoId && fetchNext);\n\n const result = useSelectAllPages<PointOfInterest>(!!videoId && ((cursor?: string) => getRequest(cursor).key));\n\n /**\n * Then we return a placeholder object that lets anything consuming this behave as if\n * the Points of interest have fetched and there are one.\n */\n if (!shouldFetch)\n return EmptySelectAllPagesResult;\n\n return result;\n}\n","import { LocationUtils } from 'libs/common/backbone/core';\nimport { StorageType } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { Core } from 'libs/common/core';\nimport { Flight } from 'libs/common/flight';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AnalyticsOptions, DevicesDescriptor, EntityType, EventVersion, LocationContext, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { IntegrationStatus } from 'libs/shared/enums/IntegrationStatus';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { PlayerIntegrationsRequests } from 'libs/shared/flight-requests/PlayerIntegrationsRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { HasPermissionsFunc, usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { Config, CurrentUser } from 'libs/shared/interfaces';\nimport { CtaContext, PlayerIntegrations } from 'libs/shared/interfaces';\nimport { AppleTvAccessToken, ViviAccessToken } from 'libs/shared/interfaces';\nimport { ArticleHelper } from 'libs/shared/utils/ArticleHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\ninterface PlayerIntegrationsHash {\n hasCompleted: boolean;\n data: PlayerIntegrations;\n}\n\nexport function usePlayerIntegrations(objectId: string): PlayerIntegrationsHash {\n const {\n hasEnabledViviPlayback,\n hasEnabledAppleTvPlayback,\n hasEnabledViviStudentCasting,\n isLoadingSettings\n } = useSettings(null);\n const { hasProduct, isLoadingProducts } = useProducts();\n const { hasPermissions, isLoaded: permissionsLoaded } = usePermissions();\n const { fetchViviAccessToken, fetchAppleTvAccessToken } = useAccessTokenFetchFunctions();\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const ctaOptions = useCtaOptions(hasPermissions);\n\n // Compute derived state\n const isAuthenticated = currentUser.data?.isAuthenticated ?? false;\n const isNotStudent = !hasPermissions(PermissionName.StudentExperience);\n const isNotGuest = !hasPermissions(PermissionName.GuestExperience);\n const hasPrimaryProduct = hasProduct(ProductId.Primary);\n const canUserCastToVivi = isAuthenticated\n && hasPrimaryProduct && (isNotStudent || hasEnabledViviStudentCasting) && isNotGuest;\n const canUserCastToAppleTv = isAuthenticated && hasPrimaryProduct && isNotStudent && isNotGuest;\n const shouldCheckViviStatus = canUserCastToVivi && hasEnabledViviPlayback;\n \n // Fetch the status of the Vivi integration if necessary\n const viviStatus = Flight.useBasicFetch<IntegrationStatus>(\n objectId &&\n shouldCheckViviStatus &&\n PlayerIntegrationsRequests.getViviIntegrationStatus()\n );\n const viviAccountConnected = viviStatus.data === IntegrationStatus.Connected;\n const viviStatusCheckCompleted = shouldCheckViviStatus ? viviStatus.hasCompleted : true;\n\n // Compute the final `hasCompleted` value\n const hasCompleted = isAuthenticated ? (\n currentUser.hasCompleted &&\n config.hasCompleted &&\n viviStatusCheckCompleted &&\n permissionsLoaded &&\n !isLoadingSettings &&\n !isLoadingProducts\n ) : true;\n \n return {\n hasCompleted,\n data: {\n ctaOptions,\n canUserCastToDevices: canUserCastToVivi || canUserCastToAppleTv,\n vivi: {\n accountConnected: viviAccountConnected,\n enabled: canUserCastToVivi && hasEnabledViviPlayback,\n apiUrl: config.data?.viviApiUrl ?? '',\n fetchAccessToken: fetchViviAccessToken\n },\n appleTv: {\n enabled: canUserCastToAppleTv && hasEnabledAppleTvPlayback,\n fetchAccessToken: fetchAppleTvAccessToken\n }\n }\n };\n}\n\nfunction useAccessTokenFetchFunctions() {\n const fetchAsync = Flight.useGetFetchAsync();\n const getResponse = Flight.useGetResponseFunc();\n\n const fetchViviAccessToken = async () => {\n const request = PlayerIntegrationsRequests.getViviAccessToken();\n const tokenResponse = getResponse<ViviAccessToken>(request.key);\n const { token } = tokenResponse.shouldFetch ?\n await fetchAsync<ViviAccessToken>(request) :\n tokenResponse.data;\n \n return token;\n };\n\n const fetchAppleTvAccessToken = () => {\n return fetchAsync<AppleTvAccessToken>(\n PlayerIntegrationsRequests.getAppleTvAccessToken()\n );\n };\n\n return {\n fetchViviAccessToken,\n fetchAppleTvAccessToken\n };\n}\n\nconst VIVI_LEARN_MORE_URL = 'https://clickv.ie/w/WVsx';\nconst APPLE_TV_LEARN_MORE_URL = 'https://clickv.ie/w/PVsx';\n\nfunction useCtaOptions(hasPermissions: HasPermissionsFunc) {\n const [ dismissedModel, setDismissedModel ] = useViewModel<{ dismissed: boolean }>(\n 'devices:cta:dismissed',\n { dismissed: false },\n { storage: StorageType.LocalStorage }\n );\n const isStudent = hasPermissions(PermissionName.StudentExperience);\n const canUserManageIntegrations = hasPermissions(PermissionName.ManageIntegrations);\n const analyticsOptions: Partial<AnalyticsOptions> = {\n entity: EntityType.DevicesCta,\n actionType: UserAction.Click,\n workflowPhase: WorkflowPhase.Complete,\n location: LocationContext.Player\n };\n\n const onDismiss = (context: CtaContext) => {\n AnalyticsHelper.logUserAction({\n canUserManageIntegrations,\n context\n }, {\n ...analyticsOptions,\n descriptor: DevicesDescriptor.Dismiss,\n eventVersion: EventVersion.V1\n });\n\n setDismissedModel({ dismissed: true });\n };\n\n const onInstall = (context: CtaContext) => {\n AnalyticsHelper.logUserAction({\n canUserManageIntegrations,\n context\n }, {\n ...analyticsOptions,\n descriptor: DevicesDescriptor.InstallIntegration,\n eventVersion: EventVersion.V1\n });\n\n Core.AppLinkHelper.trigger({\n application: AppChannels.SETTINGS,\n action: Actions.Settings.INTEGRATIONS\n });\n };\n\n const onLearnMore = (context: CtaContext) => {\n AnalyticsHelper.logUserAction({\n canUserManageIntegrations,\n context\n }, {\n ...analyticsOptions,\n descriptor: DevicesDescriptor.LearnMore,\n eventVersion: EventVersion.V1\n });\n\n if (context === 'vivi_and_apple_tv' || context === 'vivi')\n LocationUtils.PageLoad(VIVI_LEARN_MORE_URL, true);\n\n if (context === 'vivi_and_apple_tv' || context === 'apple_tv')\n LocationUtils.PageLoad(APPLE_TV_LEARN_MORE_URL, true);\n };\n\n const onContactSupport = (context: CtaContext) => {\n AnalyticsHelper.logUserAction({\n canUserManageIntegrations,\n context\n }, {\n ...analyticsOptions,\n descriptor: DevicesDescriptor.ContactSupport,\n eventVersion: EventVersion.V1\n });\n\n LocationUtils.PageLoad(ArticleHelper.getSupportRequestUrl(), true);\n };\n\n return {\n hasBeenDismissed: dismissedModel.dismissed || isStudent,\n canUserManageIntegrations,\n onDismiss,\n onInstall,\n onLearnMore,\n onContactSupport\n };\n}\n","// Misc constants\nexport const LiteConstants = {\n VIDEO_START_TIME_CUTOFF: 10, // If the video start time is in the last 10 seconds of the video duration, it's ignored\n PUBLIC_SEARCH_QUERY_DEBOUNCE: 400,\n AUTHENTICATED_SEARCH_QUERY_DEBOUNCE: 200\n};\n","import { Core } from 'libs/common/core';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { SettingsHash } from 'libs/shared/hooks/useSettings';\nimport { Category, Company, Library, Link, PartnerProfile, Person, Resource, Series, Tag, Video } from 'libs/shared/interfaces';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { LiteConstants } from 'shared/constants/LiteConstants';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { ContentPartnerAppLinkHelper } from 'shared/utils/ContentPartnerAppLinkHelper';\n\nimport { SeriesAppLinkHelper } from 'apps/series/SeriesAppLinkHelper';\n\nexport function getResources(\n video: Video,\n isLearner: boolean\n): Array<Resource | Link> {\n const resources = video.resources?.data ?? [];\n const links = video.links?.data ?? [];\n\n const filteredResources = resources.filter(r => {\n if (!isLearner)\n return true;\n\n return r.metadata?.resourceType === 'additional-materials' || r.metadata?.resourceType === 'student-activity';\n });\n\n return [ ...filteredResources, ...links ];\n}\n\nexport const getLibraryAppLink = (library: Library): Core.AppLink => {\n return {\n application: AppChannels.LIBRARIES,\n action: Actions.Libraries.LIBRARY,\n args: [ library.id.toString(), TextHelper.slugify(library.name) ]\n };\n};\n\nexport const getFolderAppLink = (library: Library, folder: Category): Core.AppLink => {\n return {\n application: AppChannels.LIBRARIES,\n action: Actions.Libraries.FOLDER,\n args: [ library.id.toString(), folder.id.toString(), TextHelper.slugify(folder.name) ]\n };\n};\n\ninterface GetAppLinksOptions {\n settings: SettingsHash;\n presentationSlug: string | null;\n}\n\nexport function getAppLinks(options: GetAppLinksOptions) {\n const { settings, presentationSlug } = options;\n\n const getTagAppLink = (tag: Tag) => {\n return {\n application: AppChannels.SEARCH,\n action: Actions.Search.HOME,\n params: { tagOrClassification: tag.name }\n };\n };\n\n const getSeriesAppLink = (series: Series, moviesAndTv: boolean): Core.AppLink => {\n return SeriesAppLinkHelper.getSeriesAppLink(series, moviesAndTv ? { mtv: true } : {}, presentationSlug);\n };\n\n const getResourceAppLink = (videoId: string, shareId: string, canViewResource: boolean) =>\n (resource: Resource | Link) => {\n /**\n * We check both the feature access value and the shareId. \n * Resources should always be available if we have a share id, and the backend should control\n * which specific resources are returned - Sha\n */\n if (!canViewResource && !shareId) {\n return {\n application: AppChannels.SIGN_UP,\n action: Actions.SignUp.SIGN_UP\n };\n }\n\n return {\n application: AppChannels.VIDEOS,\n action: Actions.Videos.PREVIEW_PDF,\n args: [resource.id],\n params: {\n videoId: videoId,\n shareId: shareId\n }\n };\n };\n\n const getPartnerProfileAppLink = (partnerProfile: PartnerProfile) => {\n return ContentPartnerAppLinkHelper.getPartnerDashboardAppLink(partnerProfile);\n };\n\n const getPartnerDashboardHubAppLink = (company: Company | Person) => {\n return ContentPartnerAppLinkHelper.getPartnerDashboardHubAppLink(company);\n };\n\n return {\n getTagAppLink,\n getSeriesAppLink,\n getResourceAppLink,\n getPartnerProfileAppLink: settings?.hasPartnerProfiles ? getPartnerProfileAppLink : null,\n getPartnerDashboardHubAppLink: settings?.hasPartnerProfiles ? getPartnerDashboardHubAppLink : null,\n getLibraryAppLink,\n getFolderAppLink\n };\n}\n\nexport function getStartTime(startTimeParam: string | number, video: Video): number {\n const startTime = Number(startTimeParam);\n\n if (!isNaN(startTime) && startTime >= 0)\n return startTime;\n\n const lastProgressPoint = VideoHelper.getVideoProgress(video);\n\n if (!lastProgressPoint)\n return 0;\n\n if (lastProgressPoint >= (video.duration / 1000 - LiteConstants.VIDEO_START_TIME_CUTOFF))\n return 0;\n\n return lastProgressPoint;\n}\n\nexport function getEndTime(endTimeParam: string | number): number | undefined {\n if (Number.isInteger(+endTimeParam))\n return +endTimeParam;\n\n return undefined;\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { EmbedPlaceHolderHelper } from 'apps/embed/utils/EmbedPlaceholderHelper';\n\nimport styles from './stream-limit-overlay.module.scss';\n\nconst namespace = 'shared.streamLimitOverlay';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface StreamLimitOverlayProps {\n posterUrl: string;\n embed: boolean;\n hasStudentExperience: boolean;\n canRedeemMoreReferrals: boolean;\n totalStreamsAvailable: number;\n}\n\nexport function StreamLimitOverlay(props: StreamLimitOverlayProps): JSX.Element {\n const ctaAction = props.canRedeemMoreReferrals ?\n Actions.SignUp.INVITE_COLLEAGUE :\n Actions.SignUp.UPGRADE;\n\n const ctaPhrase = props.canRedeemMoreReferrals ? 'inviteCta' : 'upgradeCta';\n const hideCta = props.embed || props.hasStudentExperience;\n\n let descriptionPhrase: string;\n\n if (hideCta)\n descriptionPhrase = 'basicDescription';\n else if (props.canRedeemMoreReferrals)\n descriptionPhrase = 'referralDescription';\n else\n descriptionPhrase = 'upgradeDescription';\n\n /**\n * Embeds render a server-side splash screen (#embed-placeholder) that covers\n * the React app until the player fires 'cv-playback-data-loaded'. Since the\n * overlay replaces the player, that event never fires — so we need to \n * remove it manually.\n */\n React.useEffect(() => {\n if (props.embed)\n EmbedPlaceHolderHelper.remove();\n }, [props.embed]);\n\n return (\n <div className={`position-relative bg-light overflow-hidden ${props.embed ? 'position-fixed top-0 start-0 end-0 bottom-0' : 'ratio ratio-16x9'}`}>\n {props.posterUrl && (\n <img className={`position-absolute top-0 start-0 w-100 h-100 object-fit-cover ${styles.poster}`} src={props.posterUrl} alt='' />\n )}\n <div className={`position-absolute top-0 start-0 w-100 h-100 ${styles.frost}`} />\n <div className='position-absolute top-0 start-0 w-100 h-100 d-flex flex-column align-items-center justify-content-center text-center p-4'>\n <img\n className={`${styles.image} d-none d-md-block mb-3`}\n src={ImageUrls.SignUp.INVITE_COLLEAGUE}\n alt={getPhrase('heading')}\n />\n <h2 className='h5 mb-2'><Text namespace={namespace} phrase='heading' options={{ smartCount: props.totalStreamsAvailable }} /></h2>\n <p className='text-dark mb-3'>{getPhrase(descriptionPhrase)}</p>\n {!hideCta && (\n <AppLink\n className='btn btn-dark'\n appLink={{ application: AppChannels.SIGN_UP, action: ctaAction }}\n >\n {getPhrase(ctaPhrase)}\n </AppLink>\n )}\n </div>\n </div>\n );\n}\n","import React from 'react';\n\nconst UP_ARROW = 38;\nconst DOWN_ARROW = 40;\n\n/**\n * When this hook is used on a page, it will prevent the page from being scrollable by using\n * the up/down arrow keys.\n * \n * This is helpful on pages with a video playing, as we want the up/down arrow keys to control the\n * player volume without scrolling.\n */\nexport const usePreventKeyboardScroll = () => {\n function preventDefaultForScrollKeys(e: KeyboardEvent): boolean {\n if (e.keyCode === UP_ARROW || e.keyCode === DOWN_ARROW) {\n e.preventDefault();\n return false;\n }\n }\n\n React.useEffect(() => {\n window.addEventListener('keydown', preventDefaultForScrollKeys, false);\n\n return () => {\n window.removeEventListener('keydown', preventDefaultForScrollKeys, false);\n };\n }, []);\n};\n","import { Flight } from 'libs/common/flight';\n\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { RelatedVideosContext } from 'libs/shared/enums/RelatedVideosContext';\nimport { VideoRequests } from 'libs/shared/flight-requests/VideoRequests';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { CurrentUser, VideoTypes } from 'libs/shared/interfaces';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { useVideoFeatureAccess } from './useVideoFeatureAccess';\n\n/**\n * Poor mans paging explination:\n * \n * This change was made while we were doing performance imrovements in Feb 2024.\n * Because the related videos endpoint does not have paging, we fetch 6 to display 5 videos\n * this will let us know if there is another page. When the user requests the next page\n * we just fetch 25 items.\n * \n * - sHa\n */\nconst RELATED_VIDEOS_FIRST_PAGE = 6;\nconst RELATED_VIDEOS_MAX = 25;\n\nexport interface RelatedVideosHash {\n videos: VideoTypes[];\n hasError: boolean;\n hasCompleted: boolean;\n isFetching: boolean;\n fetchNext: () => void;\n hasMore: boolean;\n}\n\ninterface RelatedVideoOptions {\n video: VideoTypes;\n currentUser: CurrentUser;\n context: RelatedVideosContext;\n contextId: string;\n moviesAndTv: boolean;\n}\n\nexport function useGetRelatedVideos(options: RelatedVideoOptions): RelatedVideosHash {\n const { video, currentUser, moviesAndTv, context, contextId } = options;\n\n const { canViewRelatedVideos } = useVideoFeatureAccess();\n\n const { hasProduct } = useProducts();\n\n const fetch = Flight.useGetFetch();\n\n function getRequest(limit: number): Flight.Request {\n if (!video || !currentUser?.isAuthenticated || !hasProduct(ProductId.Primary) || !canViewRelatedVideos)\n return null;\n\n /**\n * We are no longer fetching related videos unless we have a context\n */\n if (!context && !contextId)\n return null;\n\n return VideoRequests.relatedVideos({\n videoId: video.id,\n context,\n collectionId: contextId,\n moviesAndTv,\n limit\n });\n }\n\n function filterVideos(videos: VideoTypes[]): VideoTypes[] {\n if (!videos) // Might be undefined or null\n return videos;\n\n if (hasMore)\n videos = videos.slice(0, RELATED_VIDEOS_FIRST_PAGE - 1);\n\n return videos.filter(v => VideoHelper.getCanBeConsumed(v)?.canNavigate);\n }\n\n function fetchNext() {\n fetch(getRequest(RELATED_VIDEOS_MAX));\n }\n\n const response = Flight.useBasicFetch<VideoTypes[]>(getRequest(RELATED_VIDEOS_FIRST_PAGE));\n\n const hasMore = response.data?.length === RELATED_VIDEOS_FIRST_PAGE;\n\n return {\n videos: filterVideos(response.data),\n hasCompleted: response.hasCompleted,\n isFetching: response.isFetching,\n hasError: response.hasError,\n hasMore,\n fetchNext\n };\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { Flight } from 'libs/common/flight';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { ShareRequests } from 'libs/shared/apps/share/flight-requests/ShareRequests';\nimport { PlayerMode } from 'libs/shared/context/player-context/interfaces/PlayerMode';\nimport { PlayerReference } from 'libs/shared/context/player-context/interfaces/PlayerReference';\nimport { ImageSize } from 'libs/shared/enums/Images';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { MediaIdType } from 'libs/shared/enums/MediaIdType';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { RelatedVideosContext } from 'libs/shared/enums/RelatedVideosContext';\nimport { ShareActivityStatus } from 'libs/shared/enums/ShareActivityStatus';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { FavouriteRequests } from 'libs/shared/flight-requests/FavouriteRequests';\nimport { PlayerRequests } from 'libs/shared/flight-requests/PlayerRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useActivityStatus } from 'libs/shared/hooks/UseActivityStatus';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { Config, CurrentUser, PlayerViewKey, ShareLink, UnionShareObject, VideoTypes } from 'libs/shared/interfaces';\nimport { FavouriteHelper } from 'libs/shared/utils/FavouriteHelpers';\nimport { ImageHelper } from 'libs/shared/utils/ImageHelper';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { useFetchPointsOfInterest } from 'shared/hooks/useFetchPointsOfInterest';\nimport { useGetRelatedVideos } from 'shared/hooks/useGetRelatedVideos';\nimport { useLiteFavourites } from 'shared/hooks/useLiteFavourites';\nimport { usePlayerIntegrations } from 'shared/hooks/usePlayerIntegrations';\nimport { VideoAppLinkHelper } from 'shared/utils/VideoAppLinkHelper';\n\nconst THUMBNAIL_SIZE = ImageSize.Medium;\n\nfunction createViewKeyRequest(\n objectId: string,\n shareId: string,\n shareLink: ShareLink\n): Flight.Request {\n if (!shareId)\n return PlayerRequests.createViewKey(objectId, MediaIdType.MasterObject);\n\n if (!shareLink)\n return null;\n\n /**\n * If our share link matches our object id it's just a video share\n */\n if (shareLink.objectId === objectId)\n return PlayerRequests.createViewKey(shareId, MediaIdType.Share);\n\n /**\n * Otherwise we're attempting to watch a video inside of a shared video collection (e.g. A shared playlist)\n */\n return PlayerRequests.createViewKey(objectId, MediaIdType.MasterObject, shareId);\n}\n\ninterface UseGetPlayerDataOptions {\n objectId: string;\n objectTypeId: MasterType;\n shareId: string;\n context: RelatedVideosContext;\n contextId: string;\n moviesAndTv: boolean;\n}\n\nexport function useGetPlayerData(options: UseGetPlayerDataOptions) {\n const { objectId, objectTypeId, shareId, context, contextId, moviesAndTv } = options;\n\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const video = Flight.useBasicFetch<VideoTypes>(\n objectId && VideoHelper.getVideoRequest(objectId, objectTypeId, shareId)\n );\n const shareLink = Flight.useBasicFetch<ShareLink>(shareId && ShareRequests.getShareObject(shareId));\n const canHavePointsOfInterest = objectTypeId === MasterType.Video || objectTypeId === MasterType.Clip;\n const pointsOfInterest = useFetchPointsOfInterest(canHavePointsOfInterest && objectId);\n const viewKey = Flight.useBasicFetch<PlayerViewKey>(\n objectId && createViewKeyRequest(objectId, shareId, shareLink.data)\n );\n const relatedVideos = useGetRelatedVideos({\n video: video.data,\n context,\n contextId,\n moviesAndTv,\n currentUser: currentUser.data\n });\n const playerIntegrations = usePlayerIntegrations(objectId);\n \n /**\n * Mix in if our video is favourited\n */\n Flight.useBasicFetch(\n objectId &&\n currentUser.data?.isAuthenticated &&\n FavouriteRequests.isFavourited(currentUser.data.id, [objectId])\n );\n\n const hasCompleted = (\n video.data &&\n config.hasCompleted &&\n currentUser.hasCompleted &&\n (!shareId || shareLink.hasCompleted) &&\n (objectTypeId !== MasterType.Video || pointsOfInterest.hasCompleted) &&\n viewKey.hasCompleted &&\n playerIntegrations.hasCompleted\n );\n\n return {\n hasCompleted,\n config: config.data,\n currentUser: currentUser.data,\n video: video.data,\n shareLink: shareLink.data,\n pointsOfInterest: pointsOfInterest?.items,\n viewKey: viewKey.data,\n relatedVideos: relatedVideos.videos,\n playerIntegrations: playerIntegrations.data\n };\n}\n\nexport function useSetFavourite(player: PlayerReference, video: VideoTypes) {\n const { setFavourite, canFavourite } = useLiteFavourites(LocationContext.Player);\n const isFavourited = FavouriteHelper.isFavouritedByCurrentUser(video);\n const isArchived = VideoHelper.isVideoTypeArchived(video);\n\n React.useEffect(() => {\n if (!player || !video || !canFavourite(video) || isArchived)\n return;\n\n player.setFavourite?.(isFavourited, (setFav: boolean) => setFavourite(video, setFav));\n }, [ video, player, canFavourite, isArchived ]);\n}\n\nexport function useSetActivityStatus(\n player: PlayerReference,\n video: VideoTypes,\n shareLink: UnionShareObject\n) {\n // Disabling activity status for performance reasons (28/2/24) - Sha\n return;\n\n const setActivityStatus = useActivityStatus(LocationContext.FloatingPlayer);\n const { hasPermissions } = usePermissions();\n\n React.useEffect(() => {\n if (!player || !video || !shareLink)\n return;\n\n if (!hasPermissions(PermissionName.StudentExperience) || !('activityStatus' in shareLink))\n return;\n\n player.setActivityStatus?.(shareLink.activityStatus, () => {\n const newStatus = shareLink.activityStatus === ShareActivityStatus.Complete ?\n ShareActivityStatus.Incomplete :\n ShareActivityStatus.Complete;\n\n setActivityStatus(shareLink.id, video, newStatus);\n });\n }, [ player, video, shareLink ]);\n}\n\nexport function useCreateClip(\n playerRef: React.MutableRefObject<PlayerReference>,\n currentUser: CurrentUser,\n video: VideoTypes,\n embed: boolean,\n allowCreateClip: boolean\n) {\n const { hasProduct } = useProducts();\n const isArchived = VideoHelper.isVideoTypeArchived(video);\n\n const canCreateClip = (\n currentUser.isAuthenticated &&\n VideoHelper.isVideo(video) &&\n video._canCreateChild?.value &&\n hasProduct(ProductId.Primary) &&\n !embed &&\n allowCreateClip &&\n !isArchived\n ) ;\n\n if (!canCreateClip)\n return undefined;\n \n function onClickCreateClip(): void {\n if (!canCreateClip)\n return;\n\n Core.AppLinkHelper.trigger({\n application: AppChannels.CLIPS,\n action: Actions.Clips.CREATE_CLIP,\n args: [video.id],\n params: {\n startTime: playerRef.current?.currentTime?.() ?? undefined\n }\n });\n }\n\n return onClickCreateClip;\n}\n\nexport function usePip(\n currentUser: CurrentUser,\n onRequestPictureInPicture: (isPip: boolean) => void\n) {\n const { hasProduct } = useProducts();\n\n return (\n currentUser.isAuthenticated &&\n hasProduct(ProductId.Primary) &&\n onRequestPictureInPicture\n );\n}\n\ninterface UseSetNextVideoOptions {\n player: PlayerReference;\n relatedVideos: VideoTypes[];\n shareId: string;\n context: RelatedVideosContext;\n contextId: string;\n moviesAndTv: boolean;\n playNext: boolean;\n mode: PlayerMode;\n isAuthenticated: boolean;\n presentationSlug: string | null;\n}\n\nexport function useSetNextVideo(options: UseSetNextVideoOptions): void {\n const {\n player,\n relatedVideos,\n shareId,\n context,\n contextId,\n moviesAndTv,\n playNext,\n mode,\n isAuthenticated,\n presentationSlug\n } = options;\n\n const first = relatedVideos?.[0];\n\n React.useEffect(() => {\n if (!player?.setNextVideo || !first)\n return;\n\n /**\n * We only want to go to the next video if the user is on a play page.\n */\n if (mode !== 'default') {\n player.setNextVideo?.(null, false, null);\n return;\n }\n\n const rawThumbanilUrl = VideoHelper.getThumbnail(first)?.url;\n const nextVideo = {\n name: first.name,\n thumbnailUrl: ImageHelper.createUrl(rawThumbanilUrl, { size: THUMBNAIL_SIZE })\n };\n\n player.setNextVideo?.(nextVideo, playNext, () => {\n Core.AppLinkHelper.trigger(VideoAppLinkHelper.getAppLink(first, {\n shareId,\n context,\n contextId,\n playNext,\n moviesAndTv,\n includeContext: isAuthenticated\n }, presentationSlug));\n });\n }, [\n player,\n first,\n shareId,\n context,\n contextId,\n playNext,\n mode\n ]);\n}\n","import React from 'react';\nimport { HtmlPortalNode } from 'react-reverse-portal';\n\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { DefaultDisplayMode } from 'libs/shared/context/player-context/interfaces/PlayerContextAction';\nimport { PlayerMode } from 'libs/shared/context/player-context/interfaces/PlayerMode';\nimport { PlayerReference } from 'libs/shared/context/player-context/interfaces/PlayerReference';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { RelatedVideosContext } from 'libs/shared/enums/RelatedVideosContext';\nimport { useForceUpdate } from 'libs/shared/hooks/useForceUpdate';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { Config, CurrentUser, PlayerIntegrations, PlayerViewKey, PointOfInterest, UnionShareObject, VideoTypes } from 'libs/shared/interfaces';\nimport { AuthToken } from 'libs/shared/interfaces/models/AuthToken';\nimport { PlayerAnalyticsTracker } from 'libs/shared/utils/PlayerAnalyticsTracker';\nimport { ShareHelper } from 'libs/shared/utils/ShareHelper';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport type { PlayerOptions } from 'projects/player/players/player';\nimport type { ExternalLinkOptions } from 'projects/player/plugins/open-externally-plugin/interfaces/ExternalLinkOptions';\n\nimport { getEndTime, getStartTime } from 'shared/components/play-page/PlayPageUtils';\nimport { StreamLimitOverlay } from 'shared/components/stream-limit-overlay/StreamLimitOverlay';\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { usePreventKeyboardScroll } from 'shared/hooks/usePreventKeyboardScroll';\nimport { useStreamQuota } from 'shared/hooks/useStreamQuota';\nimport { VideoAppLinkHelper } from 'shared/utils/VideoAppLinkHelper';\nimport { useCreateClip, usePip, useSetActivityStatus, useSetFavourite, useSetNextVideo } from 'shared/views/lite-player/LitePlayerViewHooks';\n\nimport styles from './lite-player.module.scss';\n\nfunction shouldCollectResults(props: LitePlayerViewProps): boolean {\n if (!props.shareLink)\n return false;\n\n if (props.currentUser.isAuthenticated)\n return true;\n\n return !!props.collectAnonResults;\n}\n\nfunction getExternalLink(\n video: VideoTypes,\n shareLink: UnionShareObject,\n options: ExternalLinkOptions,\n isAuthenticated: boolean,\n presentationSlug: string | null\n): string {\n if (shareLink) {\n return Core.AppLinkHelper.getHref({\n application: AppChannels.SHARE,\n action: Actions.Share.VIEW_SHARE_LINK,\n args: [shareLink.id],\n params: {\n t: options.currentTime,\n a: true\n }\n });\n }\n\n const appLink = VideoAppLinkHelper.getAppLink(video, { includeContext: isAuthenticated }, presentationSlug);\n if (!appLink.params)\n appLink.params = {};\n\n (appLink.params as HashObject).t = options.currentTime;\n (appLink.params as HashObject).a = true;\n return Core.AppLinkHelper.getHref(appLink);\n}\n\nexport interface LitePlayerViewProps {\n // Core data\n config: Config;\n token?: AuthToken;\n video: VideoTypes;\n currentUser: CurrentUser;\n shareLink?: UnionShareObject;\n pointsOfInterest?: PointOfInterest[];\n viewKey: PlayerViewKey;\n relatedVideos?: VideoTypes[];\n presentationSlug: string | null;\n\n // Hook options\n context?: RelatedVideosContext;\n contextId?: string;\n moviesAndTv?: boolean;\n playNext?: boolean;\n mode?: PlayerMode;\n defaultDisplayMode?: DefaultDisplayMode;\n\n allowCreateClip?: boolean;\n allowTheatreMode?: boolean;\n allowTranscript?: boolean;\n\n // Passthrough options\n autoplay?: boolean;\n startTime?: string;\n endTime?: string;\n embed?: boolean;\n showResources?: boolean;\n muted?: boolean;\n\n // Interactive\n summaryPortalNode?: HtmlPortalNode;\n questionListPortalNode?: HtmlPortalNode;\n onShowSummary?: (showing: boolean) => void;\n collectAnonResults?: boolean;\n\n // Devices\n playerIntegrations?: PlayerIntegrations;\n\n onReady?: (player: PlayerReference) => void;\n onRequestPictureInPicture?: (isPip: boolean) => void;\n onRequestTheatreMode?: (isTheatreMode: boolean) => void;\n}\n\n/**\n * Consumers of this view need to opt out of these features.\n */\nLitePlayerView.defaultProps = {\n allowCreateClip: true\n};\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function LitePlayerView(props: LitePlayerViewProps): JSX.Element {\n const playerRef = React.useRef<PlayerReference>(null);\n const analyticsTracker = React.useRef<PlayerAnalyticsTracker>(null);\n\n useSetFavourite(playerRef.current, props.video);\n useSetActivityStatus(playerRef.current, props.video, props.shareLink);\n useSetNextVideo({\n player: playerRef.current,\n relatedVideos: props.relatedVideos,\n shareId: props.shareLink?.id,\n context: props.context,\n contextId: props.contextId,\n moviesAndTv: props.moviesAndTv,\n playNext: props.playNext,\n mode: props.mode,\n isAuthenticated: props.currentUser?.isAuthenticated,\n presentationSlug: props.presentationSlug\n });\n usePreventKeyboardScroll();\n \n const allowPip = usePip(props.currentUser, props.onRequestPictureInPicture);\n\n const { experimentalInteractiveQuestions } = useSettings(null);\n const {\n isLoaded: streamQuotaLoaded,\n hasReachedStreamLimit,\n canRedeemMoreReferrals,\n totalStreamsAvailable\n } = useStreamQuota();\n\n const { hasPermissions } = usePermissions();\n\n const isGuest = hasPermissions(PermissionName.GuestExperience);\n const hasStudentExperience = hasPermissions(PermissionName.StudentExperience);\n\n const onClickCreateClip = useCreateClip(\n playerRef,\n props.currentUser,\n props.video,\n props.embed,\n isGuest ? false : props.allowCreateClip\n );\n\n const forceUpdate = useForceUpdate();\n\n function onReady(player: PlayerReference): void {\n playerRef.current = player;\n forceUpdate();\n props.onReady && props.onReady(player);\n setupAnalytics(player);\n }\n\n function setupAnalytics(player: PlayerReference): void {\n analyticsTracker.current = new PlayerAnalyticsTracker({\n player,\n video: props.video,\n analyticsLocation: props.embed ?\n LocationContext.EmbeddedPlayer :\n LocationContext.PlayPage,\n shareId: props.shareLink?.id\n });\n }\n\n let posterUrl = '';\n if ('thumbnail' in props.video)\n posterUrl = props.video.thumbnail?.url;\n if (!posterUrl && '_parentVideo' in props.video)\n posterUrl = props.video._parentVideo?.thumbnail?.url;\n\n const commonProps: PlayerOptions = {\n // Fetched\n viewKey: props.viewKey.viewKey,\n playerApi: new URL(props.config.playerApiUrl),\n imageCdnUrl: props.config.imageCdnUrl,\n\n // Options\n autoplay: props.autoplay,\n startTime: getStartTime(props.startTime, props.video),\n endTime: getEndTime(props.endTime),\n embed: props.embed,\n showResources: props.showResources,\n getExternalLink: props.embed &&\n (options => getExternalLink(\n props.video,\n props.shareLink,\n options,\n props.currentUser?.isAuthenticated,\n props.presentationSlug\n )),\n muted: props.muted,\n splash: props.embed ? {\n title: props.video.name,\n posterUrl,\n ratingCode: VideoHelper.getRating(props.video)?.code,\n ratingValue: VideoHelper.getRating(props.video)?.value,\n seriesName: 'series' in props.video && props.video.series?.name,\n seasonNumber: 'season' in props.video && props.video.season?.number,\n episodeNumber: 'episodeNumber' in props.video && props.video.episodeNumber\n } : undefined,\n // todo remove this once we ship theatre mode for everyone\n allowTheatreMode: props.allowTheatreMode,\n allowLoop: true,\n\n // Static\n hotkeyElQuerySelector: 'body',\n sharerInstanceRegion: props.shareLink?.ownerInstanceRegion\n };\n\n const devicesConfig = props.playerIntegrations ? {\n ...props.playerIntegrations,\n trackingCode: VideoHelper.getTrackingCode(props.video)\n } : undefined;\n\n const isTheatreMode = props.mode === 'default' && props.defaultDisplayMode === 'theatre';\n const isHoverMode = props.mode === 'hover';\n const isInteractive = props.video.typeId === MasterType.Interactive;\n const isPublicShare = ShareHelper.isPublic(props.shareLink);\n const showStreamLimitOverlay = streamQuotaLoaded && hasReachedStreamLimit && !isHoverMode && !isPublicShare;\n\n /**\n * We memoize two React.lazy components (interactive and standard) to avoid Suspense flicker on re-renders.\n * Hooks can't be conditional, so both lazies are created once and we choose which to render at runtime.\n * With default exports, React.lazy infers props, so no casting is required. - Sha\n */\n const InteractivePlayer = React.useMemo(() => React.lazy(() => import('projects/player/react/InteractivePlayer')), []);\n const Player = React.useMemo(() => React.lazy(() => import('projects/player/react/Player')), []);\n \n if (showStreamLimitOverlay) {\n return (\n <StreamLimitOverlay\n posterUrl={posterUrl}\n embed={props.embed}\n hasStudentExperience={hasStudentExperience}\n canRedeemMoreReferrals={canRedeemMoreReferrals}\n totalStreamsAvailable={totalStreamsAvailable}\n />\n );\n }\n\n if (isInteractive) {\n return (\n <React.Suspense fallback={<div className={styles.placeholder} />}>\n <InteractivePlayer\n {...commonProps}\n imageApi={new URL(props.config.imageCdnUrl)}\n currentUser={props.currentUser}\n collectResults={shouldCollectResults(props)}\n shareId={props.shareLink?.id}\n enableImmersiveReader\n summaryPortalNode={props.summaryPortalNode}\n onShowSummary={props.onShowSummary}\n onReady={onReady}\n className={props.embed ? styles.embeddedPlayer : ''}\n furthestVisitedTime={props.video._videoProgress?.furthest}\n questionListPortalNode={props.questionListPortalNode}\n authToken={props.token?.value}\n experimentalInteractiveQuestions={experimentalInteractiveQuestions}\n />\n </React.Suspense>\n );\n }\n\n function getClassName(): string {\n if (props.embed) {\n return styles.embeddedPlayer;\n }\n if (isTheatreMode)\n return 'w-100 h-100';\n return '';\n }\n\n return (\n <React.Suspense fallback={<div className={`${styles.placeholder} ${isTheatreMode ? styles.theatreMode : ''}`} />}>\n <Player\n {...commonProps}\n devicesConfig={devicesConfig}\n className={getClassName()}\n onClickCreateClip={onClickCreateClip}\n pointsOfInterest={props.pointsOfInterest}\n onReady={onReady}\n showResources={props.embed}\n onRequestPictureInPicture={allowPip && props.onRequestPictureInPicture}\n onRequestTheatreMode={props.onRequestTheatreMode}\n theatreMode={isTheatreMode}\n nextDefaultDisplayMode={props.defaultDisplayMode}\n allowTranscript={props.allowTranscript}\n />\n </React.Suspense>\n );\n}\n"],"file":"OmYpHs7g.chunk.js"}
1
+ {"version":3,"mappings":"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","names":[],"ignoreList":[],"sources":["../../src/shared/hooks/useFetchPointsOfInterest.ts","../../src/shared/hooks/usePlayerIntegrations.ts","../../src/shared/constants/LiteConstants.ts","../../src/shared/components/play-page/PlayPageUtils.ts","../../src/shared/components/stream-limit-overlay/StreamLimitOverlay.tsx","../../src/shared/hooks/usePreventKeyboardScroll.ts","../../src/shared/hooks/useGetRelatedVideos.ts","../../src/shared/views/lite-player/LitePlayerViewHooks.tsx","../../src/shared/views/lite-player/LitePlayerView.tsx"],"sourcesContent":["import { Flight } from 'libs/common/flight';\n\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { VideoRequests } from 'libs/shared/flight-requests/VideoRequests';\nimport { useFetchAll } from 'libs/shared/hooks/UseFetchAll';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { EmptySelectAllPagesResult, SelectAllPagesResult, useSelectAllPages } from 'libs/shared/hooks/UseSelectAllPages';\nimport { CurrentUser, PointOfInterest } from 'libs/shared/interfaces';\n\nexport function useFetchPointsOfInterest(\n videoId?: string,\n forceFetch?: boolean\n): SelectAllPagesResult<PointOfInterest> {\n const fetch = Flight.useGetFetch();\n const { hasPermissions } = usePermissions();\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n\n const shouldFetch = (currentUser.data?.isAuthenticated || forceFetch) &&\n hasPermissions(PermissionName.ViewVideoPointsOfInterest);\n\n function getRequest(cursor?: string): Flight.Request {\n return VideoRequests.pointsOfInterest(videoId, cursor);\n }\n \n function fetchNext(cursor?: string): void {\n fetch(getRequest(cursor));\n }\n\n /**\n * This is a big strange, but since we can't conditionally use hooks, instead\n * we null out the videoId so the points of interest never fetch for students.\n */\n if (!shouldFetch)\n videoId = null;\n\n useFetchAll(!!videoId && getRequest, !!videoId && fetchNext);\n\n const result = useSelectAllPages<PointOfInterest>(!!videoId && ((cursor?: string) => getRequest(cursor).key));\n\n /**\n * Then we return a placeholder object that lets anything consuming this behave as if\n * the Points of interest have fetched and there are one.\n */\n if (!shouldFetch)\n return EmptySelectAllPagesResult;\n\n return result;\n}\n","import { LocationUtils } from 'libs/common/backbone/core';\nimport { StorageType } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { Core } from 'libs/common/core';\nimport { Flight } from 'libs/common/flight';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AnalyticsOptions, DevicesDescriptor, EntityType, EventVersion, LocationContext, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { IntegrationStatus } from 'libs/shared/enums/IntegrationStatus';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { PlayerIntegrationsRequests } from 'libs/shared/flight-requests/PlayerIntegrationsRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { HasPermissionsFunc, usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { Config, CurrentUser } from 'libs/shared/interfaces';\nimport { CtaContext, PlayerIntegrations } from 'libs/shared/interfaces';\nimport { AppleTvAccessToken, ViviAccessToken } from 'libs/shared/interfaces';\nimport { ArticleHelper } from 'libs/shared/utils/ArticleHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\ninterface PlayerIntegrationsHash {\n hasCompleted: boolean;\n data: PlayerIntegrations;\n}\n\nexport function usePlayerIntegrations(objectId: string): PlayerIntegrationsHash {\n const {\n hasEnabledViviPlayback,\n hasEnabledAppleTvPlayback,\n hasEnabledViviStudentCasting,\n isLoadingSettings\n } = useSettings(null);\n const { hasProduct, isLoadingProducts } = useProducts();\n const { hasPermissions, isLoaded: permissionsLoaded } = usePermissions();\n const { fetchViviAccessToken, fetchAppleTvAccessToken } = useAccessTokenFetchFunctions();\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const ctaOptions = useCtaOptions(hasPermissions);\n\n // Compute derived state\n const isAuthenticated = currentUser.data?.isAuthenticated ?? false;\n const isNotStudent = !hasPermissions(PermissionName.StudentExperience);\n const isNotGuest = !hasPermissions(PermissionName.GuestExperience);\n const hasPrimaryProduct = hasProduct(ProductId.Primary);\n const canUserCastToVivi = isAuthenticated\n && hasPrimaryProduct && (isNotStudent || hasEnabledViviStudentCasting) && isNotGuest;\n const canUserCastToAppleTv = isAuthenticated && hasPrimaryProduct && isNotStudent && isNotGuest;\n const shouldCheckViviStatus = canUserCastToVivi && hasEnabledViviPlayback;\n \n // Fetch the status of the Vivi integration if necessary\n const viviStatus = Flight.useBasicFetch<IntegrationStatus>(\n objectId &&\n shouldCheckViviStatus &&\n PlayerIntegrationsRequests.getViviIntegrationStatus()\n );\n const viviAccountConnected = viviStatus.data === IntegrationStatus.Connected;\n const viviStatusCheckCompleted = shouldCheckViviStatus ? viviStatus.hasCompleted : true;\n\n // Compute the final `hasCompleted` value\n const hasCompleted = isAuthenticated ? (\n currentUser.hasCompleted &&\n config.hasCompleted &&\n viviStatusCheckCompleted &&\n permissionsLoaded &&\n !isLoadingSettings &&\n !isLoadingProducts\n ) : true;\n \n return {\n hasCompleted,\n data: {\n ctaOptions,\n canUserCastToDevices: canUserCastToVivi || canUserCastToAppleTv,\n vivi: {\n accountConnected: viviAccountConnected,\n enabled: canUserCastToVivi && hasEnabledViviPlayback,\n apiUrl: config.data?.viviApiUrl ?? '',\n fetchAccessToken: fetchViviAccessToken\n },\n appleTv: {\n enabled: canUserCastToAppleTv && hasEnabledAppleTvPlayback,\n fetchAccessToken: fetchAppleTvAccessToken\n }\n }\n };\n}\n\nfunction useAccessTokenFetchFunctions() {\n const fetchAsync = Flight.useGetFetchAsync();\n const getResponse = Flight.useGetResponseFunc();\n\n const fetchViviAccessToken = async () => {\n const request = PlayerIntegrationsRequests.getViviAccessToken();\n const tokenResponse = getResponse<ViviAccessToken>(request.key);\n const { token } = tokenResponse.shouldFetch ?\n await fetchAsync<ViviAccessToken>(request) :\n tokenResponse.data;\n \n return token;\n };\n\n const fetchAppleTvAccessToken = () => {\n return fetchAsync<AppleTvAccessToken>(\n PlayerIntegrationsRequests.getAppleTvAccessToken()\n );\n };\n\n return {\n fetchViviAccessToken,\n fetchAppleTvAccessToken\n };\n}\n\nconst VIVI_LEARN_MORE_URL = 'https://clickv.ie/w/WVsx';\nconst APPLE_TV_LEARN_MORE_URL = 'https://clickv.ie/w/PVsx';\n\nfunction useCtaOptions(hasPermissions: HasPermissionsFunc) {\n const [ dismissedModel, setDismissedModel ] = useViewModel<{ dismissed: boolean }>(\n 'devices:cta:dismissed',\n { dismissed: false },\n { storage: StorageType.LocalStorage }\n );\n const isStudent = hasPermissions(PermissionName.StudentExperience);\n const canUserManageIntegrations = hasPermissions(PermissionName.ManageIntegrations);\n const analyticsOptions: Partial<AnalyticsOptions> = {\n entity: EntityType.DevicesCta,\n actionType: UserAction.Click,\n workflowPhase: WorkflowPhase.Complete,\n location: LocationContext.Player\n };\n\n const onDismiss = (context: CtaContext) => {\n AnalyticsHelper.logUserAction({\n canUserManageIntegrations,\n context\n }, {\n ...analyticsOptions,\n descriptor: DevicesDescriptor.Dismiss,\n eventVersion: EventVersion.V1\n });\n\n setDismissedModel({ dismissed: true });\n };\n\n const onInstall = (context: CtaContext) => {\n AnalyticsHelper.logUserAction({\n canUserManageIntegrations,\n context\n }, {\n ...analyticsOptions,\n descriptor: DevicesDescriptor.InstallIntegration,\n eventVersion: EventVersion.V1\n });\n\n Core.AppLinkHelper.trigger({\n application: AppChannels.SETTINGS,\n action: Actions.Settings.INTEGRATIONS\n });\n };\n\n const onLearnMore = (context: CtaContext) => {\n AnalyticsHelper.logUserAction({\n canUserManageIntegrations,\n context\n }, {\n ...analyticsOptions,\n descriptor: DevicesDescriptor.LearnMore,\n eventVersion: EventVersion.V1\n });\n\n if (context === 'vivi_and_apple_tv' || context === 'vivi')\n LocationUtils.PageLoad(VIVI_LEARN_MORE_URL, true);\n\n if (context === 'vivi_and_apple_tv' || context === 'apple_tv')\n LocationUtils.PageLoad(APPLE_TV_LEARN_MORE_URL, true);\n };\n\n const onContactSupport = (context: CtaContext) => {\n AnalyticsHelper.logUserAction({\n canUserManageIntegrations,\n context\n }, {\n ...analyticsOptions,\n descriptor: DevicesDescriptor.ContactSupport,\n eventVersion: EventVersion.V1\n });\n\n LocationUtils.PageLoad(ArticleHelper.getSupportRequestUrl(), true);\n };\n\n return {\n hasBeenDismissed: dismissedModel.dismissed || isStudent,\n canUserManageIntegrations,\n onDismiss,\n onInstall,\n onLearnMore,\n onContactSupport\n };\n}\n","// Misc constants\nexport const LiteConstants = {\n VIDEO_START_TIME_CUTOFF: 10, // If the video start time is in the last 10 seconds of the video duration, it's ignored\n PUBLIC_SEARCH_QUERY_DEBOUNCE: 400,\n AUTHENTICATED_SEARCH_QUERY_DEBOUNCE: 200\n};\n","import { Core } from 'libs/common/core';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { SettingsHash } from 'libs/shared/hooks/useSettings';\nimport { Category, Company, Library, Link, PartnerProfile, Person, Resource, Series, Tag, Video } from 'libs/shared/interfaces';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { LiteConstants } from 'shared/constants/LiteConstants';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { ContentPartnerAppLinkHelper } from 'shared/utils/ContentPartnerAppLinkHelper';\n\nimport { SeriesAppLinkHelper } from 'apps/series/SeriesAppLinkHelper';\n\nexport function getResources(\n video: Video,\n isLearner: boolean\n): Array<Resource | Link> {\n const resources = video.resources?.data ?? [];\n const links = video.links?.data ?? [];\n\n const filteredResources = resources.filter(r => {\n if (!isLearner)\n return true;\n\n return r.metadata?.resourceType === 'additional-materials' || r.metadata?.resourceType === 'student-activity';\n });\n\n return [ ...filteredResources, ...links ];\n}\n\nexport const getLibraryAppLink = (library: Library): Core.AppLink => {\n return {\n application: AppChannels.LIBRARIES,\n action: Actions.Libraries.LIBRARY,\n args: [ library.id.toString(), TextHelper.slugify(library.name) ]\n };\n};\n\nexport const getFolderAppLink = (library: Library, folder: Category): Core.AppLink => {\n return {\n application: AppChannels.LIBRARIES,\n action: Actions.Libraries.FOLDER,\n args: [ library.id.toString(), folder.id.toString(), TextHelper.slugify(folder.name) ]\n };\n};\n\ninterface GetAppLinksOptions {\n settings: SettingsHash;\n presentationSlug: string | null;\n}\n\nexport function getAppLinks(options: GetAppLinksOptions) {\n const { settings, presentationSlug } = options;\n\n const getTagAppLink = (tag: Tag) => {\n return {\n application: AppChannels.SEARCH,\n action: Actions.Search.HOME,\n params: { tagOrClassification: tag.name }\n };\n };\n\n const getSeriesAppLink = (series: Series, moviesAndTv: boolean): Core.AppLink => {\n return SeriesAppLinkHelper.getSeriesAppLink(series, moviesAndTv ? { mtv: true } : {}, presentationSlug);\n };\n\n const getResourceAppLink = (videoId: string, shareId: string, canViewResource: boolean) =>\n (resource: Resource | Link) => {\n /**\n * We check both the feature access value and the shareId. \n * Resources should always be available if we have a share id, and the backend should control\n * which specific resources are returned - Sha\n */\n if (!canViewResource && !shareId) {\n return {\n application: AppChannels.SIGN_UP,\n action: Actions.SignUp.SIGN_UP\n };\n }\n\n return {\n application: AppChannels.VIDEOS,\n action: Actions.Videos.PREVIEW_PDF,\n args: [resource.id],\n params: {\n videoId: videoId,\n shareId: shareId\n }\n };\n };\n\n const getPartnerProfileAppLink = (partnerProfile: PartnerProfile) => {\n return ContentPartnerAppLinkHelper.getPartnerDashboardAppLink(partnerProfile);\n };\n\n const getPartnerDashboardHubAppLink = (company: Company | Person) => {\n return ContentPartnerAppLinkHelper.getPartnerDashboardHubAppLink(company);\n };\n\n return {\n getTagAppLink,\n getSeriesAppLink,\n getResourceAppLink,\n getPartnerProfileAppLink: settings?.hasPartnerProfiles ? getPartnerProfileAppLink : null,\n getPartnerDashboardHubAppLink: settings?.hasPartnerProfiles ? getPartnerDashboardHubAppLink : null,\n getLibraryAppLink,\n getFolderAppLink\n };\n}\n\nexport function getStartTime(startTimeParam: string | number, video: Video): number {\n const startTime = Number(startTimeParam);\n\n if (!isNaN(startTime) && startTime >= 0)\n return startTime;\n\n const lastProgressPoint = VideoHelper.getVideoProgress(video);\n\n if (!lastProgressPoint)\n return 0;\n\n if (lastProgressPoint >= (video.duration / 1000 - LiteConstants.VIDEO_START_TIME_CUTOFF))\n return 0;\n\n return lastProgressPoint;\n}\n\nexport function getEndTime(endTimeParam: string | number): number | undefined {\n if (Number.isInteger(+endTimeParam))\n return +endTimeParam;\n\n return undefined;\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { EmbedPlaceHolderHelper } from 'apps/embed/utils/EmbedPlaceholderHelper';\n\nimport styles from './stream-limit-overlay.module.scss';\n\nconst namespace = 'shared.streamLimitOverlay';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface StreamLimitOverlayProps {\n posterUrl: string;\n embed: boolean;\n hasStudentExperience: boolean;\n canRedeemMoreReferrals: boolean;\n totalStreamsAvailable: number;\n}\n\nexport function StreamLimitOverlay(props: StreamLimitOverlayProps): JSX.Element {\n const ctaAction = props.canRedeemMoreReferrals ?\n Actions.SignUp.INVITE_COLLEAGUE :\n Actions.SignUp.UPGRADE;\n\n const ctaPhrase = props.canRedeemMoreReferrals ? 'inviteCta' : 'upgradeCta';\n const hideCta = props.embed || props.hasStudentExperience;\n\n let descriptionPhrase: string;\n\n if (hideCta)\n descriptionPhrase = 'basicDescription';\n else if (props.canRedeemMoreReferrals)\n descriptionPhrase = 'referralDescription';\n else\n descriptionPhrase = 'upgradeDescription';\n\n /**\n * Embeds render a server-side splash screen (#embed-placeholder) that covers\n * the React app until the player fires 'cv-playback-data-loaded'. Since the\n * overlay replaces the player, that event never fires — so we need to \n * remove it manually.\n */\n React.useEffect(() => {\n if (props.embed)\n EmbedPlaceHolderHelper.remove();\n }, [props.embed]);\n\n return (\n <div className={`position-relative bg-light overflow-hidden ${props.embed ? 'position-fixed top-0 start-0 end-0 bottom-0' : 'ratio ratio-16x9'}`}>\n {props.posterUrl && (\n <img className={`position-absolute top-0 start-0 w-100 h-100 object-fit-cover ${styles.poster}`} src={props.posterUrl} alt='' />\n )}\n <div className={`position-absolute top-0 start-0 w-100 h-100 ${styles.frost}`} />\n <div className='position-absolute top-0 start-0 w-100 h-100 d-flex flex-column align-items-center justify-content-center text-center p-4'>\n <img\n className={`${styles.image} d-none d-md-block mb-3`}\n src={ImageUrls.SignUp.INVITE_COLLEAGUE}\n alt={getPhrase('heading')}\n />\n <h2 className='h5 mb-2'><Text namespace={namespace} phrase='heading' options={{ smartCount: props.totalStreamsAvailable }} /></h2>\n <p className='text-dark mb-3'>{getPhrase(descriptionPhrase)}</p>\n {!hideCta && (\n <AppLink\n className='btn btn-dark'\n appLink={{ application: AppChannels.SIGN_UP, action: ctaAction }}\n >\n {getPhrase(ctaPhrase)}\n </AppLink>\n )}\n </div>\n </div>\n );\n}\n","import React from 'react';\n\nconst UP_ARROW = 38;\nconst DOWN_ARROW = 40;\n\n/**\n * When this hook is used on a page, it will prevent the page from being scrollable by using\n * the up/down arrow keys.\n * \n * This is helpful on pages with a video playing, as we want the up/down arrow keys to control the\n * player volume without scrolling.\n */\nexport const usePreventKeyboardScroll = () => {\n function preventDefaultForScrollKeys(e: KeyboardEvent): boolean {\n if (e.keyCode === UP_ARROW || e.keyCode === DOWN_ARROW) {\n e.preventDefault();\n return false;\n }\n }\n\n React.useEffect(() => {\n window.addEventListener('keydown', preventDefaultForScrollKeys, false);\n\n return () => {\n window.removeEventListener('keydown', preventDefaultForScrollKeys, false);\n };\n }, []);\n};\n","import { Flight } from 'libs/common/flight';\n\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { RelatedVideosContext } from 'libs/shared/enums/RelatedVideosContext';\nimport { VideoRequests } from 'libs/shared/flight-requests/VideoRequests';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { CurrentUser, VideoTypes } from 'libs/shared/interfaces';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { useVideoFeatureAccess } from './useVideoFeatureAccess';\n\n/**\n * Poor mans paging explination:\n * \n * This change was made while we were doing performance imrovements in Feb 2024.\n * Because the related videos endpoint does not have paging, we fetch 6 to display 5 videos\n * this will let us know if there is another page. When the user requests the next page\n * we just fetch 25 items.\n * \n * - sHa\n */\nconst RELATED_VIDEOS_FIRST_PAGE = 6;\nconst RELATED_VIDEOS_MAX = 25;\n\nexport interface RelatedVideosHash {\n videos: VideoTypes[];\n hasError: boolean;\n hasCompleted: boolean;\n isFetching: boolean;\n fetchNext: () => void;\n hasMore: boolean;\n}\n\ninterface RelatedVideoOptions {\n video: VideoTypes;\n currentUser: CurrentUser;\n context: RelatedVideosContext;\n contextId: string;\n moviesAndTv: boolean;\n}\n\nexport function useGetRelatedVideos(options: RelatedVideoOptions): RelatedVideosHash {\n const { video, currentUser, moviesAndTv, context, contextId } = options;\n\n const { canViewRelatedVideos } = useVideoFeatureAccess();\n\n const { hasProduct } = useProducts();\n\n const fetch = Flight.useGetFetch();\n\n function getRequest(limit: number): Flight.Request {\n if (!video || !currentUser?.isAuthenticated || !hasProduct(ProductId.Primary) || !canViewRelatedVideos)\n return null;\n\n /**\n * We are no longer fetching related videos unless we have a context\n */\n if (!context && !contextId)\n return null;\n\n return VideoRequests.relatedVideos({\n videoId: video.id,\n context,\n collectionId: contextId,\n moviesAndTv,\n limit\n });\n }\n\n function filterVideos(videos: VideoTypes[]): VideoTypes[] {\n if (!videos) // Might be undefined or null\n return videos;\n\n if (hasMore)\n videos = videos.slice(0, RELATED_VIDEOS_FIRST_PAGE - 1);\n\n return videos.filter(v => VideoHelper.getCanBeConsumed(v)?.canNavigate);\n }\n\n function fetchNext() {\n fetch(getRequest(RELATED_VIDEOS_MAX));\n }\n\n const response = Flight.useBasicFetch<VideoTypes[]>(getRequest(RELATED_VIDEOS_FIRST_PAGE));\n\n const hasMore = response.data?.length === RELATED_VIDEOS_FIRST_PAGE;\n\n return {\n videos: filterVideos(response.data),\n hasCompleted: response.hasCompleted,\n isFetching: response.isFetching,\n hasError: response.hasError,\n hasMore,\n fetchNext\n };\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { Flight } from 'libs/common/flight';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { ShareRequests } from 'libs/shared/apps/share/flight-requests/ShareRequests';\nimport { PlayerMode } from 'libs/shared/context/player-context/interfaces/PlayerMode';\nimport { PlayerReference } from 'libs/shared/context/player-context/interfaces/PlayerReference';\nimport { ImageSize } from 'libs/shared/enums/Images';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { MediaIdType } from 'libs/shared/enums/MediaIdType';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { RelatedVideosContext } from 'libs/shared/enums/RelatedVideosContext';\nimport { ShareActivityStatus } from 'libs/shared/enums/ShareActivityStatus';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { FavouriteRequests } from 'libs/shared/flight-requests/FavouriteRequests';\nimport { PlayerRequests } from 'libs/shared/flight-requests/PlayerRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useActivityStatus } from 'libs/shared/hooks/UseActivityStatus';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { Config, CurrentUser, PlayerViewKey, ShareLink, UnionShareObject, VideoTypes } from 'libs/shared/interfaces';\nimport { FavouriteHelper } from 'libs/shared/utils/FavouriteHelpers';\nimport { ImageHelper } from 'libs/shared/utils/ImageHelper';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { useFetchPointsOfInterest } from 'shared/hooks/useFetchPointsOfInterest';\nimport { useGetRelatedVideos } from 'shared/hooks/useGetRelatedVideos';\nimport { useLiteFavourites } from 'shared/hooks/useLiteFavourites';\nimport { usePlayerIntegrations } from 'shared/hooks/usePlayerIntegrations';\nimport { VideoAppLinkHelper } from 'shared/utils/VideoAppLinkHelper';\n\nconst THUMBNAIL_SIZE = ImageSize.Medium;\n\nfunction createViewKeyRequest(\n objectId: string,\n shareId: string,\n shareLink: ShareLink\n): Flight.Request {\n if (!shareId)\n return PlayerRequests.createViewKey(objectId, MediaIdType.MasterObject);\n\n if (!shareLink)\n return null;\n\n /**\n * If our share link matches our object id it's just a video share\n */\n if (shareLink.objectId === objectId)\n return PlayerRequests.createViewKey(shareId, MediaIdType.Share);\n\n /**\n * Otherwise we're attempting to watch a video inside of a shared video collection (e.g. A shared playlist)\n */\n return PlayerRequests.createViewKey(objectId, MediaIdType.MasterObject, shareId);\n}\n\ninterface UseGetPlayerDataOptions {\n objectId: string;\n objectTypeId: MasterType;\n shareId: string;\n context: RelatedVideosContext;\n contextId: string;\n moviesAndTv: boolean;\n}\n\nexport function useGetPlayerData(options: UseGetPlayerDataOptions) {\n const { objectId, objectTypeId, shareId, context, contextId, moviesAndTv } = options;\n\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const video = Flight.useBasicFetch<VideoTypes>(\n objectId && VideoHelper.getVideoRequest(objectId, objectTypeId, shareId)\n );\n const shareLink = Flight.useBasicFetch<ShareLink>(shareId && ShareRequests.getShareObject(shareId));\n const canHavePointsOfInterest = objectTypeId === MasterType.Video || objectTypeId === MasterType.Clip;\n const pointsOfInterest = useFetchPointsOfInterest(canHavePointsOfInterest && objectId);\n const viewKey = Flight.useBasicFetch<PlayerViewKey>(\n objectId && createViewKeyRequest(objectId, shareId, shareLink.data)\n );\n const relatedVideos = useGetRelatedVideos({\n video: video.data,\n context,\n contextId,\n moviesAndTv,\n currentUser: currentUser.data\n });\n const playerIntegrations = usePlayerIntegrations(objectId);\n \n /**\n * Mix in if our video is favourited\n */\n Flight.useBasicFetch(\n objectId &&\n currentUser.data?.isAuthenticated &&\n FavouriteRequests.isFavourited(currentUser.data.id, [objectId])\n );\n\n const hasCompleted = (\n video.data &&\n config.hasCompleted &&\n currentUser.hasCompleted &&\n (!shareId || shareLink.hasCompleted) &&\n (objectTypeId !== MasterType.Video || pointsOfInterest.hasCompleted) &&\n viewKey.hasCompleted &&\n playerIntegrations.hasCompleted\n );\n\n return {\n hasCompleted,\n config: config.data,\n currentUser: currentUser.data,\n video: video.data,\n shareLink: shareLink.data,\n pointsOfInterest: pointsOfInterest?.items,\n viewKey: viewKey.data,\n relatedVideos: relatedVideos.videos,\n playerIntegrations: playerIntegrations.data\n };\n}\n\nexport function useSetFavourite(player: PlayerReference, video: VideoTypes) {\n const { setFavourite, canFavourite } = useLiteFavourites(LocationContext.Player);\n const isFavourited = FavouriteHelper.isFavouritedByCurrentUser(video);\n const isArchived = VideoHelper.isVideoTypeArchived(video);\n\n React.useEffect(() => {\n if (!player || !video || !canFavourite(video) || isArchived)\n return;\n\n player.setFavourite?.(isFavourited, (setFav: boolean) => setFavourite(video, setFav));\n }, [ video, player, canFavourite, isArchived ]);\n}\n\nexport function useSetActivityStatus(\n player: PlayerReference,\n video: VideoTypes,\n shareLink: UnionShareObject\n) {\n // Disabling activity status for performance reasons (28/2/24) - Sha\n return;\n\n const setActivityStatus = useActivityStatus(LocationContext.FloatingPlayer);\n const { hasPermissions } = usePermissions();\n\n React.useEffect(() => {\n if (!player || !video || !shareLink)\n return;\n\n if (!hasPermissions(PermissionName.StudentExperience) || !('activityStatus' in shareLink))\n return;\n\n player.setActivityStatus?.(shareLink.activityStatus, () => {\n const newStatus = shareLink.activityStatus === ShareActivityStatus.Complete ?\n ShareActivityStatus.Incomplete :\n ShareActivityStatus.Complete;\n\n setActivityStatus(shareLink.id, video, newStatus);\n });\n }, [ player, video, shareLink ]);\n}\n\nexport function useCreateClip(\n playerRef: React.MutableRefObject<PlayerReference>,\n currentUser: CurrentUser,\n video: VideoTypes,\n embed: boolean,\n allowCreateClip: boolean\n) {\n const { hasProduct } = useProducts();\n const isArchived = VideoHelper.isVideoTypeArchived(video);\n\n const canCreateClip = (\n currentUser.isAuthenticated &&\n VideoHelper.isVideo(video) &&\n video._canCreateChild?.value &&\n hasProduct(ProductId.Primary) &&\n !embed &&\n allowCreateClip &&\n !isArchived\n ) ;\n\n if (!canCreateClip)\n return undefined;\n \n function onClickCreateClip(): void {\n if (!canCreateClip)\n return;\n\n Core.AppLinkHelper.trigger({\n application: AppChannels.CLIPS,\n action: Actions.Clips.CREATE_CLIP,\n args: [video.id],\n params: {\n startTime: playerRef.current?.currentTime?.() ?? undefined\n }\n });\n }\n\n return onClickCreateClip;\n}\n\nexport function usePip(\n currentUser: CurrentUser,\n onRequestPictureInPicture: (isPip: boolean) => void\n) {\n const { hasProduct } = useProducts();\n\n return (\n currentUser.isAuthenticated &&\n hasProduct(ProductId.Primary) &&\n onRequestPictureInPicture\n );\n}\n\ninterface UseSetNextVideoOptions {\n player: PlayerReference;\n relatedVideos: VideoTypes[];\n shareId: string;\n context: RelatedVideosContext;\n contextId: string;\n moviesAndTv: boolean;\n playNext: boolean;\n mode: PlayerMode;\n isAuthenticated: boolean;\n presentationSlug: string | null;\n}\n\nexport function useSetNextVideo(options: UseSetNextVideoOptions): void {\n const {\n player,\n relatedVideos,\n shareId,\n context,\n contextId,\n moviesAndTv,\n playNext,\n mode,\n isAuthenticated,\n presentationSlug\n } = options;\n\n const first = relatedVideos?.[0];\n\n React.useEffect(() => {\n if (!player?.setNextVideo || !first)\n return;\n\n /**\n * We only want to go to the next video if the user is on a play page.\n */\n if (mode !== 'default') {\n player.setNextVideo?.(null, false, null);\n return;\n }\n\n const rawThumbanilUrl = VideoHelper.getThumbnail(first)?.url;\n const nextVideo = {\n name: first.name,\n thumbnailUrl: ImageHelper.createUrl(rawThumbanilUrl, { size: THUMBNAIL_SIZE })\n };\n\n player.setNextVideo?.(nextVideo, playNext, () => {\n Core.AppLinkHelper.trigger(VideoAppLinkHelper.getAppLink(first, {\n shareId,\n context,\n contextId,\n playNext,\n moviesAndTv,\n includeContext: isAuthenticated\n }, presentationSlug));\n });\n }, [\n player,\n first,\n shareId,\n context,\n contextId,\n playNext,\n mode\n ]);\n}\n","import React from 'react';\nimport { HtmlPortalNode } from 'react-reverse-portal';\n\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { DefaultDisplayMode } from 'libs/shared/context/player-context/interfaces/PlayerContextAction';\nimport { PlayerMode } from 'libs/shared/context/player-context/interfaces/PlayerMode';\nimport { PlayerReference } from 'libs/shared/context/player-context/interfaces/PlayerReference';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { RelatedVideosContext } from 'libs/shared/enums/RelatedVideosContext';\nimport { useForceUpdate } from 'libs/shared/hooks/useForceUpdate';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { Config, CurrentUser, PlayerIntegrations, PlayerViewKey, PointOfInterest, UnionShareObject, VideoTypes } from 'libs/shared/interfaces';\nimport { AuthToken } from 'libs/shared/interfaces/models/AuthToken';\nimport { PlayerAnalyticsTracker } from 'libs/shared/utils/PlayerAnalyticsTracker';\nimport { ShareHelper } from 'libs/shared/utils/ShareHelper';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport type { PlayerOptions } from 'projects/player/players/player';\nimport type { ExternalLinkOptions } from 'projects/player/plugins/open-externally-plugin/interfaces/ExternalLinkOptions';\n\nimport { getEndTime, getStartTime } from 'shared/components/play-page/PlayPageUtils';\nimport { StreamLimitOverlay } from 'shared/components/stream-limit-overlay/StreamLimitOverlay';\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { usePreventKeyboardScroll } from 'shared/hooks/usePreventKeyboardScroll';\nimport { useStreamQuota } from 'shared/hooks/useStreamQuota';\nimport { VideoAppLinkHelper } from 'shared/utils/VideoAppLinkHelper';\nimport { useCreateClip, usePip, useSetActivityStatus, useSetFavourite, useSetNextVideo } from 'shared/views/lite-player/LitePlayerViewHooks';\n\nimport styles from './lite-player.module.scss';\n\nfunction shouldCollectResults(props: LitePlayerViewProps): boolean {\n if (!props.shareLink)\n return false;\n\n if (props.currentUser.isAuthenticated)\n return true;\n\n return !!props.collectAnonResults;\n}\n\nfunction getExternalLink(\n video: VideoTypes,\n shareLink: UnionShareObject,\n options: ExternalLinkOptions,\n isAuthenticated: boolean,\n presentationSlug: string | null\n): string {\n if (shareLink) {\n return Core.AppLinkHelper.getHref({\n application: AppChannels.SHARE,\n action: Actions.Share.VIEW_SHARE_LINK,\n args: [shareLink.id],\n params: {\n t: options.currentTime,\n a: true\n }\n });\n }\n\n const appLink = VideoAppLinkHelper.getAppLink(video, { includeContext: isAuthenticated }, presentationSlug);\n if (!appLink.params)\n appLink.params = {};\n\n (appLink.params as HashObject).t = options.currentTime;\n (appLink.params as HashObject).a = true;\n return Core.AppLinkHelper.getHref(appLink);\n}\n\nexport interface LitePlayerViewProps {\n // Core data\n config: Config;\n token?: AuthToken;\n video: VideoTypes;\n currentUser: CurrentUser;\n shareLink?: UnionShareObject;\n pointsOfInterest?: PointOfInterest[];\n viewKey: PlayerViewKey;\n relatedVideos?: VideoTypes[];\n presentationSlug: string | null;\n\n // Hook options\n context?: RelatedVideosContext;\n contextId?: string;\n moviesAndTv?: boolean;\n playNext?: boolean;\n mode?: PlayerMode;\n defaultDisplayMode?: DefaultDisplayMode;\n\n allowCreateClip?: boolean;\n allowTheatreMode?: boolean;\n allowTranscript?: boolean;\n\n // Passthrough options\n autoplay?: boolean;\n startTime?: string;\n endTime?: string;\n embed?: boolean;\n showResources?: boolean;\n muted?: boolean;\n\n // Interactive\n summaryPortalNode?: HtmlPortalNode;\n questionListPortalNode?: HtmlPortalNode;\n onShowSummary?: (showing: boolean) => void;\n collectAnonResults?: boolean;\n\n // Devices\n playerIntegrations?: PlayerIntegrations;\n\n onReady?: (player: PlayerReference) => void;\n onRequestPictureInPicture?: (isPip: boolean) => void;\n onRequestTheatreMode?: (isTheatreMode: boolean) => void;\n}\n\n/**\n * Consumers of this view need to opt out of these features.\n */\nLitePlayerView.defaultProps = {\n allowCreateClip: true\n};\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function LitePlayerView(props: LitePlayerViewProps): JSX.Element {\n const playerRef = React.useRef<PlayerReference>(null);\n const analyticsTracker = React.useRef<PlayerAnalyticsTracker>(null);\n\n useSetFavourite(playerRef.current, props.video);\n useSetActivityStatus(playerRef.current, props.video, props.shareLink);\n useSetNextVideo({\n player: playerRef.current,\n relatedVideos: props.relatedVideos,\n shareId: props.shareLink?.id,\n context: props.context,\n contextId: props.contextId,\n moviesAndTv: props.moviesAndTv,\n playNext: props.playNext,\n mode: props.mode,\n isAuthenticated: props.currentUser?.isAuthenticated,\n presentationSlug: props.presentationSlug\n });\n usePreventKeyboardScroll();\n \n const allowPip = usePip(props.currentUser, props.onRequestPictureInPicture);\n\n const { experimentalInteractiveQuestions } = useSettings(null);\n const {\n isLoaded: streamQuotaLoaded,\n hasReachedStreamLimit,\n canRedeemMoreReferrals,\n totalStreamsAvailable\n } = useStreamQuota();\n\n const { hasPermissions } = usePermissions();\n\n const isGuest = hasPermissions(PermissionName.GuestExperience);\n const hasStudentExperience = hasPermissions(PermissionName.StudentExperience);\n\n const onClickCreateClip = useCreateClip(\n playerRef,\n props.currentUser,\n props.video,\n props.embed,\n isGuest ? false : props.allowCreateClip\n );\n\n const forceUpdate = useForceUpdate();\n\n function onReady(player: PlayerReference): void {\n playerRef.current = player;\n forceUpdate();\n props.onReady && props.onReady(player);\n setupAnalytics(player);\n }\n\n function setupAnalytics(player: PlayerReference): void {\n analyticsTracker.current = new PlayerAnalyticsTracker({\n player,\n video: props.video,\n analyticsLocation: props.embed ?\n LocationContext.EmbeddedPlayer :\n LocationContext.PlayPage,\n shareId: props.shareLink?.id\n });\n }\n\n let posterUrl = '';\n if ('thumbnail' in props.video)\n posterUrl = props.video.thumbnail?.url;\n if (!posterUrl && '_parentVideo' in props.video)\n posterUrl = props.video._parentVideo?.thumbnail?.url;\n\n const commonProps: PlayerOptions = {\n // Fetched\n viewKey: props.viewKey.viewKey,\n playerApi: new URL(props.config.playerApiUrl),\n imageCdnUrl: props.config.imageCdnUrl,\n\n // Options\n autoplay: props.autoplay,\n startTime: getStartTime(props.startTime, props.video),\n endTime: getEndTime(props.endTime),\n embed: props.embed,\n showResources: props.showResources,\n getExternalLink: props.embed &&\n (options => getExternalLink(\n props.video,\n props.shareLink,\n options,\n props.currentUser?.isAuthenticated,\n props.presentationSlug\n )),\n muted: props.muted,\n splash: props.embed ? {\n title: props.video.name,\n posterUrl,\n ratingCode: VideoHelper.getRating(props.video)?.code,\n ratingValue: VideoHelper.getRating(props.video)?.value,\n seriesName: 'series' in props.video && props.video.series?.name,\n seasonNumber: 'season' in props.video && props.video.season?.number,\n episodeNumber: 'episodeNumber' in props.video && props.video.episodeNumber\n } : undefined,\n // todo remove this once we ship theatre mode for everyone\n allowTheatreMode: props.allowTheatreMode,\n allowLoop: true,\n\n // Static\n hotkeyElQuerySelector: 'body',\n sharerInstanceRegion: props.shareLink?.ownerInstanceRegion\n };\n\n const devicesConfig = props.playerIntegrations ? {\n ...props.playerIntegrations,\n trackingCode: VideoHelper.getTrackingCode(props.video)\n } : undefined;\n\n const isTheatreMode = props.mode === 'default' && props.defaultDisplayMode === 'theatre';\n const isHoverMode = props.mode === 'hover';\n const isInteractive = props.video.typeId === MasterType.Interactive;\n const isPublicShare = ShareHelper.isPublic(props.shareLink);\n const showStreamLimitOverlay = streamQuotaLoaded && hasReachedStreamLimit && !isHoverMode && !isPublicShare;\n\n /**\n * We memoize two React.lazy components (interactive and standard) to avoid Suspense flicker on re-renders.\n * Hooks can't be conditional, so both lazies are created once and we choose which to render at runtime.\n * With default exports, React.lazy infers props, so no casting is required. - Sha\n */\n const InteractivePlayer = React.useMemo(() => React.lazy(() => import('projects/player/react/InteractivePlayer')), []);\n const Player = React.useMemo(() => React.lazy(() => import('projects/player/react/Player')), []);\n \n if (showStreamLimitOverlay) {\n return (\n <StreamLimitOverlay\n posterUrl={posterUrl}\n embed={props.embed}\n hasStudentExperience={hasStudentExperience}\n canRedeemMoreReferrals={canRedeemMoreReferrals}\n totalStreamsAvailable={totalStreamsAvailable}\n />\n );\n }\n\n if (isInteractive) {\n return (\n <React.Suspense fallback={<div className={styles.placeholder} />}>\n <InteractivePlayer\n {...commonProps}\n imageApi={new URL(props.config.imageCdnUrl)}\n currentUser={props.currentUser}\n collectResults={shouldCollectResults(props)}\n shareId={props.shareLink?.id}\n enableImmersiveReader\n summaryPortalNode={props.summaryPortalNode}\n onShowSummary={props.onShowSummary}\n onReady={onReady}\n className={props.embed ? styles.embeddedPlayer : ''}\n furthestVisitedTime={props.video._videoProgress?.furthest}\n questionListPortalNode={props.questionListPortalNode}\n authToken={props.token?.value}\n experimentalInteractiveQuestions={experimentalInteractiveQuestions}\n />\n </React.Suspense>\n );\n }\n\n function getClassName(): string {\n if (props.embed) {\n return styles.embeddedPlayer;\n }\n if (isTheatreMode)\n return 'w-100 h-100';\n return '';\n }\n\n return (\n <React.Suspense fallback={<div className={`${styles.placeholder} ${isTheatreMode ? styles.theatreMode : ''}`} />}>\n <Player\n {...commonProps}\n devicesConfig={devicesConfig}\n className={getClassName()}\n onClickCreateClip={onClickCreateClip}\n pointsOfInterest={props.pointsOfInterest}\n onReady={onReady}\n showResources={props.embed}\n onRequestPictureInPicture={allowPip && props.onRequestPictureInPicture}\n onRequestTheatreMode={props.onRequestTheatreMode}\n theatreMode={isTheatreMode}\n nextDefaultDisplayMode={props.defaultDisplayMode}\n allowTranscript={props.allowTranscript}\n />\n </React.Suspense>\n );\n}\n"],"file":"_Cm5O72d.chunk.js"}