@clickview/lite 0.69.1-dev.0 → 0.69.1-dev.2
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/dist/bundles.json +1 -1
- package/dist/css/{9985-lite-3c49d1b796.chunk.css → 3902-lite-5eaa7e7ae0.chunk.css} +1 -2
- package/dist/css/{555-lite-1b5aa9652d.chunk.css → 4356-lite-b05b606d3d.chunk.css} +1 -2
- package/dist/css/{2636-lite-f995954232.chunk.css → 4527-lite-4d1b877b3f.chunk.css} +4 -0
- package/dist/css/{1239-lite-8152f713c8.chunk.css → 7210-lite-a568e8ec1e.chunk.css} +1 -0
- package/dist/languages/en.json +1 -1
- package/dist/scripts/1210-7afb28caac-lite.chunk.js +2 -0
- package/dist/scripts/1210-7afb28caac-lite.chunk.js.map +1 -0
- package/dist/scripts/1386-332e63f68c-lite.chunk.js +2 -0
- package/dist/scripts/1386-332e63f68c-lite.chunk.js.map +1 -0
- package/dist/scripts/232-1522c00252-lite.chunk.js +3 -0
- package/dist/scripts/232-1522c00252-lite.chunk.js.map +1 -0
- package/dist/scripts/2392-19e4bb187b-lite.chunk.js +3 -0
- package/dist/scripts/2392-19e4bb187b-lite.chunk.js.map +1 -0
- package/dist/scripts/{2640-536c550749-lite.chunk.js → 2640-052f4606f6-lite.chunk.js} +2 -2
- package/dist/scripts/2640-052f4606f6-lite.chunk.js.map +1 -0
- package/dist/scripts/300-3d9f3cd4e3-lite.chunk.js +2 -0
- package/dist/scripts/300-3d9f3cd4e3-lite.chunk.js.map +1 -0
- package/dist/scripts/3079-0a333d6805-lite.chunk.js +2 -0
- package/dist/scripts/3079-0a333d6805-lite.chunk.js.map +1 -0
- package/dist/scripts/3110-eee18143c6-lite.chunk.js +2 -0
- package/dist/scripts/3110-eee18143c6-lite.chunk.js.map +1 -0
- package/dist/scripts/312-693aa30814-lite.chunk.js +2 -0
- package/dist/scripts/312-693aa30814-lite.chunk.js.map +1 -0
- package/dist/scripts/3902-39aaff7ce9-lite.chunk.js +2 -0
- package/dist/scripts/3902-39aaff7ce9-lite.chunk.js.map +1 -0
- package/dist/scripts/4229-477b1858dc-lite.chunk.js +2 -0
- package/dist/scripts/4229-477b1858dc-lite.chunk.js.map +1 -0
- package/dist/scripts/4356-36ce3ceec1-lite.chunk.js +2 -0
- package/dist/scripts/4356-36ce3ceec1-lite.chunk.js.map +1 -0
- package/dist/scripts/4527-42075d96f4-lite.chunk.js +2 -0
- package/dist/scripts/4527-42075d96f4-lite.chunk.js.map +1 -0
- package/dist/scripts/{4845-f3646fb657-lite.chunk.js → 4845-9b4657e696-lite.chunk.js} +2 -2
- package/dist/scripts/4845-9b4657e696-lite.chunk.js.map +1 -0
- package/dist/scripts/5679-444d9a7f76-lite.chunk.js +2 -0
- package/dist/scripts/5679-444d9a7f76-lite.chunk.js.map +1 -0
- package/dist/scripts/6046-104677f08c-lite.chunk.js +2 -0
- package/dist/scripts/6046-104677f08c-lite.chunk.js.map +1 -0
- package/dist/scripts/{6188-e108abca25-lite.chunk.js → 6188-77fc2f3ec5-lite.chunk.js} +2 -2
- package/dist/scripts/6188-77fc2f3ec5-lite.chunk.js.map +1 -0
- package/dist/scripts/6351-dff9edbb16-lite.chunk.js +3 -0
- package/dist/scripts/6351-dff9edbb16-lite.chunk.js.map +1 -0
- package/dist/scripts/6973-c4cb114bd7-lite.chunk.js +2 -0
- package/dist/scripts/6973-c4cb114bd7-lite.chunk.js.map +1 -0
- package/dist/scripts/7210-2e4563178c-lite.chunk.js +3 -0
- package/dist/scripts/7210-2e4563178c-lite.chunk.js.map +1 -0
- package/dist/scripts/7480-3564c0c2da-lite.chunk.js +2 -0
- package/dist/scripts/7480-3564c0c2da-lite.chunk.js.map +1 -0
- package/dist/scripts/7482-13e6f78c32-lite.chunk.js +2 -0
- package/dist/scripts/7482-13e6f78c32-lite.chunk.js.map +1 -0
- package/dist/scripts/9040-be65e4eb1e-lite.chunk.js +2 -0
- package/dist/scripts/9040-be65e4eb1e-lite.chunk.js.map +1 -0
- package/dist/scripts/{bundle-90d3c7fd15.min.js → bundle-32e967af87.min.js} +3 -3
- package/dist/scripts/{bundle-90d3c7fd15.min.js.map → bundle-32e967af87.min.js.map} +1 -1
- package/package.json +1 -1
- package/dist/scripts/1210-3cbdc62b0a-lite.chunk.js +0 -2
- package/dist/scripts/1210-3cbdc62b0a-lite.chunk.js.map +0 -1
- package/dist/scripts/1239-ed9b8aadb4-lite.chunk.js +0 -3
- package/dist/scripts/1239-ed9b8aadb4-lite.chunk.js.map +0 -1
- package/dist/scripts/1386-d93ee75e0c-lite.chunk.js +0 -2
- package/dist/scripts/1386-d93ee75e0c-lite.chunk.js.map +0 -1
- package/dist/scripts/2392-acfd69dfa3-lite.chunk.js +0 -3
- package/dist/scripts/2392-acfd69dfa3-lite.chunk.js.map +0 -1
- package/dist/scripts/2636-63e5f2c9e6-lite.chunk.js +0 -2
- package/dist/scripts/2636-63e5f2c9e6-lite.chunk.js.map +0 -1
- package/dist/scripts/2640-536c550749-lite.chunk.js.map +0 -1
- package/dist/scripts/3036-d18c598435-lite.chunk.js +0 -2
- package/dist/scripts/3036-d18c598435-lite.chunk.js.map +0 -1
- package/dist/scripts/4229-75ba28a266-lite.chunk.js +0 -2
- package/dist/scripts/4229-75ba28a266-lite.chunk.js.map +0 -1
- package/dist/scripts/4266-e856b96643-lite.chunk.js +0 -3
- package/dist/scripts/4266-e856b96643-lite.chunk.js.map +0 -1
- package/dist/scripts/4598-f326dc1aec-lite.chunk.js +0 -2
- package/dist/scripts/4598-f326dc1aec-lite.chunk.js.map +0 -1
- package/dist/scripts/4845-f3646fb657-lite.chunk.js.map +0 -1
- package/dist/scripts/555-d811b49435-lite.chunk.js +0 -2
- package/dist/scripts/555-d811b49435-lite.chunk.js.map +0 -1
- package/dist/scripts/6046-44c115a89c-lite.chunk.js +0 -2
- package/dist/scripts/6046-44c115a89c-lite.chunk.js.map +0 -1
- package/dist/scripts/6188-e108abca25-lite.chunk.js.map +0 -1
- package/dist/scripts/6317-49be898c73-lite.chunk.js +0 -2
- package/dist/scripts/6317-49be898c73-lite.chunk.js.map +0 -1
- package/dist/scripts/6973-ede6601614-lite.chunk.js +0 -2
- package/dist/scripts/6973-ede6601614-lite.chunk.js.map +0 -1
- package/dist/scripts/7075-9a76ce47c9-lite.chunk.js +0 -3
- package/dist/scripts/7075-9a76ce47c9-lite.chunk.js.map +0 -1
- package/dist/scripts/7480-02bc4e08a3-lite.chunk.js +0 -2
- package/dist/scripts/7480-02bc4e08a3-lite.chunk.js.map +0 -1
- package/dist/scripts/9040-9393c59004-lite.chunk.js +0 -2
- package/dist/scripts/9040-9393c59004-lite.chunk.js.map +0 -1
- package/dist/scripts/9985-c488ab5f65-lite.chunk.js +0 -2
- package/dist/scripts/9985-c488ab5f65-lite.chunk.js.map +0 -1
- /package/dist/css/{3036-lite-1b3e9aa905.chunk.css → 3079-lite-1b3e9aa905.chunk.css} +0 -0
- /package/dist/css/{7075-lite-a377febbb0.chunk.css → 6351-lite-a377febbb0.chunk.css} +0 -0
- /package/dist/scripts/{4266-e856b96643-lite.chunk.js.LICENSE.txt → 232-1522c00252-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{1239-ed9b8aadb4-lite.chunk.js.LICENSE.txt → 2392-19e4bb187b-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{2392-acfd69dfa3-lite.chunk.js.LICENSE.txt → 6351-dff9edbb16-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{7075-9a76ce47c9-lite.chunk.js.LICENSE.txt → 7210-2e4563178c-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{bundle-90d3c7fd15.min.js.LICENSE.txt → bundle-32e967af87.min.js.LICENSE.txt} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scripts/7075-9a76ce47c9-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/apps/analytics/components/engagement-heat-map/engagement-heat-map.scss","file:///app/packages/libs/shared/src/apps/analytics/components/engagement-heat-map/EngagementHeatMap.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/insight-card/insight-card.scss","file:///app/packages/libs/shared/src/apps/analytics/components/insight-card/InsightCard.tsx","file:///app/packages/libs/shared/src/apps/analytics/constants/ChartStyles.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/AnonymiseUserUtils.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/EngagementUtils.ts","file:///app/packages/libs/shared/src/components/percentage-indicator/PercentageIndicator.tsx","file:///app/packages/libs/shared/src/components/percentage-indicator/PercentageIndicatorUtils.ts","file:///app/packages/libs/shared/src/constants/DragOverlayStyles.ts","file:///app/packages/libs/shared/src/components/table/TableUtils.ts","file:///app/packages/libs/shared/src/components/table/table.scss","file:///app/packages/libs/shared/src/components/table/Table.tsx","file:///app/packages/libs/shared/src/constants/ScoreThresholds.ts","file:///app/packages/libs/shared/src/hooks/useLockContentWidth.ts","file:///app/packages/libs/shared/src/apps/analytics/components/engagement-table/engagement-table.scss","file:///app/packages/libs/shared/src/apps/analytics/components/engagement-table/EngagementTableUtils.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/engagement-table/EngagementTable.tsx","file:///app/packages/libs/shared/src/components/percentage-indicator/PartialPercentageIndicator.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/insights/amount-watched/InsightAmountWatched.tsx","file:///app/packages/libs/shared/src/apps/analytics/utils/ChartColourUtils.ts","file:///app/packages/libs/shared/src/apps/analytics/components/insights/total-views/InsightTotalViews.tsx","file:///app/packages/libs/shared/src/apps/analytics/utils/SharedUserActivityPieChartUtils.ts","file:///app/packages/projects/lite/src/apps/my-shares/components/insights-heatmap/partial-loading/partial-insights-heatmap.scss","file:///app/packages/projects/lite/src/apps/my-shares/components/insights-heatmap/partial-loading/PartialInsightsHeatmap.tsx","file:///app/packages/projects/player/src/plugins/engagement-overlay-plugin/components/engagement-overlay-menu-item/engagement-overlay-menu-item.ts","file:///app/packages/projects/player/src/plugins/engagement-overlay-plugin/components/timepoint-interactions/timepoint-interactions.tsx","file:///app/packages/projects/player/src/plugins/engagement-overlay-plugin/components/engagement-overlay/engagement-overlay-chart-options.tsx","file:///app/packages/projects/player/src/plugins/engagement-overlay-plugin/components/engagement-overlay/engagement-overlay.ts","file:///app/packages/projects/player/src/plugins/engagement-overlay-plugin/engagement-overlay-plugin.ts","file:///app/packages/projects/player/src/plugins/interactive-plugin/interactive-seek-bar-plugin.ts","file:///app/packages/projects/player/src/players/reports/reports-player.ts","file:///app/packages/projects/player/src/react/ReportsPlayer.tsx","file:///app/packages/projects/lite/src/apps/my-shares/components/video-engagement-overlay/video-engagement-overlay.scss","file:///app/packages/projects/lite/src/apps/my-shares/components/video-engagement-overlay/VideoEngagementOverlay.tsx","file:///app/packages/projects/lite/src/apps/my-shares/components/insights-heatmap/insights-heatmap.scss","file:///app/packages/projects/lite/src/apps/my-shares/components/insights-heatmap/InsightsHeatmap.tsx","file:///app/packages/libs/shared/src/apps/analytics/utils/FilterParamUtils.ts","file:///app/packages/libs/shared/src/components/percentage-indicator/percentage-indicator.scss"],"sourcesContent":["// extracted by mini-css-extract-plugin\nexport default {\"heatMap\":\"epapa\",\"legend\":\"uhH4p\"};","import React from 'react';\nimport chroma from 'chroma-js';\n\nimport { getFullHeatMap } from 'libs/shared/apps/analytics/utils/EngagementUtils';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Engagement } from 'libs/shared/interfaces';\n\nimport styles from './engagement-heat-map.scss';\n\nconst namespace = 'shared.engagementHeatMap';\n\nconst ZERO_COLOUR = '#f1f1f1';\nconst MIN_COLOUR = '#daf07d';\nconst MAX_COLOUR = '#08bd1a';\n\nconst COLOUR_SCALE = chroma.scale([ MIN_COLOUR, MAX_COLOUR ]);\n\nconst LEGEND_VALUES = [ 0, 0.01, 0.25, 0.5, 0.75, 1 ];\n\nfunction getBackgroundColor(value: number, max: number): string {\n if (!value)\n return ZERO_COLOUR;\n\n return COLOUR_SCALE(value / max).hex();\n}\n\nfunction getGradient(data: number[], max: number): string {\n const gradient: string[] = [];\n\n for (let i = 0; i < data.length; i++) {\n const previousValue = i > 0 && data[i - 1];\n const currentValue = data[i];\n const nextValue = i < data.length - 1 && data[i + 1];\n\n /**\n * We want to capture colour changes but if a value has the same value\n * of both of its neighbours, we can skip it.\n */\n if (currentValue === previousValue && currentValue === nextValue)\n continue;\n\n gradient.push(`${getBackgroundColor(currentValue, max)} ${100 / data.length * i}%`);\n }\n\n return `linear-gradient(to right, ${gradient.join(',')})`;\n}\n\nexport function EngagementHeatMapLegend(): JSX.Element {\n const max = Math.max(...LEGEND_VALUES);\n const legendSquareWidthPercentage = 100 / LEGEND_VALUES.length;\n\n return (\n <div className='d-flex justify-content-between w-100'>\n <Text namespace={namespace} phrase='less' />\n <div className={`d-flex mx-1 flex-grow-1 ${styles.legend}`}>\n {LEGEND_VALUES.map((val, idx) => (\n <div\n key={idx}\n style={{\n width: `${legendSquareWidthPercentage}%`,\n backgroundColor: getBackgroundColor(val, max)\n }}\n />\n ))}\n </div>\n <Text namespace={namespace} phrase='more' />\n </div>\n );\n}\n\ninterface EngagementHeatMapProps {\n engagement: Engagement;\n max?: number;\n className?: string;\n}\n\nexport function EngagementHeatMap(props: EngagementHeatMapProps): JSX.Element {\n const heatMap = getFullHeatMap(props.engagement);\n const max = props.max ?? Math.max(...heatMap);\n\n return (\n <div\n className={`border rounded ${styles.heatMap} ${props.className ?? ''}`}\n style={{\n background: getGradient(heatMap, max)\n }}\n />\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"icon\":\"sAmpy\",\"count\":\"faDs4\"};","import React from 'react';\n\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\n\nimport styles from './insight-card.scss';\n\ninterface InsightCardProps extends React.PropsWithChildren {\n svgName: string;\n svgClassName: string;\n title: string;\n subtitle?: string;\n count?: number;\n}\n\nexport function InsightCard(props: InsightCardProps) {\n return (\n <section className='d-flex flex-column border rounded p-3 h-100'>\n <div className={`d-flex ${props.subtitle ? 'align-items-top' : 'align-items-center'} mb-2`}>\n <div className={`${styles.icon} ${props.svgClassName} rounded-circle d-flex justify-content-center align-items-center`}>\n <SvgContainer svgName={props.svgName} size={SvgContainerSize.Small} />\n </div>\n <div className='d-flex flex-column ms-2'>\n <h2 className='h6 mb-0'>{props.title}</h2>\n </div>\n {typeof props.count === 'number' && (\n <div className={`${styles.count} d-flex justify-content-center align-items-center bg-light rounded-circle ms-auto`}>\n {props.count}\n </div>\n )}\n </div>\n {props.children}\n </section>\n );\n}","export const CHART_FONT_STYLES = {\n fontSize: '12px',\n fontFamily: `\"Inter\",-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,\"Noto Sans\",\"Liberation Sans\",sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\"`,\n fontWeight: '400',\n color: '#313543'\n};","import { animals, colors, Config as UniqueNamesConfig, uniqueNamesGenerator } from 'unique-names-generator';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AnonSession, AnonSessions } from 'libs/shared/apps/analytics/hooks/UseAnonSessions';\nimport { UserOrAnonSession } from 'libs/shared/apps/analytics/interfaces/UserOrAnonSession';\nimport { StudentResults } from 'libs/shared/interfaces';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nconst namespace = 'shared.analyticsUtils';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getUniqueNamesConfig(id: string): UniqueNamesConfig {\n /**\n * Generate a seed that is unique to each user but changes every 5 minutes.\n * \n * We use a seed so that if the same user's name is anonymised multiple times\n * in quick succession (e.g. multiple renders), the same name will be returned each time.\n * \n * We change the seed every 5 minutes so that students don't always have the same name.\n */\n const seed = +`${id}${Math.floor((new Date()).getMinutes() / 5)}`;\n\n return {\n dictionaries: [ colors, animals ],\n separator: ' ',\n length: 2,\n style: 'capital',\n seed\n };\n}\n\nexport function anonymiseUserName(user: UserOrAnonSession, shouldAnonymise: boolean): string {\n if (!user)\n return '';\n\n if (!shouldAnonymise)\n return 'sessionId' in user ? user.sessionName : UserHelper.getFullName(user);\n\n return uniqueNamesGenerator(getUniqueNamesConfig('sessionId' in user ? user.sessionName : user.id));\n}\n\nexport function getAnonSession(sessionId: string, anonSessions: AnonSessions): AnonSession {\n const fallback = {\n sessionId: sessionId,\n sessionName: getPhrase('anonymousUser')\n };\n\n if (!sessionId || !anonSessions)\n return fallback;\n\n const anonSession = anonSessions[sessionId];\n\n if (anonSession)\n return anonSession;\n\n return fallback;\n}\n\nexport function getUserOrAnonSession(result: StudentResults, anonSessions: AnonSessions): UserOrAnonSession {\n if (result.user)\n return result.user;\n\n return getAnonSession(result.sessionId, anonSessions);\n}\n","import { Engagement } from 'libs/shared/interfaces';\n\n/**\n * The heat map in the API response won't contain trailing zeros so we need to add those\n * in manually.\n */\nexport function getFullHeatMap(engagement: Engagement): number[] {\n return (new Array(Math.ceil(engagement.videoDuration))).fill(null).map((t, idx) => engagement.heatMap[idx] || 0);\n}","import React from 'react';\n\nimport { ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\n\nimport {\n getCircleClassName,\n getCircleContainerClassName,\n getCircleRadius,\n getColouredLabelClassName,\n getFormattedPercentage,\n getPercentageToFixed,\n isPending,\n ProgressCircleSize\n} from './PercentageIndicatorUtils';\n\nimport styles from './percentage-indicator.scss';\n\ninterface ProgressCircleProps {\n size: ProgressCircleSize;\n scoreThresholds?: ScoreThresholds;\n percentage?: number;\n}\n\nfunction ProgressCircle(props: ProgressCircleProps): JSX.Element {\n const ref = React.useCallback((circle: SVGCircleElement) => {\n if (!circle)\n return;\n\n const radius = circle.r.baseVal.value;\n const circumference = 2 * Math.PI * radius;\n const offset = circumference - props.percentage * circumference;\n\n circle.style.strokeDasharray = `${circumference} ${circumference}`;\n circle.style.strokeDashoffset = offset.toString();\n }, [props.percentage]);\n\n return (\n <svg>\n <circle r={getCircleRadius(props.size)} className={styles.backgroundCircle} />\n {!isPending(props.percentage) &&\n <circle\n ref={ref}\n r={getCircleRadius(props.size)}\n className={getCircleClassName(props.percentage, props.scoreThresholds)}\n />\n }\n </svg>\n );\n}\n\nexport enum PercentageIndicatorLayout {\n CircleOnly = 'circle_only',\n LabelOnly = 'label_only',\n LabelBefore = 'label_before',\n LabelInside = 'label_inside'\n}\n\ninterface PercentageIndicatorProps {\n layout: PercentageIndicatorLayout;\n percentage?: number; // Between 0 and 1 or undefined for pending\n className?: string;\n customLabel?: string;\n scoreThresholds?: ScoreThresholds;\n size?: ProgressCircleSize;\n}\n\nPercentageIndicator.defaultProps = {\n layout: PercentageIndicatorLayout.CircleOnly\n};\n\nexport function PercentageIndicator(props: PercentageIndicatorProps): JSX.Element {\n const percentageToFixed = getPercentageToFixed(props.percentage);\n\n const size = props.size ||\n (props.layout === PercentageIndicatorLayout.LabelInside\n ? ProgressCircleSize.Large\n : ProgressCircleSize.Small\n );\n\n const label = props.customLabel || getFormattedPercentage(percentageToFixed);\n\n if (props.layout === PercentageIndicatorLayout.LabelOnly)\n return (\n <span className={getColouredLabelClassName(percentageToFixed)}>\n {label}\n </span>\n );\n\n return (\n <div className={`d-flex align-items-center justify-content-between ${props.className ?? ''}`}>\n {props.layout === PercentageIndicatorLayout.LabelBefore &&\n <span className='me-2'>\n {label}\n </span>\n }\n <div className={getCircleContainerClassName(size, percentageToFixed)}>\n <ProgressCircle percentage={percentageToFixed} size={size} scoreThresholds={props.scoreThresholds} />\n {props.layout === PercentageIndicatorLayout.LabelInside &&\n <span className={styles.centredPercentageText}>\n {label}\n </span>\n }\n </div>\n </div>\n );\n}","import { ScoreThresholdDefaults, ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\n\nimport styles from './percentage-indicator.scss';\n\n/**\n * Values for width and strokeWidth are taken from progress-circle.scss.\n * If either are changed, they must be updated in both places.\n */\nconst CIRCLE_WIDTH = 2; // rem\nconst CIRCLE_WIDTH_LG = 5.8; // rem\nconst CIRCLE_STROKE_WIDTH = 0.2; // rem\nconst CIRCLE_STROKE_WIDTH_LG = 0.36; // rem\n \nexport enum ProgressCircleSize {\n Small = 'small',\n Large = 'large',\n ExtraSmall = 'extraSmall'\n}\n\nconst ProgressCircleSizeMap = {\n [ProgressCircleSize.ExtraSmall]: {\n size: CIRCLE_WIDTH\n },\n [ProgressCircleSize.Small]: {\n size: CIRCLE_WIDTH\n },\n [ProgressCircleSize.Large]: {\n size: CIRCLE_WIDTH_LG\n }\n};\n\n/**\n * radius = width / 2 - strokeWidth * 2\n */\nexport function getCircleRadius(size: ProgressCircleSize): string {\n const width = ProgressCircleSizeMap[size].size;\n const strokeWidth = size === ProgressCircleSize.Large ? CIRCLE_STROKE_WIDTH_LG : CIRCLE_STROKE_WIDTH;\n return `${width / 2 - strokeWidth * 2}rem`;\n}\n \nexport function getCircleClassName(\n percentage: number,\n scoreThresholds: ScoreThresholds = ScoreThresholdDefaults\n): string {\n if (percentage >= scoreThresholds.HIGH)\n return styles.circleSuccess;\n \n if (percentage >= scoreThresholds.MODERATE)\n return styles.circleWarning;\n \n return styles.circleDanger;\n}\n \nexport function getColouredLabelClassName(\n percentage: number,\n scoreThresholds: ScoreThresholds = ScoreThresholdDefaults\n): string {\n if (percentage >= scoreThresholds.HIGH)\n return 'text-success';\n \n if (percentage >= scoreThresholds.MODERATE)\n return 'text-warning';\n \n return 'text-danger';\n}\n \nexport function getCircleContainerClassName(size: ProgressCircleSize, percentage?: number): string {\n let className = `d-inline-block ${styles.circleContainer}`;\n \n if (size === ProgressCircleSize.Large)\n className += ` ${styles.lgCircleContainer}`;\n\n if (size === ProgressCircleSize.ExtraSmall)\n className += ` ${styles.xsCircleContainer}`;\n\n if (isPending(percentage))\n className += ` ${styles.pendingCircle}`;\n \n return className;\n}\n\nexport function getPercentageToFixed(percentage?: number): number | undefined {\n if (isPending(percentage))\n return;\n \n return +percentage.toFixed(2);\n}\n \nexport function getFormattedPercentage(percentage?: number): string {\n if (isPending(percentage))\n return `--%`;\n\n return `${Math.round(percentage * 100)}%`;\n}\n\nexport function isPending(percentage?: number): boolean {\n return typeof percentage !== 'number';\n}","export const DragOverlayStyles = { opacity: '0.8', cursor: 'grabbing' };","import React from 'react';\nimport { PluginHook, useBlockLayout, useFilters, useFlexLayout, useGlobalFilter, useRowSelect, useSortBy } from 'react-table';\n\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { HashObject } from 'libs/common/react/interfaces';\n\ninterface PluginOptions {\n allowFiltering?: boolean;\n allowGlobalFiltering?: boolean;\n layout?: 'flex' | 'block';\n}\n\nexport function getPlugins<T extends HashObject>(props: PluginOptions): PluginHook<T>[] {\n let plugins: PluginHook<T>[] = [\n useSortBy,\n useRowSelect,\n props.layout === 'flex' ? useFlexLayout : useBlockLayout\n ];\n\n if (props.allowFiltering)\n plugins = [\n ...plugins,\n useFilters\n ];\n\n if (props.allowGlobalFiltering)\n plugins = [\n ...plugins,\n useGlobalFilter\n ];\n\n return plugins;\n}\n\nexport function getSelectedRowIds(ids: string[]): Record<string, boolean> {\n const idHash: Record<string, boolean> = {};\n\n ids.forEach(id => idHash[id] = true);\n\n return idHash;\n}\n\ninterface TableScrollState {\n canScrollLeft: boolean;\n canScrollRight: boolean;\n}\n\nfunction calculateScrollState(ref: React.MutableRefObject<HTMLDivElement>): TableScrollState {\n const canScrollLeft = ref.current?.scrollLeft > 0;\n const canScrollRight = (ref.current?.scrollLeft + 1) < ref.current?.scrollWidth - ref.current?.clientWidth;\n\n return { canScrollLeft, canScrollRight };\n}\n\ninterface UseTableScroll {\n ref: (el: HTMLDivElement) => void;\n scrollState: TableScrollState;\n scroll: (scrollBy: number) => void;\n}\n\nexport function useTableScroll(): UseTableScroll {\n const elRef = React.useRef<HTMLDivElement>(null);\n const [ scrollState, setScrollState ] = React.useState<TableScrollState>(calculateScrollState(elRef));\n\n function onScroll(): void {\n setScrollState(calculateScrollState(elRef));\n }\n\n function scroll(scrollBy: number): void {\n elRef.current?.scrollBy({ left: scrollBy, top: 0, behavior: 'smooth' });\n }\n\n const throttledOnScroll = FunctionHelper.throttle(onScroll, 200);\n\n const ref = React.useCallback((el: HTMLDivElement) => {\n if (elRef.current) {\n elRef.current?.removeEventListener('scroll', throttledOnScroll);\n }\n\n if (el) {\n setScrollState(calculateScrollState(elRef));\n el.addEventListener('scroll', throttledOnScroll);\n }\n\n elRef.current = el;\n }, []);\n\n React.useEffect(() => {\n if (elRef?.current) {\n setScrollState(calculateScrollState(elRef));\n }\n }, [elRef]);\n\n return { ref, scrollState, scroll };\n}","// extracted by mini-css-extract-plugin\nexport default {\"sortIndicator\":\"gFhu0\",\"scrollContainer\":\"sWUp9\",\"scrollbarTrack\":\"Vn2qM\"};","import React from 'react';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\nimport {\n Cell,\n Column as BaseColumn,\n HeaderGroup,\n HeaderProps as BaseHeaderProps,\n IdType,\n Row,\n SortingRule,\n TableOptions,\n TableRowProps,\n useTable } from 'react-table';\nimport { DragEndEvent } from '@dnd-kit/core';\n\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { SortableContainerWrapper } from 'libs/shared/components/sortable/SortableContainerWrapper';\nimport { PropsWithSortableItemProps, SortableItemWrapper } from 'libs/shared/components/sortable/SortableItemWrapper';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { WidgetButton, WidgetButtonDirection } from 'libs/shared/components/widgets/widget-button/WidgetButton';\nimport { DragOverlayStyles } from 'libs/shared/constants/DragOverlayStyles';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { getPlugins, getSelectedRowIds, useTableScroll } from './TableUtils';\n\nimport styles from './table.scss';\n\nexport interface TableTheme {\n table?: string;\n header?: string;\n headerRow?: string;\n headerCell?: string;\n body?: string;\n row?: string | ((row: Row<any>) => string);\n selectedRow?: string;\n cell?: string | ((row?: Row<any>, cell?: Cell<any, any>) => string);\n sortIndicator?: string;\n}\n\nexport type HeaderProps<T extends HashObject> = BaseHeaderProps<T> & {\n renderSortIndicator: () => void;\n}\n\nexport type Column<T extends HashObject> = BaseColumn<T> & {\n hideSortIndicator?: boolean;\n}\n\ninterface SortIndicatorProps<T extends HashObject> {\n column: HeaderGroup<T>;\n theme?: TableTheme;\n}\n\nfunction SortIndicator<T extends HashObject>(props: SortIndicatorProps<T>): JSX.Element {\n if (!props.column.canSort)\n return <></>;\n\n return (\n <span\n className={\n `${styles.sortIndicator}\n ${!props.column.isSorted ? 'text-secondary' : ''}\n ${props.theme?.sortIndicator ?? ''}`\n }\n >\n <SvgContainer\n svgName={(props.column.isSortedDesc || !props.column.isSorted)\n ? cvSvgLibrary.ArrowRight\n : cvSvgLibrary.ArrowLeft\n }\n size={SvgContainerSize.Small}\n />\n </span>\n );\n}\n\ninterface BaseTableProps<T extends HashObject> {\n /**\n * Must be memoized.\n */\n data: T[];\n\n /**\n * Must be memoized.\n * \n * For documentation on Column Options, see https://react-table.tanstack.com/docs/api/useTable#column-options\n */\n columns: Column<T>[];\n\n theme?: TableTheme;\n\n onSelectRow?: (row: Row<T>) => void;\n\n onSelectCell?: (cell: Cell<T>) => void;\n\n onRowMouseOver?: (row: Row<T>) => void;\n\n onRowMouseLeave?: (row: Row<T>) => void;\n\n allowSelectMultipleRows?: boolean;\n\n initialSelectedRowIds?: string[];\n\n getRowId?: (row: T) => string;\n\n getRowAppLink?: (row: Row<T>) => Core.AppLink;\n\n enableSort?: boolean;\n\n manualSort?: boolean;\n\n onSort?: (sortingRule: SortingRule<T>[]) => void;\n \n // Opt-in to utilise react-table's useFilter hook.\n allowFiltering?: boolean;\n\n // Opt-in to utilise react-table's useGlobalFilter hook.\n allowGlobalFiltering?: boolean;\n\n // Use either a flex layout or a block layout. Default is flex.\n layout?: 'flex' | 'block';\n\n // Used by useGlobalFilter hook, needs to be enabled by prop above.\n globalFilter?: string;\n\n // Set initial state of hidden columns in react-table.\n hiddenColumns?: IdType<T>[];\n\n // Determine whether hidden columns should be preserved on a table update event.\n autoResetHiddenColumns?: boolean;\n\n // Determine whether sort order state should be preserved on a table update event.\n autoResetSortBy?: boolean;\n\n // Determine whether rows are sortable by drag and drop\n enableSortableRows?: boolean;\n\n onSortingRowsEnd?: (event: DragEndEvent) => void;\n\n // Set initial state of sorting in react-table\n initialSortBy?: SortingRule<T>[];\n}\n \ntype SortableRowProps = PropsWithSortableItemProps<TableRowProps>;\n\nfunction BaseTable<T extends HashObject>(props: BaseTableProps<T>): JSX.Element {\n const tableOptions: TableOptions<T> = {\n columns: props.columns,\n data: props.data,\n disableSortBy: !props.enableSort,\n manualSortBy: props.manualSort,\n autoResetHiddenColumns: props.autoResetHiddenColumns,\n autoResetSortBy: props.autoResetSortBy,\n initialState: {\n sortBy: props.initialSortBy || []\n }\n };\n\n if (props.initialSelectedRowIds)\n tableOptions.initialState = { selectedRowIds: getSelectedRowIds(props.initialSelectedRowIds) };\n\n if (props.getRowId)\n tableOptions.getRowId = props.getRowId;\n\n const {\n getTableProps,\n getTableBodyProps,\n headerGroups,\n rows,\n prepareRow,\n toggleAllRowsSelected,\n setGlobalFilter,\n setHiddenColumns,\n state: { sortBy }\n } = useTable<T>(tableOptions, ...getPlugins<T>({ ...props }));\n\n function getTableRowsClass(row: Row<T>) {\n let className = FunctionHelper.isFunction(props.theme?.row)\n ? props.theme.row(row)\n : props.theme?.row ?? '';\n\n if (row.isSelected && props.theme?.selectedRow)\n className += ` ${props.theme?.selectedRow}`;\n\n if (props.onSelectRow)\n className += ' cursor-pointer';\n\n if (props.enableSortableRows)\n className += ' cursor-grab';\n\n return className;\n }\n\n function renderTableRows(): JSX.Element[] {\n return rows.map(row => {\n prepareRow(row);\n \n const className = getTableRowsClass(row);\n const rowAppLink = !!props.getRowAppLink && props.getRowAppLink(row);\n\n function onClickRow(): void {\n if (!props.onSelectRow)\n return;\n\n if (!props.allowSelectMultipleRows)\n toggleAllRowsSelected(false);\n \n props.onSelectRow(row);\n row.toggleRowSelected(true);\n }\n\n function getSortableProps(props: TableRowProps | PropsWithSortableItemProps<TableRowProps>, ref?: any) {\n if ('dragAttributes' in props && 'dragListeners' in props) {\n return {\n ...props.dragAttributes,\n ...props.dragListeners,\n 'aria-roledescription': 'Sortable row',\n ref\n };\n }\n\n return {};\n }\n\n function renderRow(props: TableRowProps | PropsWithSortableItemProps<TableRowProps>, ref?: any): JSX.Element {\n const sortableProps = getSortableProps(props, ref);\n\n if (rowAppLink) {\n return (\n <div\n role='row'\n key={row.id}\n >\n <AppLink\n {...props}\n {...sortableProps}\n className={className}\n appLink={rowAppLink}\n >\n {renderCells(row)}\n </AppLink>\n </div>\n );\n }\n\n return (\n <div\n {...props}\n {...sortableProps}\n key={row.id}\n role='row'\n className={className}\n onClick={onClickRow}\n >\n {renderCells(row)}\n </div>\n );\n }\n\n const rowProps = row.getRowProps();\n\n if (props.enableSortableRows) {\n return (\n <SortableItemWrapper\n id={row.original.id}\n key={row.id}\n childProps={rowProps}\n childComponent={React.forwardRef(\n (props: SortableRowProps, ref: React.LegacyRef<HTMLDivElement>) => (renderRow(props, ref))\n )}\n />\n );\n }\n\n return renderRow(rowProps);\n });\n }\n\n function getDragOverlayClassName(theme: TableTheme): string {\n let className = 'g-0 ';\n\n if (theme)\n className += theme.row;\n\n return className;\n }\n\n function getDragOverlay(id: string) {\n const rowIndex = rows.findIndex(item => item.original.id === id);\n const row = rows[rowIndex];\n \n return (\n <div\n {...props}\n className={getDragOverlayClassName(props.theme)}\n style={DragOverlayStyles}\n >\n {renderCells(row)}\n </div>\n );\n }\n\n function getCellClassName(row: Row<T>, cell: Cell<T>): string {\n let cellClassName = '';\n\n if (typeof props.theme?.cell === 'function')\n cellClassName = props.theme.cell(row, cell);\n\n if (typeof props.theme?.cell === 'string')\n cellClassName = props.theme.cell;\n\n if (props.onSelectCell)\n cellClassName += ' cursor-pointer';\n\n return cellClassName;\n }\n\n function renderCells(row: Row<T>): JSX.Element[] {\n return row.cells.map(cell => {\n const cellClassName = getCellClassName(row, cell);\n\n function onClickCell(): void {\n props.onSelectCell && props.onSelectCell(cell);\n }\n\n return (\n <div key={cell.column.id} {...cell.getCellProps()} className={cellClassName} onClick={onClickCell} >\n {cell.render('Cell')}\n </div>\n );\n });\n }\n\n React.useEffect(() => {\n if (!props.onSort)\n return;\n\n props.onSort(sortBy);\n }, [sortBy]);\n\n React.useEffect(() => {\n if (!props.globalFilter)\n return;\n\n setGlobalFilter(props.globalFilter);\n }, [props.globalFilter]);\n\n React.useEffect(() => {\n if (!props.hiddenColumns)\n return;\n\n setHiddenColumns(props.hiddenColumns);\n }, [props.hiddenColumns && props.hiddenColumns.length]);\n\n return (\n <div {...getTableProps()} className={props.theme?.table ?? ''}>\n <div className={props.theme?.header ?? ''}>\n {headerGroups.map(headerGroup => (\n <div {...headerGroup.getHeaderGroupProps()} className={props.theme?.headerRow ?? ''}>\n {headerGroup.headers.map(column => (\n <div {...column.getHeaderProps(column.getSortByToggleProps())} className={props.theme?.headerCell ?? ''}>\n {column.render('Header', { renderSortIndicator: () => <SortIndicator column={column} theme={props.theme} /> })}\n {!(column as Column<T>).hideSortIndicator &&\n <SortIndicator column={column} theme={props.theme} />\n }\n </div>\n ))}\n </div>\n ))}\n </div>\n <div {...getTableBodyProps()} className={props.theme?.body ?? ''}>\n { props.enableSortableRows ? (\n <SortableContainerWrapper\n ids={rows.map(row => row.original.id)}\n getDragOverlay={getDragOverlay}\n onSortEnd={props.onSortingRowsEnd}\n >\n {renderTableRows()}\n </SortableContainerWrapper>\n ) : (\n renderTableRows()\n )}\n </div>\n </div>\n );\n}\n\ninterface TableProps<T extends HashObject> extends BaseTableProps<T> {\n enableSlider?: boolean;\n scrollIncrement?: number;\n scrollContainerClassName?: string;\n scrollable?: boolean;\n initialSortBy?: SortingRule<T>[];\n}\n\nTable.defaultProps = {\n scrollIncrement: 250,\n scrollable: false,\n layout: 'flex'\n};\n\nexport function Table<T extends HashObject>(props: TableProps<T>): JSX.Element {\n const { enableSlider, scrollIncrement, scrollable, ...tableProps } = props;\n\n const { ref, scrollState, scroll } = useTableScroll();\n\n if (scrollable) {\n return (\n <Scrollbars\n renderTrackHorizontal={() => <div className={styles.scrollbarTrack} />}\n autoHeightMax={10000}\n autoHeight\n >\n <BaseTable {...tableProps} />\n </Scrollbars>\n );\n }\n\n if (!enableSlider)\n return <BaseTable {...tableProps} />;\n\n function onClickScroll(direction: 'left' | 'right'): void {\n scroll(scrollIncrement * (direction === 'right' ? 1 : -1));\n }\n\n return (\n <div className='mx-n4 overflow-x-hidden overflow-y-hidden'>\n <div className='px-4'>\n <div className='position-relative'>\n <WidgetButton\n direction={WidgetButtonDirection.Left}\n onClick={() => onClickScroll('left')}\n hide={!scrollState.canScrollLeft}\n />\n <div className={`${styles.scrollContainer} ${props.scrollContainerClassName}`} ref={ref}>\n <BaseTable {...tableProps } />\n </div>\n <WidgetButton\n direction={WidgetButtonDirection.Right}\n onClick={() => onClickScroll('right')}\n hide={!scrollState.canScrollRight}\n />\n </div>\n </div>\n </div>\n );\n}","export interface ScoreThresholds {\n HIGH: number;\n MODERATE: number;\n}\n\nexport const ScoreThresholdDefaults: ScoreThresholds = {\n HIGH: 0.75,\n MODERATE: 0.5\n};\n\nexport const ScoreThresholdInsights: ScoreThresholds = {\n HIGH: 0.7,\n MODERATE: 0.7\n};","import React from 'react';\n\nimport { LayoutHelper } from 'libs/shared/utils/LayoutHelper';\n\nexport function useLockContentWidth(): void {\n React.useEffect(() => {\n LayoutHelper.lockContentWidth();\n return () => LayoutHelper.unlockContentWidth();\n }, []);\n}","// extracted by mini-css-extract-plugin\nexport default {\"heatMap\":\"rwDjh\",\"avatarContainer\":\"kW4ZM\"};","import React from 'react';\nimport { Column, ColumnInstance, Row } from 'react-table';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EngagementHeatMap } from 'libs/shared/apps/analytics/components/engagement-heat-map/EngagementHeatMap';\nimport { AnonSessions } from 'libs/shared/apps/analytics/hooks/UseAnonSessions';\nimport { UserOrAnonSession } from 'libs/shared/apps/analytics/interfaces/UserOrAnonSession';\nimport { anonymiseUserName, getAnonSession } from 'libs/shared/apps/analytics/utils/AnonymiseUserUtils';\nimport { Avatar } from 'libs/shared/components/avatar/Avatar';\nimport { PercentageIndicator, PercentageIndicatorLayout } from 'libs/shared/components/percentage-indicator/PercentageIndicator';\nimport { Engagement, User } from 'libs/shared/interfaces';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nimport styles from './engagement-table.scss';\n\nconst namespace = 'shared.engagementTable';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface CellWrapperProps {\n className?: string;\n}\n\nfunction CellWrapper(props: React.PropsWithChildren<CellWrapperProps>): JSX.Element {\n return (\n <div className={`${props.className ?? ''}`}>\n {props.children}\n </div>\n );\n}\n\ninterface HeaderCellProps {\n column: ColumnInstance<EngagementTableData>;\n phraseKey: string;\n}\n\nfunction HeaderCell(props: HeaderCellProps): JSX.Element {\n return (\n <CellWrapper className={`d-inline-block ${props.column.isSorted ? 'fw-bold' : ''}`}>\n {getPhrase(props.phraseKey)}\n </CellWrapper>\n );\n}\n\nexport interface EngagementTableData extends Engagement {\n user: UserOrAnonSession;\n}\n\nfunction getMaxHeatMapValue(engagement: Engagement[]): number {\n let max = 0;\n\n engagement.forEach(e => {\n const localMax = Math.max(...e.heatMap);\n\n if (localMax > max)\n max = localMax;\n });\n\n return max;\n}\n\nfunction getUsersName(user: UserOrAnonSession, anonymiseUsers: boolean) {\n const fullName = anonymiseUserName(user, anonymiseUsers);\n const nameParts = fullName.split(' ').filter(n => !!n);\n\n return {\n name: nameParts[0],\n surname: nameParts.slice(1).join(' ')\n };\n}\n\ninterface EngagementColumnProps {\n engagement: Engagement[],\n imageCdnUrl: string;\n anonymiseUsers: boolean;\n}\n\nexport function useGetColumns(props: EngagementColumnProps): Column<EngagementTableData>[] {\n return React.useMemo(() => {\n const maxHeatMapValue = getMaxHeatMapValue(props.engagement);\n\n return [\n {\n Header: ({ column }) => <HeaderCell column={column} phraseKey='name' />,\n width: 22,\n accessor: 'user',\n sortType: (rowA: Row<EngagementTableData>, rowB: Row<EngagementTableData>) => {\n const nameA = anonymiseUserName(rowA.values.user, props.anonymiseUsers);\n const nameB = anonymiseUserName(rowB.values.user, props.anonymiseUsers);\n\n return nameA > nameB ? 1 : -1;\n },\n Cell: ({ value }) => {\n const { name, surname } = getUsersName(value, props.anonymiseUsers);\n return (\n <CellWrapper className='d-flex align-items-center h-100'>\n <span className={styles.avatarContainer}>\n <Avatar\n imageCdnUrl={props.imageCdnUrl}\n initials={UserHelper.getInitials(name, surname)}\n imageUrl={!props.anonymiseUsers && 'avatar' in value ? value.avatar?.url : null}\n showAnonymousUser={'sessionId' in value}\n />\n </span>\n <span className={'ms-2 clamp-1'}>\n {name} {surname}\n </span>\n </CellWrapper>\n );\n }\n },\n {\n Header: ({ column }) => <HeaderCell column={column} phraseKey='views' />,\n accessor: 'viewCount',\n width: 15,\n sortType: 'basic', // Default is 'alphanumeric' which would treat the numbers as strings\n sortDescFirst: true,\n Cell: ({ value }) => (\n <CellWrapper className='d-flex align-items-center h-100'>\n <div>{value}</div>\n </CellWrapper>\n )\n },\n {\n Header: ({ column }) => <HeaderCell column={column} phraseKey='engagement' />,\n accessor: 'engagementRate',\n width: 20,\n sortType: 'basic', // Default is 'alphanumeric' which would treat the numbers as strings\n sortDescFirst: true,\n Cell: ({ value }) => (\n <CellWrapper className='w-33'>\n <PercentageIndicator\n percentage={value}\n layout={PercentageIndicatorLayout.LabelBefore}\n />\n </CellWrapper>\n )\n },\n {\n Header: ({ column }) => <HeaderCell column={column} phraseKey='heatMap' />,\n accessor: 'heatMap',\n width: 48,\n disableSortBy: true,\n Cell: ({ row: { original } }) => (\n <CellWrapper className='d-flex align-items-center h-100'>\n <EngagementHeatMap\n engagement={original}\n max={maxHeatMapValue}\n className={`${styles.heatMap} flex-grow-1`}\n />\n </CellWrapper>\n )\n }\n ];\n }, [props.anonymiseUsers]);\n}\n\nexport function useGetTableData(\n engagement: Engagement[],\n users: User[],\n anonSessions: AnonSessions\n): EngagementTableData[] {\n return React.useMemo(() => {\n const data: EngagementTableData[] = [];\n\n engagement.forEach(e => {\n const user = users?.find(u => u.id === e.userId);\n\n // Omit deleted users\n if (user)\n data.push({ ...e, user });\n else if (e.sessionId)\n data.push({ ...e, user: getAnonSession(e.sessionId, anonSessions) });\n });\n\n return data;\n }, [users?.length]);\n}","import React from 'react';\n\nimport { AnonSessions } from 'libs/shared/apps/analytics/hooks/UseAnonSessions';\nimport { Table, TableTheme } from 'libs/shared/components/table/Table';\nimport { Engagement, User } from 'libs/shared/interfaces';\n\nimport { useGetColumns, useGetTableData } from './EngagementTableUtils';\n\nconst theme: TableTheme = {\n table: 'bg-white rounded px-0',\n header: 'border-bottom',\n headerCell: 'm-3',\n cell: 'mx-3 my-2'\n};\n\ninterface EngagementTableProps {\n engagement: Engagement[];\n imageCdnUrl: string;\n users?: User[];\n anonymiseUsers: boolean;\n border?: boolean;\n anonSessions?: AnonSessions;\n}\n\nexport function EngagementTable(props: EngagementTableProps): JSX.Element {\n const columns = useGetColumns({\n engagement: props.engagement,\n imageCdnUrl: props.imageCdnUrl,\n anonymiseUsers: props.anonymiseUsers\n });\n\n const data = useGetTableData(props.engagement, props.users, props.anonSessions);\n\n if (!data.length)\n return <></>;\n\n return (\n <Table\n columns={columns}\n data={data}\n theme={{\n ...theme,\n table: props.border ? `${theme.table} border` : theme.table\n }}\n enableSort\n />\n );\n}","import React from 'react';\n\nimport { PercentageIndicator, PercentageIndicatorLayout } from './PercentageIndicator';\n\ninterface PartialPercentageIndicatorProps {\n layout: PercentageIndicatorLayout;\n className?: string;\n}\n\nexport function PartialPercentageIndicator(props: PartialPercentageIndicatorProps): JSX.Element {\n return (\n <PercentageIndicator\n layout={props.layout}\n className={props.className}\n percentage={0}\n customLabel='--%'\n />\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { InsightCard } from 'libs/shared/apps/analytics/components/insight-card/InsightCard';\nimport { FilterQueryParams } from 'libs/shared/apps/analytics/interfaces/FilterQueryParams';\nimport { PartialPercentageIndicator } from 'libs/shared/components/percentage-indicator/PartialPercentageIndicator';\nimport { PercentageIndicator, PercentageIndicatorLayout } from 'libs/shared/components/percentage-indicator/PercentageIndicator';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Engagement } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'shared.insightAmountWatched';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface InsightAmountWatchedProps {\n engagement: Engagement;\n params: FilterQueryParams;\n}\n\nexport function InsightAmountWatched(props: InsightAmountWatchedProps) {\n const engagementRate = props.engagement?.engagementRate > 0 ? props.engagement.engagementRate : null;\n const percentage = Math.round(props.engagement.engagementRate * 100);\n\n const everyoneSelected = !props.params.users\n && !props.params.classrooms\n && !props.params.classroomGroups;\n\n return (\n <InsightCard\n title={getPhrase('title')}\n svgName={cvSvgLibrary.Timer}\n svgClassName='bg-light-green text-green'\n >\n <div className='d-flex flex-column align-items-center my-auto gap-2'>\n {!!props.engagement &&\n <>\n <PercentageIndicator\n percentage={engagementRate}\n layout={PercentageIndicatorLayout.LabelInside}\n />\n <p className='text-center'>\n {typeof engagementRate === 'number'\n ? everyoneSelected ?\n <Text namespace={namespace} phrase='everyoneWatched' options={{ percentage }} />\n : <Text namespace={namespace} phrase='usersWatched' options={{ percentage }} />\n : <Text namespace={namespace} phrase='notWatched' />\n }\n </p>\n </>\n }\n {!props.engagement &&\n <>\n <PartialPercentageIndicator layout={PercentageIndicatorLayout.LabelInside} />\n </>\n }\n </div>\n </InsightCard>\n );\n}","const CHART_COLOURS = [\n '#FF9300', // Pizazz\n '#38A2E8', // Picton Blue\n '#7A76E8', // Portage\n '#B679C7', // East Side\n '#F7847B', // Froly\n '#D9584F', // Red (Not in the Primary palette)\n '#FFCD52', // Yellow (Not in the Primary Palette)\n '#5DC786', // Emerald\n '#40BCC3', // Perolous\n '#40C2BB' // Puerto rico\n];\n\nexport function mixinSeriesColours<T>(data: T[]): T[] {\n return data.map((d, idx) => ({\n ...d,\n color: CHART_COLOURS[idx % CHART_COLOURS.length]\n }));\n}","import React from 'react';\nimport Highcharts from 'highcharts';\nimport HighchartsReact from 'highcharts-react-official';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { InsightCard } from 'libs/shared/apps/analytics/components/insight-card/InsightCard';\nimport { CHART_FONT_STYLES } from 'libs/shared/apps/analytics/constants/ChartStyles';\nimport { VideoViewEventResponse } from 'libs/shared/apps/analytics/interfaces/VideoViewEvent';\nimport { getTotalEventCount, groupEvents, sortByYearGroup } from 'libs/shared/apps/analytics/utils/SharedUserActivityPieChartUtils';\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'shared.insightTotalViews';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst STATIC_CHART_OPTIONS: Highcharts.Options = {\n title: {\n text: null\n },\n credits: {\n enabled: false\n },\n chart: {\n backgroundColor: 'transparent',\n spacing: [ 0, 0, 0, 0 ]\n },\n legend: {\n itemStyle: CHART_FONT_STYLES,\n itemDistance: 8\n },\n plotOptions: {\n pie: {\n allowPointSelect: true,\n cursor: 'pointer',\n dataLabels: {\n enabled: false\n },\n showInLegend: true,\n borderWidth: 0,\n size: '80%'\n }\n }\n};\n\ninterface InsightTotalViewsProps {\n events: VideoViewEventResponse;\n emptyStateImage: string;\n}\n\nexport function InsightTotalViews(props: InsightTotalViewsProps) {\n const chartData = sortByYearGroup(groupEvents(props.events, 'yearGroupCount', [], getSeriesName));\n const totalViews = getTotalEventCount(chartData);\n\n function getChartOptions(\n data: Highcharts.PointOptionsObject[]\n ): Highcharts.Options {\n return {\n ...STATIC_CHART_OPTIONS,\n series: [{\n type: 'pie',\n name: getPhrase('title'),\n data\n }]\n };\n }\n\n function getSeriesName(group: string): string {\n return group === 'Unknown' ? 'Staff' : group;\n }\n\n return (\n <InsightCard\n title={getPhrase('title')}\n // Replace with ultra marine + light colour\n svgClassName='bg-light-blue text-blue'\n // Add visibility icon \n svgName={cvSvgLibrary.VisibleOn}\n >\n {chartData?.length ? (\n <>\n <p className='mb-0'><Text namespace={namespace} phrase='totalViews' options={{ totalViews }} /></p>\n\n <div className='d-flex justify-content-center h-75'>\n <HighchartsReact\n highcharts={Highcharts}\n options={getChartOptions(chartData)}\n containerProps={{\n className: `w-100`\n }}\n />\n </div>\n </>\n ) : (\n <EmptyState className='pt-0 my-auto'>\n <EmptyState.Image src={props.emptyStateImage} className='w-75 h-auto'></EmptyState.Image>\n <EmptyState.Heading className='h4'><Text namespace={namespace} phrase='noViews' /></EmptyState.Heading>\n <EmptyState.Info className='w-100'><Text namespace={namespace} phrase='notWatched' /></EmptyState.Info>\n </EmptyState>\n )}\n </InsightCard>\n );\n}","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { HashObject } from 'libs/analytics/interfaces';\n\nimport { BaseAnalyticsEventResponse, GroupedAnalyticsCount } from 'libs/shared/apps/analytics/interfaces/BaseAnalyticsEvent';\nimport { UnionEventResponse } from 'libs/shared/apps/analytics/interfaces/UnionEvent';\nimport { VideoViewEventResponse } from 'libs/shared/apps/analytics/interfaces/VideoViewEvent';\nimport { mixinSeriesColours } from 'libs/shared/apps/analytics/utils/ChartColourUtils';\n\ntype EventResponseGroupByAttributes = keyof Pick<VideoViewEventResponse, 'contentTypeCount'>\n | keyof Pick<BaseAnalyticsEventResponse, 'userTypeCount' | 'yearGroupCount'>;\n\nexport function groupEvents(\n events: UnionEventResponse,\n groupBy: EventResponseGroupByAttributes,\n groupsToOmit?: string[],\n getSeriesName?: (group: string) => string\n): Highcharts.PointOptionsObject[] {\n const groups: HashObject<number> = {};\n\n const eventCounts = events[groupBy as keyof UnionEventResponse] as GroupedAnalyticsCount[];\n\n eventCounts?.forEach(ev => {\n if (!ev.name || groupsToOmit?.includes(ev.name.toLowerCase()))\n return;\n\n groups[ev.name] = groups[ev.name] ?? 0;\n groups[ev.name] += ev.count;\n });\n\n return mixinSeriesColours(ArrayHelper.sortBy(Object.keys(groups).map(group => ({\n name: getSeriesName ? getSeriesName(group) : group,\n y: groups[group],\n type: 'pie'\n })), 'name'));\n}\n\nexport function sortByYearGroup(data: Highcharts.PointOptionsObject[]) {\n const staffIndex = data.findIndex(group => group.name === 'Staff');\n\n // Move Staff to last index\n if (staffIndex > -1) {\n const [staffObject] = data.splice(staffIndex, 1);\n\n data.push(staffObject);\n }\n return data.sort((a, b) => {\n const numA = parseInt((a.name as string).match(/\\d+/)?.[0]);\n const numB = parseInt((b.name as string).match(/\\d+/)?.[0]);\n return numA - numB;\n });\n}\n\nexport function getTotalEventCount(data?: Highcharts.PointOptionsObject[]): number | null {\n return data?.reduce((a, b) => a + b.y, 0) ?? null;\n}","// extracted by mini-css-extract-plugin\nexport default {\"partialInsights\":\"nKLWa\",\"videoContainer\":\"WF2iA\"};","import React from 'react';\n\nimport styles from './partial-insights-heatmap.scss';\n\nexport function PartialInsightsHeatmap() {\n return (\n <div>\n <div className='row g-3 mb-3'>\n <div className='col'>\n <div className={`${styles.partialInsights} rounded partial-loading-background`}></div>\n </div>\n <div className='col'>\n <div className={`${styles.partialInsights} rounded partial-loading-background`}></div>\n </div>\n <div className={styles.videoContainer}>\n <div className={`${styles.partialInsights} rounded partial-loading-background`}></div>\n </div>\n </div>\n\n <div className='row g-3 mb-5'>\n <div className='col-12'>\n <div className={`${styles.partialInsights} rounded partial-loading-background`}></div>\n </div>\n </div>\n </div>\n );\n}","import videojs, { VideoJsPlayer } from 'video.js';\n\nconst MenuItem = videojs.getComponent('MenuItem');\n\ninterface EngagementOverlayMenuItemOptions extends videojs.MenuItemOptions {\n overlayVisible: boolean\n}\n\nexport class EngagementOverlayMenuItem extends MenuItem {\n private toggleEl: Element;\n private overlayVisible: boolean;\n\n /**\n * Because we want to bind our listener in createEl\n * and createEl runs in super. We store if we've bounud\n * our handler, so we only call bind once and \n * the call to removeEventListener will still work\n */\n private handlerBound: boolean;\n\n constructor(player: VideoJsPlayer, options: EngagementOverlayMenuItemOptions) {\n super(player, options);\n\n this.overlayVisible = options.overlayVisible;\n this.toggle(this.overlayVisible);\n }\n\n public handleToggle(): void {\n this.toggle(!this.overlayVisible);\n }\n\n private toggle(state: boolean): void {\n state ? this.toggleOn() : this.toggleOff();\n }\n\n private toggleOn(): void {\n videojs.dom.addClass(this.toggleEl, 'on');\n this.overlayVisible = true;\n this.player().engagementOverlayPlugin().toggleOverlay(this.overlayVisible);\n this.player().addClass('cv-reports-player-overlay-visible');\n }\n\n private toggleOff(): void {\n videojs.dom.removeClass(this.toggleEl, 'on');\n this.overlayVisible = false;\n this.player().engagementOverlayPlugin().toggleOverlay(this.overlayVisible);\n this.player().removeClass('cv-reports-player-overlay-visible');\n }\n\n /**\n * Because we extend MenuItem which will close the menu by default\n * we need to halt the event propogation here\n */\n public handleClick(event: videojs.EventTarget.Event): void {\n event.stopImmediatePropagation();\n }\n\n public createEl(tagName?: string, properties?: any, attributes?: any): HTMLLIElement {\n /**\n * Bind our event listener only once\n * see the comment where handlerBound is defined\n */\n if (!this.handlerBound) {\n this.handleToggle = this.handleToggle.bind(this);\n this.handlerBound = true;\n }\n\n if (this.toggleEl)\n this.toggleEl.removeEventListener('click', this.handleToggle);\n\n this.toggleEl = videojs.dom.createEl('div', {\n className: `custom-toggle custom-toggle-info toggle-option float-end`,\n innerHTML: '<span class=\"handle\"></span></div>'\n });\n this.toggleEl.addEventListener('click', this.handleToggle);\n\n const innerHTML = `\n <span class=\"vjs-menu-item-text\">Heat Map</span>\n <span class=\"cv-toggle-container\"></span>`;\n\n const el = super.createEl(tagName, {\n className: 'vjs-menu-item cv-cog-menu-item',\n innerHTML\n }, attributes);\n\n /**\n * Indexing into the child this way is only safe to do because\n * we know that the el only has two children\n */\n el.children[1].appendChild(this.toggleEl);\n\n return el;\n }\n}\n\nvideojs.registerComponent('EngagementOverlayMenuItem', EngagementOverlayMenuItem);\n","import React from 'react';\n\nimport { InteractionLabel } from 'libs/shared/components/interactive-questions/InteractionLabel';\nimport { Interactive } from 'libs/shared/interfaces';\n\nconst MAX_INTERACTIONS_TO_SHOW = 3;\n\ninterface TimepointInteractionsProps {\n interactive: Interactive;\n time: number;\n}\n\nexport function TimepointInteractions(props: TimepointInteractionsProps): JSX.Element {\n const timepoint = props.interactive.timepoints.find(t => {\n const timepointTime = t.visibleAt / 1000;\n \n return Math.floor(props.time) === Math.floor(timepointTime)\n || Math.ceil(props.time) === Math.ceil(timepointTime);\n });\n\n if (!timepoint?.interactions?.length)\n return <></>;\n\n const interactions = timepoint.interactions.length > MAX_INTERACTIONS_TO_SHOW\n ? timepoint.interactions.slice(0, MAX_INTERACTIONS_TO_SHOW - 1)\n : timepoint.interactions;\n\n const hiddenInteractions = timepoint.interactions.length - interactions.length;\n\n return (\n <div className='d-flex justify-content-end ms-2'>\n {interactions.map((i, idx) => (\n <InteractionLabel\n key={idx}\n interaction={i}\n showQuestion={false}\n iconClassName='ms-1'\n />\n ))}\n {!!hiddenInteractions &&\n <div\n className={'interaction-type-icon d-flex justify-content-center'\n + ' align-items-center border border-dark text-body ms-1'}\n >\n {`+${hiddenInteractions}`}\n </div>\n }\n </div>\n );\n}","import React from 'react';\nimport { renderToStaticMarkup } from 'react-dom/server';\nimport Highcharts from 'highcharts';\n\nimport { Interactive } from 'libs/shared/interfaces';\n\nimport { TimepointInteractions } from 'projects/player/plugins/engagement-overlay-plugin/components/timepoint-interactions/timepoint-interactions';\nimport { formatTime } from 'projects/player/utils/formatTime';\n\nexport const STATIC_CHART_OPTIONS: Highcharts.Options = {\n title: {\n text: null\n },\n xAxis: {\n visible: false,\n minPadding: 0,\n maxPadding: 0\n },\n legend: {\n enabled: false\n },\n credits: {\n enabled: false\n },\n defs: {\n gradient: ({\n tagName: 'linearGradient',\n id: 'area-gradient',\n x1: 0,\n y1: 1,\n x2: 0,\n y2: 0,\n children: [\n ({\n tagName: 'stop',\n offset: 0\n } as Highcharts.ASTNode),\n ({\n tagName: 'stop',\n offset: 1\n } as Highcharts.ASTNode)\n ]\n } as Highcharts.ASTNode)\n }\n};\n\nexport function getChartOptions(width: number, height: number): Highcharts.ChartOptions {\n return {\n styledMode: true,\n spacing: [ 15, 0, 0, 0 ],\n width,\n height\n };\n}\n\nexport function getYAxisChartOptions(heatMap: number[]): Highcharts.YAxisOptions {\n const maxValue = Math.max(...heatMap);\n\n return {\n /**\n * To prevent max values from being cut off, we pad them relative to the chart scale.\n */\n max: maxValue * 1.05,\n min: 0,\n minPadding: 0,\n maxPadding: 0,\n allowDecimals: true,\n startOnTick: false,\n endOnTick: false,\n visible: false\n };\n}\n\nexport function getTooltipOptions(interactive?: Interactive): Highcharts.TooltipOptions {\n return {\n formatter: function () {\n const timepointInteractionsHtml = interactive\n ? getTimepointInteractionsHtml(interactive, this.x)\n : '';\n\n return (\n '<div class=\"cv-engagement-tooltip bg-white rounded\">'\n + '<div class=\"d-flex justify-content-between\">'\n + `<strong>${formatTime(this.x)}</strong>`\n + `${timepointInteractionsHtml}`\n + '</div>'\n + '<div class=\"d-flex justify-content-between rounded bg-light cv-view-count-container\">'\n + `<strong>Views</strong> <span class=\"cv-view-count\">${this.y}</span>`\n + '</div>'\n + '</div>'\n );\n },\n positioner: function (\n labelWidth: number,\n labelHeight: number,\n point: Highcharts.TooltipPositionerPointObject\n ) {\n const minX = 0;\n const maxX = this.chart.plotWidth - labelWidth;\n const x = point.plotX - labelWidth / 2;\n \n return {\n // Clamp x between min and max\n x: Math.min(Math.max(x, minX), maxX),\n y: this.chart.plotTop\n };\n },\n useHTML: true,\n padding: 0\n };\n}\n\nexport function getPlotOptions(moveTimepointIndicator: (x: number | null) => void): Highcharts.PlotOptions {\n return {\n area: {\n point: {\n events: {\n mouseOver: function () {\n moveTimepointIndicator(this.x);\n },\n mouseOut: function () {\n moveTimepointIndicator(null);\n }\n }\n }\n },\n series: {\n marker: {\n enabled: false\n }\n }\n };\n}\n\nfunction getTimepointInteractionsHtml(interactive: Interactive, time: number): string {\n return renderToStaticMarkup(\n <TimepointInteractions time={time} interactive={interactive} />\n );\n}","import Highcharts from 'highcharts';\nimport videojs, { VideoJsPlayer } from 'video.js';\n\nimport { Interactive } from 'libs/shared/interfaces';\n\nimport {\n getChartOptions,\n getPlotOptions,\n getTooltipOptions,\n getYAxisChartOptions,\n STATIC_CHART_OPTIONS\n} from './engagement-overlay-chart-options';\n\nimport './engagement-overlay.scss';\n\nconst Component = videojs.getComponent('Component');\n\nHighcharts.AST.allowedTags.push('g');\nHighcharts.AST.allowedAttributes.push('viewBox', 'transform');\n\ninterface ChartDimensions {\n width: number;\n height: number;\n}\n\ninterface EngagementOverlayOptions extends videojs.ComponentOptions {\n heatMap: number[];\n interactive?: Interactive;\n onTimepointHover?: (time: number | null) => void;\n}\n\nexport class EngagementOverlay extends Component {\n public options_: EngagementOverlayOptions;\n private chart: Highcharts.Chart;\n\n constructor(player: VideoJsPlayer, options: EngagementOverlayOptions) {\n super(player, options);\n\n this.initialize();\n this.bindListeners();\n }\n\n public initialize(): void {\n this.player().ready(() => this.buildChart());\n }\n\n public buildCSSClass(): string {\n return 'cv-engagement-overlay';\n }\n\n public createEl(tagName?: string, properties?: any, attributes?: any): Element {\n const innerHTML = '<div class=\"cv-engagement-chart\"></div>'\n + '<div class=\"cv-engagement-timepoint-indicator\"></div>';\n\n return super.createEl(tagName, {\n ...properties,\n className: this.buildCSSClass(),\n innerHTML\n }, attributes);\n }\n\n public toggleChart(show: boolean): void {\n if (show)\n this.buildChart();\n else\n this.destroyChart();\n }\n\n private bindListeners(): void {\n this.handleClick = this.handleClick.bind(this);\n this.resizeChart = this.resizeChart.bind(this);\n\n this.player().on('playerresize', this.resizeChart);\n\n this.on(this.el(), 'mouseup', this.handleClick);\n\n this.player().on('dispose', () => {\n this.player().off('playerresize', this.resizeChart);\n\n this.off(this.el(), 'mouseup', this.handleClick);\n });\n }\n\n private handleClick(event: videojs.EventTarget.Event): void {\n if (!videojs.dom.isSingleLeftClick(event))\n return;\n\n if (this.player().paused()) {\n this.player().play();\n return;\n }\n\n this.player().pause();\n }\n\n private buildChart(): void {\n if (this.chart)\n return;\n\n const chartDimensions = this.getChartDimensions();\n\n /**\n * The dimensions calculation relies on the control bar and progress control\n * being visible, so if it isn't, we wait for the play event.\n */\n if (!chartDimensions) {\n this.player().one('play', () => this.buildChart());\n return;\n }\n\n const container: HTMLElement = this.el().querySelector('.cv-engagement-chart');\n\n this.chart = Highcharts.chart(container, this.getHighchartOptions(chartDimensions));\n }\n\n private resizeChart(): void {\n const chartDimensions = this.getChartDimensions();\n\n if (!this.chart || !chartDimensions)\n return;\n\n this.chart.setSize(chartDimensions.width, chartDimensions.height);\n }\n\n private destroyChart(): void {\n this.chart?.destroy();\n this.chart = null;\n }\n\n private getChartDimensions(): ChartDimensions {\n const collapserator = this.player().getChild('collapserator');\n const collapseratorHeight = collapserator?.currentHeight();\n\n const width = this.el().clientWidth;\n\n if (!collapseratorHeight || !width)\n return null;\n\n const { height } = this.player().currentDimensions();\n \n return {\n width,\n height: height - collapseratorHeight\n };\n }\n\n private getHighchartOptions({ width, height }: ChartDimensions): Highcharts.Options {\n return {\n ...STATIC_CHART_OPTIONS,\n chart: getChartOptions(width, height),\n yAxis: getYAxisChartOptions(this.options_.heatMap),\n tooltip: getTooltipOptions(this.options_.interactive),\n plotOptions: getPlotOptions(this.moveTimepointIndicator.bind(this)),\n series: [{\n type: 'area',\n data: this.options_.heatMap\n }]\n };\n }\n\n private moveTimepointIndicator(x: number | null): void {\n if (this.options_.onTimepointHover)\n this.options_.onTimepointHover(x);\n\n const indicator: HTMLDivElement = this.el().querySelector('.cv-engagement-timepoint-indicator');\n\n if (x === null) {\n videojs.dom.removeClass(indicator, 'cv-engagement-timepoint-indicator-visible');\n return;\n }\n\n videojs.dom.addClass(indicator, 'cv-engagement-timepoint-indicator-visible');\n indicator.style.left = `${x / this.options_.heatMap.length * 100}%`;\n }\n}\n\nvideojs.registerComponent('EngagementOverlay', EngagementOverlay);","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { Interactive } from 'libs/shared/interfaces';\n\nimport { CogButton } from 'projects/player/components/cog-button/cog-button';\nimport { EngagementOverlay } from 'projects/player/plugins/engagement-overlay-plugin/components/engagement-overlay/engagement-overlay';\nimport { EngagementOverlayMenuItem } from 'projects/player/plugins/engagement-overlay-plugin/components/engagement-overlay-menu-item/engagement-overlay-menu-item';\n\nimport 'projects/player/plugins/engagement-overlay-plugin/components/engagement-overlay/engagement-overlay';\n\nconst Plugin = videojs.getPlugin('plugin');\n\ninterface EngagementOverlayPluginOptions {\n heatMap: number[];\n interactive?: Interactive;\n onTimepointHover?: (time: number | null) => void;\n}\n\nclass EngagementOverlayPlugin extends Plugin {\n private options: EngagementOverlayPluginOptions;\n\n constructor(player: VideoJsPlayer, options: EngagementOverlayPluginOptions) {\n super(player, options);\n\n this.options = options;\n\n player.ready(() => {\n this.initialize();\n });\n }\n \n private initialize(): void {\n if (!this.hasHeatMapData())\n return;\n\n this.player.addChild('engagementOverlay', {\n heatMap: this.options.heatMap,\n interactive: this.options.interactive,\n onTimepointHover: this.options.onTimepointHover\n });\n\n const cogButton = this.player.getChild('collapserator')?.getChild('cogButton') as CogButton;\n cogButton.addItem({\n index: 0,\n ctor: EngagementOverlayMenuItem,\n name: 'EngagementOverlayMenuItem',\n options: { overlayVisible: true }\n });\n }\n\n public toggleOverlay(show: boolean): void {\n const engagementOverlay = this.player.getChild('engagementOverlay') as EngagementOverlay;\n engagementOverlay?.toggleChart(show);\n }\n\n private hasHeatMapData(): boolean {\n return this.options.heatMap?.reduce((acc, val) => acc + val, 0) > 0;\n }\n}\n\nvideojs.registerPlugin('engagementOverlayPlugin', EngagementOverlayPlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n engagementOverlayPlugin(options?: EngagementOverlayPluginOptions): EngagementOverlayPlugin;\n }\n}","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { Interactive } from 'libs/shared/interfaces';\n\nimport { InteractiveBarItems } from 'projects/player/plugins/interactive-plugin/components/seek-bar/interactive-bar-items';\nimport { TrackHelper } from 'projects/player/utils/track-helper';\n\nimport './interactive-plugin-styles.scss';\n\nconst Plugin = videojs.getPlugin('plugin');\n\ninterface InteractiveSeekBarPluginOptions {\n interactive: Interactive;\n}\n\n/**\n * This plugin will just render the interactive seek bar (i.e. just the interaction markers).\n * The user won't be able to interact with any of the interactions.\n * Currently this is just used in reports-player\n */\nclass InteractiveSeekBarPlugin extends Plugin {\n private options: InteractiveSeekBarPluginOptions;\n\n constructor(player: VideoJsPlayer, options: InteractiveSeekBarPluginOptions) {\n super(player);\n\n this.options = options;\n\n this.player.one('loadedmetadata', () => this.player.ready(this.initialize.bind(this)));\n }\n\n private initialize(): void {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n TrackHelper.useTrack(this.player, 'metadata', 'interactive', this.onTrackLoaded.bind(this));\n\n this.player.addClass('cv-interactive-plugin');\n }\n\n private onTrackLoaded(track: TextTrack): void {\n this.addChildren(track);\n }\n\n private addChildren(track: TextTrack): void {\n const seekBar = this.player.controlBar.getChild('progressControl').getChild('SeekBar');\n\n seekBar.addChild(new InteractiveBarItems(this.player, {\n interactive: this.options.interactive,\n track\n }));\n }\n}\n\nvideojs.registerPlugin('interactiveSeekBarPlugin', InteractiveSeekBarPlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n interactiveSeekBarPlugin(options?: InteractiveSeekBarPluginOptions): InteractiveSeekBarPlugin;\n }\n}","import { Interactive } from 'libs/shared/interfaces';\n\nimport { ClipData } from 'projects/player/interfaces/models/ClipData';\nimport { PlaybackObject } from 'projects/player/interfaces/models/PlaybackObject';\nimport { BasePlayer, BasePlayerOptions } from 'projects/player/players/base-player';\nimport { AnalyticsPlayerType } from 'projects/player/services/analytics-service';\nimport { InteractiveTrackHelper } from 'projects/player/utils/interactive-track-helper';\n\nimport './reports-player.scss';\n\nimport 'projects/player/plugins/engagement-overlay-plugin/engagement-overlay-plugin';\nimport 'projects/player/plugins/clip-plugin/clip-plugin';\nimport 'projects/player/plugins/interactive-plugin/interactive-seek-bar-plugin';\n\nexport interface ReportsPlayerOptions extends BasePlayerOptions {\n heatMap: number[];\n onTimepointHover?: (time: number | null) => void;\n}\n\nexport class ReportsPlayer extends BasePlayer {\n protected options: ReportsPlayerOptions;\n private track: TextTrack;\n\n constructor(id: string | Element, options: ReportsPlayerOptions) {\n super(id, options);\n }\n\n protected getPlayerClassName(): string {\n return 'cv-reports-player';\n }\n\n protected getAnalyticsPlayerType(): AnalyticsPlayerType {\n return 'reports-player';\n }\n\n protected async additionalSetup(playbackObject: PlaybackObject): Promise<void> {\n super.additionalSetup(playbackObject);\n\n this.setupEngagementOverlayPlugin(playbackObject);\n this.setupUpClipPlugin(playbackObject);\n this.setupInteractiveSeekBarPlugin(playbackObject);\n }\n\n private setupEngagementOverlayPlugin(playbackObject: PlaybackObject): void {\n this.player.engagementOverlayPlugin({\n heatMap: this.options.heatMap,\n interactive: playbackObject.additionalData?.interactive as Interactive,\n onTimepointHover: this.options.onTimepointHover\n });\n }\n\n private setupUpClipPlugin(playbackObject: PlaybackObject): void {\n const isClip = playbackObject.mediaType === 'MasterClip';\n const isInteractive = playbackObject.mediaType === 'MasterInteractive';\n\n if (!isClip && !isInteractive)\n return;\n\n let clipData: ClipData;\n if (isClip)\n clipData = playbackObject.additionalData;\n \n if (isInteractive) {\n clipData = playbackObject.additionalData?.clipData;\n\n // Not all interactives will have clip data\n if (!clipData)\n return;\n }\n\n if (!clipData)\n throw Error('Invalid clip data');\n\n this.player.clipPlugin({\n startTime: clipData.startTime,\n endTime: clipData.endTime\n });\n }\n\n private setupInteractiveSeekBarPlugin(playbackObject: PlaybackObject): void {\n const interactive = playbackObject.additionalData?.interactive as Interactive;\n\n if (!playbackObject.additionalData?.interactive)\n return;\n\n this.track = InteractiveTrackHelper.getInteractiveTrack(this.player, playbackObject);\n\n this.player.interactiveSeekBarPlugin({ interactive });\n }\n\n protected getSeekBarOptions(): any {\n return {\n ignoreChapters: true\n };\n }\n}\n","import React from 'react';\n\nimport { ReportsPlayer, ReportsPlayerOptions } from 'projects/player/players/reports/reports-player';\n\nexport function ClickViewReportsPlayer(props: ReportsPlayerOptions): React.ReactElement {\n const ref = React.useRef(null);\n const playerRef = React.useRef<ReportsPlayer>(null);\n\n React.useEffect(() => {\n playerRef.current = new ReportsPlayer(ref.current, props);\n }, []);\n\n return (\n <div ref={ref}></div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"playerContainer\":\"fGWsk\",\"playerPlaceholder\":\"v1MjE\",\"heatMap\":\"lp1Yn\",\"heatMapTimepointIndicator\":\"yOOK6\",\"heatMapTimepointIndicatorVisible\":\"rTXmB\",\"partialLoadingContainer\":\"gW1HU\"};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EngagementHeatMap, EngagementHeatMapLegend } from 'libs/shared/apps/analytics/components/engagement-heat-map/EngagementHeatMap';\nimport { getFullHeatMap } from 'libs/shared/apps/analytics/utils/EngagementUtils';\nimport { Engagement } from 'libs/shared/interfaces';\n\nimport { ClickViewReportsPlayer } from 'projects/player/react/ReportsPlayer';\n\nimport styles from './video-engagement-overlay.scss';\n\nconst namespace = 'shared.videoEngagementOverlay';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface VideoEngagementOverlayProps {\n engagement: Engagement;\n viewKey: string;\n imageCdnUrl: string;\n playerApiUrl: string;\n}\n\nexport function VideoEngagementOverlay(props: VideoEngagementOverlayProps): JSX.Element {\n const timepointIndicatorRef = React.useRef<HTMLDivElement>(null);\n\n const heatMap = getFullHeatMap(props.engagement);\n\n function setHoverTimepoint(time: number | null): void {\n const el = timepointIndicatorRef.current;\n\n if (!el)\n return;\n\n if (time === null) {\n el.classList.remove(styles.heatMapTimepointIndicatorVisible);\n return;\n }\n\n el.classList.add(styles.heatMapTimepointIndicatorVisible);\n el.style.left = `${time / heatMap.length * 100}%`;\n }\n\n return (\n <div className='bg-white border rounded overflow-hidden h-100'>\n <div className='position-relative'>\n {/**\n * The below div is an empty 16:9 rectangle which maintains this component's\n * height while the player is loading.\n */\n }\n <div className={styles.playerPlaceholder} />\n <div className={styles.playerContainer}>\n <ClickViewReportsPlayer\n viewKey={props.viewKey}\n playerApi={new URL(props.playerApiUrl)}\n hotkeyElQuerySelector='body'\n heatMap={heatMap}\n onTimepointHover={setHoverTimepoint}\n aspectRatio='16:9'\n />\n </div>\n </div>\n <div className='p-3'>\n <div className='position-relative'>\n <EngagementHeatMap\n engagement={props.engagement}\n className={styles.heatMap}\n />\n <div ref={timepointIndicatorRef} className={styles.heatMapTimepointIndicator} />\n </div>\n <div className='d-flex justify-content-between mt-2'>\n <strong>\n {getPhrase('heatmap')}\n </strong>\n <div className='w-33'>\n <EngagementHeatMapLegend />\n </div>\n </div>\n </div>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"videoContainer\":\"cpl68\"};","import React from 'react';\n\nimport { EngagementTable } from 'libs/shared/apps/analytics/components/engagement-table/EngagementTable';\nimport { InsightAmountWatched } from 'libs/shared/apps/analytics/components/insights/amount-watched/InsightAmountWatched';\nimport { InsightTotalViews } from 'libs/shared/apps/analytics/components/insights/total-views/InsightTotalViews';\nimport { AnonSessions } from 'libs/shared/apps/analytics/hooks/UseAnonSessions';\nimport { AudienceQueryParams } from 'libs/shared/apps/analytics/interfaces/AudienceQueryParams';\nimport { DateRangeQueryParams } from 'libs/shared/apps/analytics/interfaces/DateRangeQueryParams';\nimport { VideoViewEventResponse } from 'libs/shared/apps/analytics/interfaces/VideoViewEvent';\nimport { getFilterParamsKey } from 'libs/shared/apps/analytics/utils/FilterParamUtils';\nimport { Config, Engagement, IndividualEngagementResponse, PlayerViewKey, User } from 'libs/shared/interfaces';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\n\nimport { PartialInsightsHeatmap } from 'apps/my-shares/components/insights-heatmap/partial-loading/PartialInsightsHeatmap';\nimport { VideoEngagementOverlay } from 'apps/my-shares/components/video-engagement-overlay/VideoEngagementOverlay';\n\nimport styles from './insights-heatmap.scss';\n\ninterface InsightsHeatmapProps {\n hasDataLoaded: boolean;\n tableDataLoaded: boolean;\n videoViews: VideoViewEventResponse;\n aggregateEngagement: Engagement;\n audienceAppLinkParams: AudienceQueryParams;\n dateRangeAppLinkParams: DateRangeQueryParams;\n individualEngagement: IndividualEngagementResponse;\n viewKey: PlayerViewKey;\n config: Config;\n users: User[];\n anonymiseUsers: boolean;\n anonSessions?: AnonSessions;\n}\n\nexport function InsightsHeatmap(props: InsightsHeatmapProps) {\n return (\n <>\n {!props.hasDataLoaded && <PartialInsightsHeatmap />}\n\n <div className='row g-3 mb-3'>\n {props.hasDataLoaded &&\n <>\n <div className='col'>\n <InsightTotalViews events={props.videoViews} emptyStateImage={ImageUrls.EmptyStates.MY_VIDEOS} />\n </div>\n <div className='col'>\n <InsightAmountWatched engagement={props.aggregateEngagement} params={props.audienceAppLinkParams} />\n </div>\n <div className={styles.videoContainer}>\n <VideoEngagementOverlay\n engagement={props.aggregateEngagement}\n viewKey={props.viewKey.viewKey}\n playerApiUrl={props.config.playerApiUrl}\n imageCdnUrl={props.config.imageCdnUrl}\n />\n </div>\n </>\n }\n\n {props.tableDataLoaded &&\n <div className='col-12'>\n <EngagementTable\n key={getFilterParamsKey({ ...props.audienceAppLinkParams, ...props.dateRangeAppLinkParams })}\n engagement={props.individualEngagement.data}\n users={props.users}\n imageCdnUrl={props.config?.imageCdnUrl}\n anonymiseUsers={props.anonymiseUsers}\n border\n anonSessions={props.anonSessions}\n />\n </div>\n }\n </div>\n </>\n );\n}","import { FilterQueryParams } from 'libs/shared/apps/analytics/interfaces/FilterQueryParams';\n\nexport function getFilterParamsKey(filters: FilterQueryParams): string {\n const keys: string[] = [];\n\n Object.keys(filters).forEach((key: keyof FilterQueryParams) => {\n const val = filters[key];\n\n if (!val)\n return;\n\n keys.push(`${key}:${Array.isArray(val) ? val.join(',') : val}`);\n });\n\n return keys.join(':');\n}","// extracted by mini-css-extract-plugin\nexport default {\"circleContainer\":\"p8Vgz\",\"backgroundCircle\":\"asGGE\",\"circleSuccess\":\"PXLNj\",\"circleWarning\":\"ZckRN\",\"circleDanger\":\"slBRg\",\"lgCircleContainer\":\"N8KCI\",\"xsCircleContainer\":\"RPqZ2\",\"pendingCircle\":\"DKrcq\",\"centredPercentageText\":\"tpmLR\"};"],"names":["namespace","ZERO_COLOUR","COLOUR_SCALE","LEGEND_VALUES","getBackgroundColor","value","max","hex","getGradient","data","gradient","i","length","previousValue","currentValue","nextValue","push","join","EngagementHeatMapLegend","Math","legendSquareWidthPercentage","className","Text","phrase","map","val","idx","key","style","width","backgroundColor","EngagementHeatMap","props","heatMap","engagement","background","InsightCard","subtitle","svgClassName","SvgContainer","svgName","size","S","title","count","children","CHART_FONT_STYLES","fontSize","fontFamily","fontWeight","color","getPhrase","anonymiseUserName","user","shouldAnonymise","id","sessionName","seed","floor","Date","getMinutes","dictionaries","separator","getAnonSession","sessionId","anonSessions","fallback","getUserOrAnonSession","result","getFullHeatMap","Array","ceil","videoDuration","fill","t","PercentageIndicatorLayout","ProgressCircle","ref","circle","radius","r","baseVal","circumference","PI","offset","percentage","strokeDasharray","strokeDashoffset","toString","scoreThresholds","PercentageIndicator","percentageToFixed","layout","LabelInside","label","customLabel","LabelOnly","LabelBefore","defaultProps","CircleOnly","ProgressCircleSize","CIRCLE_STROKE_WIDTH","CIRCLE_STROKE_WIDTH_LG","ProgressCircleSizeMap","ExtraSmall","Small","Large","getCircleRadius","strokeWidth","getCircleClassName","HIGH","MODERATE","getColouredLabelClassName","getCircleContainerClassName","isPending","getPercentageToFixed","toFixed","getFormattedPercentage","round","DragOverlayStyles","opacity","cursor","calculateScrollState","canScrollLeft","current","scrollLeft","canScrollRight","scrollWidth","clientWidth","SortIndicator","column","canSort","isSorted","theme","sortIndicator","isSortedDesc","BaseTable","ids","idHash","tableOptions","columns","disableSortBy","enableSort","manualSortBy","manualSort","autoResetHiddenColumns","autoResetSortBy","initialState","sortBy","initialSortBy","initialSelectedRowIds","selectedRowIds","forEach","getRowId","useTable","plugins","useSortBy","useRowSelect","useFlexLayout","useBlockLayout","allowFiltering","useFilters","allowGlobalFiltering","useGlobalFilter","getPlugins","getTableProps","getTableBodyProps","headerGroups","rows","prepareRow","toggleAllRowsSelected","setGlobalFilter","setHiddenColumns","state","renderTableRows","row","FunctionHelper","isSelected","selectedRow","onSelectRow","enableSortableRows","getTableRowsClass","rowAppLink","getRowAppLink","onClickRow","allowSelectMultipleRows","toggleRowSelected","renderRow","sortableProps","dragAttributes","dragListeners","getSortableProps","role","AppLink","appLink","renderCells","onClick","rowProps","getRowProps","SortableItemWrapper","original","childProps","childComponent","cells","cell","cellClassName","onSelectCell","getCellClassName","getCellProps","render","onSort","globalFilter","hiddenColumns","table","header","headerGroup","getHeaderGroupProps","headerRow","headers","getHeaderProps","getSortByToggleProps","headerCell","renderSortIndicator","hideSortIndicator","body","SortableContainerWrapper","getDragOverlay","rowIndex","findIndex","item","onSortEnd","onSortingRowsEnd","Table","enableSlider","scrollIncrement","scrollable","tableProps","elRef","scrollState","setScrollState","throttledOnScroll","el","removeEventListener","addEventListener","scroll","scrollBy","left","top","behavior","useTableScroll","renderTrackHorizontal","autoHeightMax","autoHeight","onClickScroll","direction","WidgetButton","W","hide","scrollContainerClassName","ScoreThresholdDefaults","ScoreThresholdInsights","useLockContentWidth","LanguageService","CellWrapper","HeaderCell","phraseKey","useGetColumns","maxHeatMapValue","e","localMax","Header","accessor","sortType","rowA","rowB","values","anonymiseUsers","Cell","nameParts","name","split","filter","n","surname","slice","Avatar","imageCdnUrl","initials","UserHelper","imageUrl","avatar","url","showAnonymousUser","sortDescFirst","EngagementTable","users","find","u","userId","border","PartialPercentageIndicator","InsightAmountWatched","engagementRate","everyoneSelected","params","classrooms","classroomGroups","options","CHART_COLOURS","STATIC_CHART_OPTIONS","text","credits","enabled","chart","spacing","legend","itemStyle","itemDistance","plotOptions","pie","allowPointSelect","dataLabels","showInLegend","borderWidth","InsightTotalViews","events","groupsToOmit","getSeriesName","groups","eventCounts","chartData","staffIndex","group","staffObject","splice","sort","a","b","parseInt","match","sortByYearGroup","ev","includes","toLowerCase","ArrayHelper","Object","keys","y","type","d","totalViews","reduce","highcharts","series","getChartOptions","containerProps","EmptyState","src","emptyStateImage","PartialInsightsHeatmap","EngagementOverlayMenuItem","player","overlayVisible","toggle","this","toggleOn","toggleOff","toggleEl","engagementOverlayPlugin","toggleOverlay","addClass","removeClass","event","stopImmediatePropagation","tagName","properties","attributes","handlerBound","handleToggle","bind","innerHTML","appendChild","TimepointInteractions","timepoint","interactive","timepoints","timepointTime","visibleAt","time","interactions","MAX_INTERACTIONS_TO_SHOW","hiddenInteractions","InteractionLabel","interaction","showQuestion","iconClassName","xAxis","visible","minPadding","maxPadding","defs","x1","y1","x2","y2","height","styledMode","Component","EngagementOverlay","initialize","bindListeners","ready","buildChart","buildCSSClass","show","destroyChart","handleClick","resizeChart","on","off","paused","play","pause","chartDimensions","getChartDimensions","container","querySelector","getHighchartOptions","one","setSize","destroy","collapserator","getChild","collapseratorHeight","currentHeight","currentDimensions","moveTimepointIndicator","yAxis","options_","min","allowDecimals","startOnTick","endOnTick","tooltip","formatter","timepointInteractionsHtml","renderToStaticMarkup","getTimepointInteractionsHtml","x","formatTime","positioner","labelWidth","labelHeight","point","maxX","plotWidth","plotX","plotTop","useHTML","padding","area","mouseOver","mouseOut","marker","onTimepointHover","indicator","EngagementOverlayPlugin","hasHeatMapData","addChild","addItem","index","ctor","engagementOverlay","toggleChart","acc","InteractiveSeekBarPlugin","onTrackLoaded","track","addChildren","controlBar","ReportsPlayer","playbackObject","additionalSetup","setupEngagementOverlayPlugin","setupUpClipPlugin","setupInteractiveSeekBarPlugin","additionalData","clipData","isClip","mediaType","isInteractive","Error","clipPlugin","startTime","endTime","interactiveSeekBarPlugin","ignoreChapters","ClickViewReportsPlayer","playerRef","VideoEngagementOverlay","timepointIndicatorRef","viewKey","playerApi","URL","playerApiUrl","hotkeyElQuerySelector","classList","add","remove","aspectRatio","InsightsHeatmap","filters","hasDataLoaded","videoViews","ImageUrls","aggregateEngagement","audienceAppLinkParams","config","tableDataLoaded","dateRangeAppLinkParams","isArray","individualEngagement"],"sourceRoot":""}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[7480],{9806:(e,t,n)=>{n.d(t,{k:()=>x});var a=n(32735),i=n(65858),l=n(64249),o=n(15611),r=n(7432),c=n(11834),s=n(83345),u=n(56754),m=n(86348),d=n(7733),p=n(54610),v=n(4594),g=n(68626),h=n(9085),f=n(67453),b=n(31908);const y={thumbnailFallbackSvg:"D4JFs",posterFallbackSvg:"bjUWl",coverFallbackSvg:"kdLpt",thumbnailContainer:"d3CKN",insightsMask:"KM76U",requireMarking:"peLH7",badge:"mVu0E",bar:"zO3MS",a:"K1jW5",expandBar:"YITJl",b:"tCpLF",c:"lC0cq"};var E="shared.sharedObjectImage",k="rounded overflow-hidden";function C(){return a.createElement("div",{className:"d-flex pointer-events-none position-absolute bottom-0 start-0 h-100 w-100 z-1 justify-content-center align-items-center"},a.createElement("div",{className:"position-absolute bg-dark bg-gradient opacity-50 w-100 h-100 z-0 rounded-3"}),a.createElement("div",{className:"d-flex align-items-end gap-2 h-50 z-1"},a.createElement("div",{className:"d-flex align-items-end h-50"},a.createElement("div",{className:"".concat(y.bar," ").concat(y.a," rounded shadow")})),a.createElement("div",{className:"d-flex align-items-end h-75"},a.createElement("div",{className:"".concat(y.bar," ").concat(y.b," rounded shadow")})),a.createElement("div",{className:"d-flex align-items-end h-100"},a.createElement("div",{className:"".concat(y.bar," ").concat(y.c," rounded shadow")}))))}function x(e){var t=a.useCallback((function(t){var n;t&&e.fixedHeight&&(t.style.width="".concat(t.offsetHeight*(n=e.object,b.M.isVideoType(n)?16/9:n.typeId===v.E.Playlist?1:n.typeId===v.E.Series?9/16:void 0),"px"))}),[]),n=b.M.isVideoType(e.object),x=function(e){var t=f.j.getDisplayImageFromObject(e);if(b.M.isVideoType(e))return{image:t,imageType:p.__.Thumbnails,imageClassName:k,imageFallbackComponent:a.createElement(c.oy,{type:c.mS.Video})};switch(e.typeId){case v.E.Series:return{image:t,imageType:p.__.TallPosters,imageClassName:k,imageFallbackComponent:a.createElement(c.oy,{type:c.mS.Series,svgContainerClassName:y.posterFallbackSvg})};case v.E.Playlist:return{image:t,imageType:p.__.Covers,imageClassName:(null==t?void 0:t.url)?k:"".concat(k," ").concat((0,h.x)(e.name,d.o)),imageFallbackComponent:a.createElement(c.oy,{type:c.mS.Playlist,svgContainerClassName:(null==t?void 0:t.url)?y.coverFallbackSvg:"d-none",extraClasses:!(null==t?void 0:t.url)&&"bg-transparent"})}}}(e.object),w=x.image,N=x.imageType,T=x.imageClassName,S=x.imageFallbackComponent;return a.createElement("div",{className:"d-flex align-items-center justify-content-center w-100 h-100"},a.createElement("div",{ref:t,className:e.fixedHeight?"h-100":"w-100"},n&&a.createElement("div",{className:"".concat(y.thumbnailContainer," position-relative")},e.showInsightsMask&&a.createElement(C,null),a.createElement(o.F,{appLink:e.appLink},a.createElement(m.u,{video:e.object,imageOptions:e.imageOptions,textPosition:g.z.Independent,type:"cosmetic",hideDuration:!0,hideMask:!0})),!!e.requireMarking&&a.createElement("div",{className:"".concat(e.showInsightsMask&&y.requireMarking," position-absolute bottom-0 end-0 z-1 m-2")},a.createElement("div",{className:"".concat(y.badge," d-flex align-items-center bg-light-ultramarine text-ultramarine fw-semibold rounded-pill w-fit mt-1 px-2")},a.createElement(s.x,{namespace:E,phrase:"requireMarking",options:{smartCount:e.requireMarking}})))),!n&&a.createElement(a.Fragment,null,"videos"in e.object?a.createElement(u.I,{collection:e.object,imageOptions:e.imageOptions,appLink:e.appLink,analyticsData:{id:e.object.id,name:e.object.name},analyticsOptions:{entity:l.I.getAnalyticsEntity(e.object.type),actionType:i.Vw.Click,location:e.locationContext},showMask:e.showCollectionMask,showVideoCount:e.showVideoCount}):a.createElement(r.Z,{data:null==w?void 0:w.url,imageType:N,imageOptions:e.imageOptions,appLink:e.appLink,className:T,analyticsData:{id:e.object.id,name:e.object.name},analyticsOptions:{entity:l.I.getAnalyticsEntity(e.object.type),actionType:i.Vw.Click,location:e.locationContext}},S))))}x.defaultProps={imageOptions:{size:p.h2.Small}}},31754:(e,t,n)=>{n.d(t,{x:()=>r});var a=n(82602),i=n(75896),l=n(41859),o=n(11576),r={groupByDateShared:function(e){var t=i.m.groupBy(e,"dateShared");return Object.keys(t).sort().reverse().reduce((function(e,n){var i=(0,a.WU)(n);return e[i]||(e[i]=[]),e[i]=e[i].concat(t[n]),e}),{})},mapActivityStatusToCheckMarkStatus:function(e){switch(e){case o.T.Complete:return l.h.Complete;case o.T.Incomplete:return l.h.Incomplete;case o.T.None:return l.h.None}},mapCheckMarkStatusToActivityStatus:function(e){switch(e){case l.h.Complete:return o.T.Complete;case l.h.Incomplete:return o.T.Incomplete;case l.h.None:return o.T.None}}}},56754:(e,t,n)=>{n.d(t,{I:()=>E});var a=n(32735),i=n(75896),l=n(65858),o=n(15611),r=n(83914),c=n(83345);const s={thumbnailTitle:"OsWjL"};function u(e){return a.createElement("h3",{title:e.title,className:"h6"},e.title)}function m(e){return e.appLink?a.createElement(o.F,{appLink:e.appLink,className:"".concat(s.thumbnailTitle)},a.createElement(u,Object.assign({},e))):a.createElement(u,Object.assign({},e))}var d=n(86348),p=n(62335),v=n(4594),g=n(68626),h=n(45778),f=n(35223);const b={badge:"M4zat",mask:"r0Ztg",thumbnailContainer:"uD9dz"};var y="shared.collectionThumbnail";function E(e){var t,n,s,u,E=function(){var t,n=null===(t=e.collection)||void 0===t?void 0:t.videos;if(n){if(!n.count&&e.collection.typeId===v.E.Playlist){var a=e.collection;a.clips.count&&(n=a.clips),a.interactives.count&&(n=a.interactives)}return i.m.first(n.data)}}(),k=function(){var t,n,a=0;if(e.collection.videos&&e.collection.videos.count&&(a+=e.collection.videos.count),e.collection.typeId===v.E.Playlist){var i=e.collection;(null===(t=i.interactives)||void 0===t?void 0:t.count)&&(a+=i.interactives.count),(null===(n=i.clips)||void 0===n?void 0:n.count)&&(a+=i.clips.count)}return a}(),C=(null===(t=e.title)||void 0===t?void 0:t.length)||(null===(n=e.subText)||void 0===n?void 0:n.length),x=Object.assign({id:e.collection.id.toString(),name:e.collection.name},e.analyticsData),w=Object.assign({actionType:l.Vw.Click,entity:(u=e.collection,h.G.isType(u,v.E.Playlist)?l.py.Playlist:h.G.isType(u,v.E.Series)?l.py.Series:void 0)},e.analyticsOptions);return a.createElement("div",null,a.createElement("div",{className:"position-relative ".concat(b.thumbnailContainer," z-1")},a.createElement(o.F,{appLink:e.appLink,analyticsData:x,analyticsOptions:w,preventFocus:!0},e.showMask&&a.createElement("div",{className:"".concat(b.mask," position-absolute w-100 h-100 rounded-3 bg-dark bg-gradient z-1 bg-opacity-50 pointer-events-none")},a.createElement("div",{className:"".concat(b.badge," d-flex align-items-center w-fit flex-grow-0 bg-dark rounded-pill ps-1 m-2")},a.createElement(r.x,{svgName:f.vn.Play,className:"svg-container text-white"}),a.createElement("p",{className:"d-inline fw-medium text-white mb-0"},(null===(s=e.hoverText)||void 0===s?void 0:s.length)?a.createElement("span",null,e.hoverText):a.createElement(c.x,{namespace:y,phrase:"playAll"})))),E&&a.createElement(d.u,{video:E,imageOptions:e.imageOptions,textPosition:g.z.Independent,type:"cosmetic",hideMask:!0,hideRating:!0,hideDuration:!0,hideVideoTypeBadge:!0}),!E&&a.createElement("div",{className:"ratio ratio-16x9 bg-light rounded-3"},a.createElement("div",{className:"d-flex justify-content-center align-items-center"},a.createElement(r.x,{svgName:f.vn.Play,className:"w-33 opacity-25 text-gray-400"}))),e.showVideoCount&&a.createElement("div",{className:"".concat(b.badge," d-flex align-items-center w-fit bg-dark bg-opacity-75 rounded-pill position-absolute bottom-0 end-0 ps-1 m-2")},a.createElement(r.x,{svgName:f.vn.Series,className:"svg-container text-white me-1"}),a.createElement("p",{className:"d-inline fw-semibold text-white mb-0"},a.createElement(c.x,{namespace:y,phrase:"videos",options:{count:k,smartCount:k}}))))),C&&a.createElement("div",{className:"mt-2 d-flex flex-column"},e.subText&&a.createElement(p.m,{title:e.subText,appLink:e.subTextAppLink},e.subText),e.title&&a.createElement(m,{title:e.collection.name,appLink:e.titleAppLink})))}},60115:(e,t,n)=>{n.d(t,{K:()=>s});var a=n(32735),i=n(50242),l=n(91967),o=400,r=n(45719);function c(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,a=Array(t);n<t;n++)a[n]=e[n];return a}function s(e,t,n,s,u,m){var d,p,v,g,h=(d=(0,a.useState)(0),p=2,function(e){if(Array.isArray(e))return e}(d)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var a,i,l,o,r=[],c=!0,s=!1;try{if(l=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;c=!1}else for(;!(c=(a=l.call(n)).done)&&(r.push(a.value),r.length!==t);c=!0);}catch(e){s=!0,i=e}finally{try{if(!c&&null!=n.return&&(o=n.return(),Object(o)!==o))return}finally{if(s)throw i}}return r}}(d,p)||function(e,t){if(e){if("string"==typeof e)return c(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?c(e,t):void 0}}(d,p)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),f=h[0],b=h[1],y=t,E=(0,r.P)((function(t){if(!e)return null;var n=e(t);return n?n.key:null}),s,u);return v={fetchNextPage:function(){if(t&&e&&E)return b((function(e){return e+1})),y(E.nextCursor)},hasMore:!!(null==E?void 0:E.nextCursor),isFetching:null==E?void 0:E.isFetching,scrollContainer:m},g=function(){if(!v.isFetching){if(v.scrollContainer){var e=v.scrollContainer;if(e.getBoundingClientRect().height+e.scrollTop<e.scrollHeight-o)return}else if(window.innerHeight+document.documentElement.scrollTop<document.documentElement.scrollHeight-o)return;v.fetchNextPage()}},(0,a.useEffect)((function(){var e=l.q.throttle(g,200),t=v.scrollContainer||window;return v.hasMore&&t.addEventListener("scroll",e),function(){return t.removeEventListener("scroll",e)}}),[v.hasMore,v.fetchNextPage,v.scrollContainer]),(0,a.useEffect)((function(){E&&E.shouldInitialFetch&&t&&(y(),b((function(e){return e+1})))}),[null==E?void 0:E.shouldInitialFetch,t]),(0,a.useEffect)((function(){var e,t;if((null==E?void 0:E.statusCode)&&l.q.isFunction(n)){var a=+(null===(t=null===(e=E.statusCode)||void 0===e?void 0:e.toString())||void 0===t?void 0:t.substr(0,1));a!==i.k.ClientError&&a!==i.k.ServerError||n(f,E.statusCode)}}),[null==E?void 0:E.statusCode]),{items:null==E?void 0:E.items,hasMore:!!(null==E?void 0:E.nextCursor),nextCursor:null==E?void 0:E.nextCursor,isFetching:null==E?void 0:E.isFetching,totalItems:null==E?void 0:E.totalItems,hasFirstPageCompleted:null==E?void 0:E.hasFirstPageCompleted}}},82602:(e,t,n)=>{n.d(t,{WU:()=>s});var a=["second","minute","hour","day","week","month","year"],i=["秒","分钟","小时","天","周","个月","年"],l={},o=function(e,t){l[e]=t},r=[60,60,24,7,365/7/12,12];function c(e){return e instanceof Date?e:!isNaN(e)||/^\d+$/.test(e)?new Date(parseInt(e)):(e=(e||"").trim().replace(/\.\d+/,"").replace(/-/,"/").replace(/-/,"/").replace(/(\d)T(\d)/,"$1 $2").replace(/Z/," UTC").replace(/([+-]\d\d):?(\d\d)/," $1$2"),new Date(e))}var s=function(e,t,n){var a=function(e,t){return(+(t?c(t):new Date)-+c(e))/1e3}(e,n&&n.relativeDate);return function(e,t){for(var n=e<0?1:0,a=e=Math.abs(e),i=0;e>=r[i]&&i<r.length;i++)e/=r[i];return(e=Math.floor(e))>(0==(i*=2)?9:1)&&(i+=1),t(e,i,a)[n].replace("%s",e.toString())}(a,function(e){return l[e]||l.en_US}(t))};o("en_US",(function(e,t){if(0===t)return["just now","right now"];var n=a[Math.floor(t/2)];return e>1&&(n+="s"),[e+" "+n+" ago","in "+e+" "+n]})),o("zh_CN",(function(e,t){if(0===t)return["刚刚","片刻后"];var n=i[~~(t/2)];return[e+" "+n+"前",e+" "+n+"后"]}))}}]);
|
|
2
|
-
//# sourceMappingURL=7480-02bc4e08a3-lite.chunk.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scripts/7480-02bc4e08a3-lite.chunk.js","mappings":"mTACA,SAAgB,qBAAuB,QAAQ,kBAAoB,QAAQ,iBAAmB,QAAQ,mBAAqB,QAAQ,aAAe,QAAQ,eAAiB,QAAQ,MAAQ,QAAQ,IAAM,QAAQ,EAAI,QAAQ,UAAY,QAAQ,EAAI,QAAQ,EAAI,SCuBjQ,IAAMA,EAAY,2BAEZC,EAAwB,0BAgD9B,SAASC,IACP,OACE,uBAAKC,UAAS,2HACZ,uBAAKA,UAAU,+EACf,uBAAKA,UAAU,yCACb,uBAAKA,UAAU,+BACb,uBAAKA,UAAS,UAAK,MAAU,YAAI,IAAQ,sBAE3C,uBAAKA,UAAU,+BACb,uBAAKA,UAAS,UAAK,MAAU,YAAI,IAAQ,sBAE3C,uBAAKA,UAAU,gCACb,uBAAKA,UAAS,UAAK,MAAU,YAAI,IAAQ,uBAKnD,CA8BM,SAAUC,EAAkBC,GAChC,IAAMC,EAAM,eAAkB,SAACC,GA7BjC,IAAuBC,EA8BdD,GAAOF,EAAMI,cAGlBF,EAAGG,MAAMC,MAAQ,GAAH,OAAMJ,EAAGK,cAjCJJ,EAiCiCH,EAAMG,OAhCxDK,EAAA,cAAwBL,GACnB,GAAK,EAEVA,EAAOM,SAAWC,EAAA,WACb,EAELP,EAAOM,SAAWC,EAAA,SACb,EAAI,QADb,GA0BmE,MACnE,GAAG,IAEGC,EAAoBH,EAAA,cAAwBR,EAAMG,QAExD,EAhGF,SAAuBA,GACrB,IAAMS,EAAQC,EAAA,4BAAsCV,GAEpD,GAAIK,EAAA,cAAwBL,GAC1B,MAAO,CACLS,MAAAA,EACAE,UAAW,gBACXC,eAAgBnB,EAChBoB,uBAAwB,gBAACC,EAAA,GAAa,CAACC,KAAMD,EAAA,YAGjD,OAAQd,EAAOM,QACb,KAAKC,EAAA,SACH,MAAO,CACLE,MAAAA,EACAE,UAAW,iBACXC,eAAgBnB,EAChBoB,uBACE,gBAACC,EAAA,GAAa,CAACC,KAAMD,EAAA,UAA0BE,sBAAuB,uBAG5E,KAAKT,EAAA,WACH,MAAO,CACLE,MAAAA,EACAE,UAAW,YACXC,gBAAiBH,aAAK,EAALA,EAAOQ,KAEpBxB,EAFuB,UACpBA,EAAqB,aAAI,EAAAyB,EAAA,GAAgBlB,EAAOmB,KAAM,MAE7DN,uBACE,gBAACC,EAAA,GAAa,CACZC,KAAMD,EAAA,YACNE,uBAAuBP,aAAK,EAALA,EAAOQ,KAAM,mBAA0B,SAC9DG,eAAeX,aAAK,EAALA,EAAOQ,MAAO,oBAKzC,CAgEMI,CAAcxB,EAAMG,QAJtBS,EAAK,EAALA,MACAE,EAAS,EAATA,UACAC,EAAc,EAAdA,eACAC,EAAsB,EAAtBA,uBAGF,OACE,uBAAKlB,UAAU,gEACb,uBAAKG,IAAKA,EAAKH,UAAWE,EAAMI,YAAc,QAAU,SACrDO,GACC,uBAAKb,UAAS,UAAK,qBAAyB,uBACzCE,EAAMyB,kBAAoB,gBAAC5B,EAAY,MACxC,gBAAC6B,EAAA,EAAO,CAACC,QAAS3B,EAAM2B,SACtB,gBAACC,EAAA,EAAc,CACbC,MAAO7B,EAAMG,OACb2B,aAAc9B,EAAM8B,aACpBC,aAAcC,EAAA,cACdd,KAAK,WACLe,cAAY,EACZC,UAAQ,OAGTlC,EAAMmC,gBACP,uBAAKrC,UAAS,UAAKE,EAAMyB,kBAAoB,iBAAqB,8CAChE,uBAAK3B,UAAS,UAAK,QAAY,8GAC7B,gBAACsC,EAAA,EAAI,CAACzC,UAAWA,EAAW0C,OAAO,iBAAiBC,QAAS,CAAEC,WAAYvC,EAAMmC,sBAMzFxB,GACA,gCACG,WAAaX,EAAMG,OAClB,gBAACqC,EAAA,EAAmB,CAClBC,WAAYzC,EAAMG,OAClB2B,aAAc9B,EAAM8B,aACpBH,QAAS3B,EAAM2B,QACfe,cAAe,CACbC,GAAI3C,EAAMG,OAAOwC,GACjBrB,KAAMtB,EAAMG,OAAOmB,MAErBsB,iBAAkB,CAChBC,OAAQC,EAAA,qBAAmC9C,EAAMG,OAAOe,MACxD6B,WAAY,WACZC,SAAUhD,EAAMiD,iBAElBC,SAAUlD,EAAMmD,mBAChBC,eAAgBpD,EAAMoD,iBAGxB,gBAACC,EAAA,EAAS,CACRC,KAAM1C,aAAK,EAALA,EAAOQ,IACbN,UAAWA,EACXgB,aAAc9B,EAAM8B,aACpBH,QAAS3B,EAAM2B,QACf7B,UAAWiB,EACX2B,cAAe,CACbC,GAAI3C,EAAMG,OAAOwC,GACjBrB,KAAMtB,EAAMG,OAAOmB,MAErBsB,iBAAkB,CAChBC,OAAQC,EAAA,qBAAmC9C,EAAMG,OAAOe,MACxD6B,WAAY,WACZC,SAAUhD,EAAMiD,kBAGjBjC,KAQjB,CAvGAjB,EAAkBwD,aAAe,CAC/BzB,aAAc,CAAE0B,KAAM,Y,mFC5FXC,EAAc,CACzBC,kBAAiB,SAAiCJ,GAChD,IAAMK,EAAwC,YAAoBL,EAAM,cAKxE,OAHoBM,OAAOC,KAAKF,GAAqBG,OAAOC,UAGzCC,QAAO,SAACC,EAAuBC,GAChD,IAAMC,GAAU,QAAOD,GAMvB,OAJKD,EAAIE,KACPF,EAAIE,GAAW,IAEjBF,EAAIE,GAAWF,EAAIE,GAASC,OAAOT,EAAoBO,IAChDD,CACT,GAAG,CAAC,EACN,EAEAI,mCAAkC,SAACC,GACjC,OAAQA,GACN,KAAK,aACH,OAAO,aACT,KAAK,eACH,OAAO,eACT,KAAK,SACH,OAAO,SAEb,EAEAC,mCAAkC,SAACC,GACjC,OAAQA,GACN,KAAK,aACH,OAAO,aACT,KAAK,eACH,OAAO,eACT,KAAK,SACH,OAAO,SAEb,E,yGClDF,SAAgB,eAAiB,SCWjC,SAASC,EAA6BzE,GACpC,OACE,sBAAI0E,MAAO1E,EAAM0E,MAAO5E,UAAU,MAAME,EAAM0E,MAElD,CAMM,SAAUC,EAAyB3E,GACvC,OAAKA,EAAM2B,QAOT,gBAACD,EAAA,EAAO,CAACC,QAAS3B,EAAM2B,QAAS7B,UAAS,UAAK,mBAC7C,gBAAC2E,EAA4B,iBAAKzE,KANlC,gBAACyE,EAA4B,iBAAKzE,GASxC,C,qECjCA,SAAgB,MAAQ,QAAQ,KAAO,QAAQ,mBAAqB,SCsBpE,IAAML,EAAY,6BAmBZ,SAAU6C,EAAoBxC,G,UAwCXyC,EAUjBmC,EAjDN,W,MACMC,EAAmC,QAAhB,EAAA7E,EAAMyC,kBAAU,eAAEqC,OAEzC,GAAKD,EAAL,CAGA,IAAKA,EAAiBE,OAAS/E,EAAMyC,WAAWhC,SAAWC,EAAA,WAAqB,CAC9E,IAAMsE,EAAWhF,EAAMyC,WAEnBuC,EAASC,MAAMF,QACjBF,EAAmBG,EAASC,OAE1BD,EAASE,aAAaH,QACxBF,EAAmBG,EAASE,aAC/B,CAED,OAAOC,EAAA,QAAkBN,EAAiBvB,KAZlC,CAaV,CAgCmB8B,GACbC,EA/BN,W,QACMC,EAAa,EAMjB,GAJItF,EAAMyC,WAAWqC,QAAU9E,EAAMyC,WAAWqC,OAAOC,QACrDO,GAActF,EAAMyC,WAAWqC,OAAOC,OAGpC/E,EAAMyC,WAAWhC,SAAWC,EAAA,WAAqB,CACnD,IAAMsE,EAAWhF,EAAMyC,YAEE,QAArB,EAAAuC,EAASE,oBAAY,eAAEH,SACzBO,GAAcN,EAASE,aAAaH,QAEpB,QAAd,EAAAC,EAASC,aAAK,eAAEF,SAClBO,GAAcN,EAASC,MAAMF,MAChC,CAED,OAAOO,CACT,CAamBC,GACbC,GAAuB,QAAX,EAAAxF,EAAM0E,aAAK,eAAEe,UAAuB,QAAb,EAAAzF,EAAM0F,eAAO,eAAED,QAElD/C,EAAgB,OAAH,QACjBC,GAAI3C,EAAMyC,WAAWE,GAAGgD,WACxBrE,KAAMtB,EAAMyC,WAAWnB,MAEpBtB,EAAM0C,eAGLE,EAAmB,OAAH,QACpBG,WAAY,WACZF,QAvBqBJ,EAuBCzC,EAAMyC,WAtBxBmD,EAAA,SAAkCnD,EAAY/B,EAAA,YACzC,cAGLkF,EAAA,SAAgCnD,EAAY/B,EAAA,UACvC,iBADT,IAoBGV,EAAM4C,kBAGX,OACE,2BACE,uBAAK9C,UAAS,4BAAuB,qBAAyB,SAC5D,gBAAC4B,EAAA,EAAO,CACNC,QAAS3B,EAAM2B,QACfe,cAAeA,EACfE,iBAAkBA,EAClBiD,cAAY,GAEX7F,EAAMkD,UACL,uBAAKpD,UAAS,UAAK,OAAW,uGAC5B,uBAAKA,UAAS,UAAK,QAAY,+EAC7B,gBAACgG,EAAA,EAAY,CAACC,QAAS,UAAmBjG,UAAU,6BACpD,qBAAGA,UAAU,uCACK,QAAf,EAAAE,EAAMgG,iBAAS,eAAEP,QAChB,4BAAOzF,EAAMgG,WACb,gBAAC5D,EAAA,EAAI,CAACzC,UAAWA,EAAW0C,OAAO,eAO5CuC,GACC,gBAAChD,EAAA,EAAc,CACbC,MAAO+C,EACP9C,aAAc9B,EAAM8B,aACpBC,aAAcC,EAAA,cACdd,KAAK,WACLgB,UAAQ,EACR+D,YAAU,EACVhE,cAAY,EACZiE,oBAAkB,KAIpBtB,GACA,uBAAK9E,UAAU,uCACb,uBAAKA,UAAU,oDACb,gBAACgG,EAAA,EAAY,CAACC,QAAS,UAAmBjG,UAAU,oCAKzDE,EAAMoD,gBACL,uBAAKtD,UAAS,UAAK,QAAY,kHAC7B,gBAACgG,EAAA,EAAY,CAACC,QAAS,YAAqBjG,UAAU,kCACtD,qBAAGA,UAAU,wCACX,gBAACsC,EAAA,EAAI,CAACzC,UAAWA,EAAW0C,OAAO,SAASC,QAAS,CAAEyC,MAAOM,EAAY9C,WAAY8C,SAQ/FG,GACC,uBAAK1F,UAAU,2BACZE,EAAM0F,SACL,gBAACS,EAAA,EAAY,CAACzB,MAAO1E,EAAM0F,QAAS/D,QAAS3B,EAAMoG,gBAChDpG,EAAM0F,SAGV1F,EAAM0E,OACL,gBAACC,EAAwB,CACvBD,MAAO1E,EAAMyC,WAAWnB,KACxBK,QAAS3B,EAAMqG,gBAO7B,C,wECnLMC,EAAmB,I,iHC2BnB,SAAUC,EACdC,EACAC,EACAC,EACAC,EACAC,EACAC,GAEA,I,ID1BgCvE,EAC1BwE,ECyB+C,G,GAAX,IAAAC,UAAS,G,EAAE,E,o4BAA7CC,EAAY,KAAEC,EAAe,KAE/BC,EAAcT,EAcdU,GAAW,QAZjB,SAAgBC,GACd,IAAKZ,EACH,OAAO,KAET,IAAMa,EAAUb,EAAWY,GAE3B,OAAKC,EAGEA,EAAQC,IAFN,IAGX,GAIEX,EACAC,GAwCF,ODrFgCtE,ECwDd,CAChBiF,cATF,WACE,GAAKd,GAAcD,GAAeW,EAIlC,OADAF,GAAgB,SAAAO,GAAU,OAAIA,EAAa,CAAC,IACrCN,EAAYC,EAASM,WAC9B,EAIEC,WAAWP,aAAQ,EAARA,EAAUM,YACrBE,WAAYR,aAAQ,EAARA,EAAUQ,WACtBd,gBAAAA,GD3DIC,EAAe,WACnB,IAAIxE,EAAQqF,WAAZ,CAGA,GAAKrF,EAAQuE,gBAON,CACL,IAAQA,EAAoBvE,EAApBuE,gBAKR,GAJ4BA,EAAgBe,wBAAwBC,OAAShB,EAAgBiB,UAEzEjB,EAAgBkB,aAAezB,EAGjD,MACH,MAVC,GAJ4B0B,OAAOC,YAAcC,SAASC,gBAAgBL,UAEtDI,SAASC,gBAAgBJ,aAAezB,EAG1D,OAWJhE,EAAQiF,eAnBA,CAoBV,GAEA,IAAAa,YAAU,WACR,IAAMC,EAAWC,EAAA,WAAwBxB,EAAc,KAEjDD,EAAkBvE,EAAQuE,iBAAmBmB,OAKnD,OAHI1F,EAAQoF,SACVb,EAAgB0B,iBAAiB,SAAUF,GAEtC,kBAAMxB,EAAgB2B,oBAAoB,SAAUH,EAAS,CACtE,GAAG,CAAE/F,EAAQoF,QAASpF,EAAQiF,cAAejF,EAAQuE,mBC6BrD,IAAAuB,YAAU,WACHjB,GAGDA,EAASsB,oBAAsBhC,IACjCS,IACAD,GAAgB,SAAAO,GAAU,OAAIA,EAAa,CAAC,IAEhD,GAAG,CAAEL,aAAQ,EAARA,EAAUsB,mBAAoBhC,KAEnC,IAAA2B,YAAU,W,QACR,IAAKjB,aAAQ,EAARA,EAAUuB,aAAeJ,EAAA,aAA0B5B,GAAxD,CAGA,IAAMiC,IAAoE,QAA/B,EAAmB,QAAnB,EAAAxB,EAASuB,kBAAU,eAAE/C,kBAAU,eAAEiD,OAAO,EAAG,IAElFD,IAAoBE,EAAA,eAA+BF,IAAoBE,EAAA,eAG3EnC,EAAQM,EAAcG,EAASuB,WAPvB,CAQV,GAAG,CAACvB,aAAQ,EAARA,EAAUuB,aAEP,CACLI,MAAO3B,aAAQ,EAARA,EAAU2B,MACjBpB,WAAWP,aAAQ,EAARA,EAAUM,YACrBA,WAAYN,aAAQ,EAARA,EAAUM,WACtBE,WAAYR,aAAQ,EAARA,EAAUQ,WACtBoB,WAAY5B,aAAQ,EAARA,EAAU4B,WACtBC,sBAAuB7B,aAAQ,EAARA,EAAU6B,sBAErC,C,oCC1GA,IAAIC,EAAQ,CAAC,SAAU,SAAU,OAAQ,MAAO,OAAQ,QAAS,QCA7DC,EAAQ,CAAC,IAAK,KAAM,KAAM,IAAK,IAAK,KAAM,KCO1CC,EAAU,CAAC,EAMJC,EAAW,SAAUC,EAAQC,GACpCH,EAAQE,GAAUC,CACtB,ECXIC,EAAY,CACZ,GACA,GACA,GACA,EACA,IAAM,EAAI,GACV,IAOG,SAASC,EAAOC,GACnB,OAAIA,aAAiBC,KACVD,GAENE,MAAMF,IAAU,QAAQG,KAAKH,GACvB,IAAIC,KAAKG,SAASJ,KAC7BA,GAASA,GAAS,IAEbK,OACAC,QAAQ,QAAS,IACjBA,QAAQ,IAAK,KACbA,QAAQ,IAAK,KACbA,QAAQ,YAAa,SACrBA,QAAQ,IAAK,QACbA,QAAQ,qBAAsB,SAC5B,IAAIL,KAAKD,GACpB,CCzBO,IAAIO,EAAS,SAAU9F,EAAMmF,EAAQY,GAExC,IAAIC,EDgFD,SAAiBhG,EAAMiG,GAE1B,SADcA,EAAeX,EAAOW,GAAgB,IAAIT,OACpCF,EAAOtF,IAAS,GACxC,CCnFc,CAAQA,EAAM+F,GAAQA,EAAKE,cAErC,OD4BG,SAAoBC,EAAMC,GAyB7B,IAhBA,IAAIC,EAAQF,EAAO,EAAI,EAAI,EAWvBG,EAJJH,EAAOI,KAAKC,IAAIL,GAQZM,EAAM,EACHN,GAAQb,EAAUmB,IAAQA,EAAMnB,EAAU9D,OAAQiF,IACrDN,GAAQb,EAAUmB,GAgBtB,OAJAN,EAAOI,KAAKG,MAAMP,KAEE,IADpBM,GAAO,GACiB,EAAI,KACxBA,GAAO,GACJL,EAAWD,EAAMM,EAAKH,GAAUD,GAAOP,QAAQ,KAAMK,EAAKzE,WACrE,CCvEW,CAAWuE,EFSC,SAAUb,GAC7B,OAAOF,EAAQE,IAAWF,EAAe,KAC7C,CEX2B,CAAUE,GACrC,ECNAD,EAAS,SLNM,SAAUgB,EAAMM,GAC3B,GAAY,IAARA,EACA,MAAO,CAAC,WAAY,aACxB,IAAIE,EAAO3B,EAAMuB,KAAKG,MAAMD,EAAM,IAGlC,OAFIN,EAAO,IACPQ,GAAQ,KACL,CAACR,EAAO,IAAMQ,EAAO,OAAQ,MAAQR,EAAO,IAAMQ,EAC7D,IKAAxB,EAAS,SJPM,SAAUgB,EAAMM,GAC3B,GAAY,IAARA,EACA,MAAO,CAAC,KAAM,OAClB,IAAIE,EAAO1B,KAASwB,EAAM,IAC1B,MAAO,CAACN,EAAO,IAAMQ,EAAO,IAAUR,EAAO,IAAMQ,EAAO,IAC9D,G","sources":["file:///app/packages/libs/shared/src/apps/share/components/shared-object-image/shared-object-image.scss","file:///app/packages/libs/shared/src/apps/share/components/shared-object-image/SharedObjectImage.tsx","file:///app/packages/libs/shared/src/apps/share/utils/ShareHelper.ts","file:///app/packages/libs/shared/src/components/thumbnails/collection/title/collection-thumbnail-title.scss","file:///app/packages/libs/shared/src/components/thumbnails/collection/title/CollectionThumbnailTitle.tsx","file:///app/packages/libs/shared/src/components/thumbnails/collection/collection-thumbnail.scss","file:///app/packages/libs/shared/src/components/thumbnails/collection/CollectionThumbnail.tsx","file:///app/packages/libs/shared/src/hooks/UseInfiniteScroll.ts","file:///app/packages/libs/shared/src/hooks/UseInfiniteList.ts","file:///app/node_modules/timeago.js/esm/lang/en_US.js","file:///app/node_modules/timeago.js/esm/lang/zh_CN.js","file:///app/node_modules/timeago.js/esm/register.js","file:///app/node_modules/timeago.js/esm/utils/date.js","file:///app/node_modules/timeago.js/esm/format.js","file:///app/node_modules/timeago.js/esm/index.js"],"sourcesContent":["// extracted by mini-css-extract-plugin\nexport default {\"thumbnailFallbackSvg\":\"D4JFs\",\"posterFallbackSvg\":\"bjUWl\",\"coverFallbackSvg\":\"kdLpt\",\"thumbnailContainer\":\"d3CKN\",\"insightsMask\":\"KM76U\",\"requireMarking\":\"peLH7\",\"badge\":\"mVu0E\",\"bar\":\"zO3MS\",\"a\":\"K1jW5\",\"expandBar\":\"YITJl\",\"b\":\"tCpLF\",\"c\":\"lC0cq\"};","import React from 'react';\n\nimport { Core } from 'libs/common/core';\n\nimport { LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { ShareViewHelper } from 'libs/shared/apps/share/views/share/ShareViewHelper';\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { BaseImage } from 'libs/shared/components/image/BaseImage';\nimport { ImageFallback, ImageFallbackType } from 'libs/shared/components/image/ImageFallback';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { CollectionThumbnail } from 'libs/shared/components/thumbnails/collection/CollectionThumbnail';\nimport { VideoThumbnail } from 'libs/shared/components/thumbnails/video/VideoThumbnail';\nimport { BG_COLOUR_CLASS_NAMES } from 'libs/shared/constants/ColourClassNames';\nimport { ImageSize, ImageType } from 'libs/shared/enums/Images';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { ThumbnailTextPosition } from 'libs/shared/enums/ThumbnailTextPosition';\nimport { BaseObject, Image, Playlist, Series } from 'libs/shared/interfaces';\nimport { getBgColorClass } from 'libs/shared/utils/getBgColorClass';\nimport { ImageHelper, ImageOptions } from 'libs/shared/utils/ImageHelper';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport styles from './shared-object-image.scss';\n\nconst namespace = 'shared.sharedObjectImage';\n\nconst BASE_IMAGE_CLASS_NAME = 'rounded overflow-hidden';\n\ninterface ImageProps {\n image: Image;\n imageType: ImageType;\n imageClassName?: string;\n imageFallbackComponent: JSX.Element;\n}\n\nfunction getImageProps(object: BaseObject): ImageProps {\n const image = ImageHelper.getDisplayImageFromObject(object);\n\n if (VideoHelper.isVideoType(object))\n return {\n image,\n imageType: ImageType.Thumbnails,\n imageClassName: BASE_IMAGE_CLASS_NAME,\n imageFallbackComponent: <ImageFallback type={ImageFallbackType.Video} />\n };\n\n switch (object.typeId) {\n case MasterType.Series:\n return {\n image,\n imageType: ImageType.TallPosters,\n imageClassName: BASE_IMAGE_CLASS_NAME,\n imageFallbackComponent:\n <ImageFallback type={ImageFallbackType.Series} svgContainerClassName={styles.posterFallbackSvg} />\n };\n\n case MasterType.Playlist:\n return {\n image,\n imageType: ImageType.Covers,\n imageClassName: !image?.url\n ? `${BASE_IMAGE_CLASS_NAME} ${getBgColorClass(object.name, BG_COLOUR_CLASS_NAMES)}`\n : BASE_IMAGE_CLASS_NAME,\n imageFallbackComponent: (\n <ImageFallback\n type={ImageFallbackType.Playlist}\n svgContainerClassName={image?.url ? styles.coverFallbackSvg : 'd-none'}\n extraClasses={!image?.url && 'bg-transparent'}\n />\n )\n };\n }\n}\n\nfunction InsightsMask() {\n return (\n <div className={`d-flex pointer-events-none position-absolute bottom-0 start-0 h-100 w-100 z-1 justify-content-center align-items-center`}>\n <div className='position-absolute bg-dark bg-gradient opacity-50 w-100 h-100 z-0 rounded-3'></div>\n <div className='d-flex align-items-end gap-2 h-50 z-1'>\n <div className='d-flex align-items-end h-50'>\n <div className={`${styles.bar} ${styles.a} rounded shadow`}></div>\n </div>\n <div className='d-flex align-items-end h-75'>\n <div className={`${styles.bar} ${styles.b} rounded shadow`}></div>\n </div>\n <div className='d-flex align-items-end h-100'>\n <div className={`${styles.bar} ${styles.c} rounded shadow`}></div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction getImageRatio(object: BaseObject): ImageFallbackType {\n if (VideoHelper.isVideoType(object))\n return 16 / 9;\n\n if (object.typeId === MasterType.Playlist)\n return 1;\n\n if (object.typeId === MasterType.Series)\n return 9 / 16;\n}\n\nSharedObjectImage.defaultProps = {\n imageOptions: { size: ImageSize.Small }\n};\n\ninterface SharedObjectImageProps {\n object: BaseObject;\n locationContext: LocationContext;\n appLink?: Core.AppLink;\n showVideoMetadata?: boolean;\n fixedHeight?: boolean;\n requireMarking?: number;\n imageOptions?: ImageOptions;\n showInsightsMask?: boolean;\n showCollectionMask?: boolean;\n showVideoCount?: boolean;\n}\n\nexport function SharedObjectImage(props: SharedObjectImageProps): JSX.Element {\n const ref = React.useCallback((el: HTMLDivElement) => {\n if (!el || !props.fixedHeight)\n return;\n\n el.style.width = `${el.offsetHeight * getImageRatio(props.object)}px`;\n }, []);\n\n const useVideoThumbnail = VideoHelper.isVideoType(props.object);\n\n const {\n image,\n imageType,\n imageClassName,\n imageFallbackComponent\n } = getImageProps(props.object);\n\n return (\n <div className='d-flex align-items-center justify-content-center w-100 h-100'>\n <div ref={ref} className={props.fixedHeight ? 'h-100' : 'w-100'}>\n {useVideoThumbnail &&\n <div className={`${styles.thumbnailContainer} position-relative`}>\n {props.showInsightsMask && <InsightsMask />}\n <AppLink appLink={props.appLink}>\n <VideoThumbnail\n video={props.object}\n imageOptions={props.imageOptions}\n textPosition={ThumbnailTextPosition.Independent}\n type='cosmetic'\n hideDuration\n hideMask\n />\n </AppLink>\n {!!props.requireMarking && (\n <div className={`${props.showInsightsMask && styles.requireMarking} position-absolute bottom-0 end-0 z-1 m-2`}>\n <div className={`${styles.badge} d-flex align-items-center bg-light-ultramarine text-ultramarine fw-semibold rounded-pill w-fit mt-1 px-2`}>\n <Text namespace={namespace} phrase='requireMarking' options={{ smartCount: props.requireMarking }} />\n </div>\n </div>\n )}\n </div>\n }\n {!useVideoThumbnail &&\n <>\n {'videos' in (props.object as Playlist | Series) ? (\n <CollectionThumbnail\n collection={props.object}\n imageOptions={props.imageOptions}\n appLink={props.appLink}\n analyticsData={{\n id: props.object.id,\n name: props.object.name\n }}\n analyticsOptions={{\n entity: ShareViewHelper.getAnalyticsEntity(props.object.type),\n actionType: UserAction.Click,\n location: props.locationContext\n }}\n showMask={props.showCollectionMask}\n showVideoCount={props.showVideoCount}\n />\n ) : (\n <BaseImage\n data={image?.url}\n imageType={imageType}\n imageOptions={props.imageOptions}\n appLink={props.appLink}\n className={imageClassName}\n analyticsData={{\n id: props.object.id,\n name: props.object.name\n }}\n analyticsOptions={{\n entity: ShareViewHelper.getAnalyticsEntity(props.object.type),\n actionType: UserAction.Click,\n location: props.locationContext\n }}\n >\n {imageFallbackComponent}\n </BaseImage>\n )}\n </>\n }\n </div>\n </div>\n );\n}","import { format } from 'timeago.js';\n\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { CheckMarkStatus } from 'libs/shared/components/check-mark-button/CheckMarkButton';\nimport { ShareActivityStatus } from 'libs/shared/enums/ShareActivityStatus';\n\ninterface ObjectWithDateShared {\n dateShared: string;\n}\n\ntype GroupedByDate<T extends ObjectWithDateShared> = { [date: string]: T[] };\n\nexport const ShareHelper = {\n groupByDateShared<T extends ObjectWithDateShared>(data: T[]): GroupedByDate<T> {\n const dateToObjectMapping: GroupedByDate<T> = ArrayHelper.groupBy(data, 'dateShared');\n\n const sortedDates = Object.keys(dateToObjectMapping).sort().reverse();\n\n // Create a sorted mapping between dates and the \"ObjectWithDateShared\" objects\n return sortedDates.reduce((acc: GroupedByDate<T>, date) => {\n const heading = format(date);\n\n if (!acc[heading])\n acc[heading] = [];\n\n acc[heading] = acc[heading].concat(dateToObjectMapping[date]);\n return acc;\n }, {});\n },\n\n mapActivityStatusToCheckMarkStatus(activityStatus: ShareActivityStatus): CheckMarkStatus {\n switch (activityStatus) {\n case ShareActivityStatus.Complete:\n return CheckMarkStatus.Complete;\n case ShareActivityStatus.Incomplete:\n return CheckMarkStatus.Incomplete;\n case ShareActivityStatus.None:\n return CheckMarkStatus.None;\n }\n },\n\n mapCheckMarkStatusToActivityStatus(checkMarkStatus: CheckMarkStatus): ShareActivityStatus {\n switch (checkMarkStatus) {\n case CheckMarkStatus.Complete:\n return ShareActivityStatus.Complete;\n case CheckMarkStatus.Incomplete:\n return ShareActivityStatus.Incomplete;\n case CheckMarkStatus.None:\n return ShareActivityStatus.None;\n }\n }\n};","// extracted by mini-css-extract-plugin\nexport default {\"thumbnailTitle\":\"OsWjL\"};","import React from 'react';\n\nimport { Core } from 'libs/common/core';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\n\nimport styles from './collection-thumbnail-title.scss';\n\ninterface BaseCollectionThumbnailTitleProps {\n title: string;\n}\n\nfunction BaseCollectionThumbnailTitle(props: BaseCollectionThumbnailTitleProps): JSX.Element {\n return (\n <h3 title={props.title} className='h6'>{props.title}</h3>\n );\n}\n\ninterface CollectionThumbnailTitleProps extends BaseCollectionThumbnailTitleProps {\n appLink: Core.AppLink;\n}\n\nexport function CollectionThumbnailTitle(props: CollectionThumbnailTitleProps) {\n if (!props.appLink) {\n return (\n <BaseCollectionThumbnailTitle {...props} />\n );\n }\n \n return (\n <AppLink appLink={props.appLink} className={`${styles.thumbnailTitle}`}>\n <BaseCollectionThumbnailTitle {...props} />\n </AppLink>\n );\n}\n","// extracted by mini-css-extract-plugin\nexport default {\"badge\":\"M4zat\",\"mask\":\"r0Ztg\",\"thumbnailContainer\":\"uD9dz\"};","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { AnalyticsOptions, EntityType, UserAction } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { CollectionThumbnailTitle } from 'libs/shared/components/thumbnails/collection/title/CollectionThumbnailTitle';\nimport { VideoThumbnail } from 'libs/shared/components/thumbnails/video/VideoThumbnail';\nimport { TitleSubText } from 'libs/shared/components/title-sub-text/TitleSubText';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { ThumbnailTextPosition } from 'libs/shared/enums/ThumbnailTextPosition';\nimport { Playlist, Series } from 'libs/shared/interfaces';\nimport { ImageOptions } from 'libs/shared/utils/ImageHelper';\nimport { MasterTypeHelper } from 'libs/shared/utils/MasterTypeHelper';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport styles from './collection-thumbnail.scss';\n\nconst namespace = 'shared.collectionThumbnail';\n\ntype SupportedContentType = Playlist | Series;\n\ninterface CollectionThumbnailProps {\n appLink?: Core.AppLink\n collection: SupportedContentType;\n imageOptions?: ImageOptions;\n analyticsData?: HashObject;\n analyticsOptions?: AnalyticsOptions;\n showMask?: boolean;\n showVideoCount?: boolean;\n title?: string;\n titleAppLink?: Core.AppLink;\n subText?: string;\n subTextAppLink?: Core.AppLink;\n hoverText?: string;\n}\n\nexport function CollectionThumbnail(props: CollectionThumbnailProps) {\n function getFirstVideo() {\n let collectionVideos = props.collection?.videos;\n\n if (!collectionVideos)\n return;\n\n if (!collectionVideos.count && props.collection.typeId === MasterType.Playlist) {\n const playlist = props.collection as Playlist;\n\n if (playlist.clips.count)\n collectionVideos = playlist.clips;\n\n if (playlist.interactives.count)\n collectionVideos = playlist.interactives;\n }\n\n return ArrayHelper.first(collectionVideos.data);\n }\n\n function getVideoCount() {\n let totalCount = 0;\n\n if (props.collection.videos && props.collection.videos.count) {\n totalCount += props.collection.videos.count;\n }\n\n if (props.collection.typeId === MasterType.Playlist) {\n const playlist = props.collection as Playlist;\n\n if (playlist.interactives?.count)\n totalCount += playlist.interactives.count;\n\n if (playlist.clips?.count)\n totalCount += playlist.clips.count;\n }\n\n return totalCount;\n }\n\n function getEntityType(collection: SupportedContentType) {\n if (MasterTypeHelper.isType<Playlist>(collection, MasterType.Playlist)) {\n return EntityType.Playlist;\n }\n\n if (MasterTypeHelper.isType<Series>(collection, MasterType.Series)) {\n return EntityType.Series;\n }\n }\n\n const firstVideo = getFirstVideo();\n const videoCount = getVideoCount();\n const showTexts = props.title?.length || props.subText?.length;\n\n const analyticsData = {\n id: props.collection.id.toString(),\n name: props.collection.name,\n\n ...props.analyticsData\n };\n\n const analyticsOptions = {\n actionType: UserAction.Click,\n entity: getEntityType(props.collection),\n \n ...props.analyticsOptions\n };\n\n return (\n <div>\n <div className={`position-relative ${styles.thumbnailContainer} z-1`}>\n <AppLink\n appLink={props.appLink}\n analyticsData={analyticsData}\n analyticsOptions={analyticsOptions}\n preventFocus\n >\n {props.showMask &&\n <div className={`${styles.mask} position-absolute w-100 h-100 rounded-3 bg-dark bg-gradient z-1 bg-opacity-50 pointer-events-none`}>\n <div className={`${styles.badge} d-flex align-items-center w-fit flex-grow-0 bg-dark rounded-pill ps-1 m-2`}>\n <SvgContainer svgName={cvSvgLibrary.Play} className='svg-container text-white' />\n <p className='d-inline fw-medium text-white mb-0'>\n {props.hoverText?.length ?\n <span>{props.hoverText}</span> :\n <Text namespace={namespace} phrase='playAll' />\n }\n </p>\n </div>\n </div>\n }\n\n {firstVideo &&\n <VideoThumbnail\n video={firstVideo}\n imageOptions={props.imageOptions}\n textPosition={ThumbnailTextPosition.Independent}\n type='cosmetic'\n hideMask\n hideRating\n hideDuration\n hideVideoTypeBadge\n />\n }\n\n {!firstVideo &&\n <div className='ratio ratio-16x9 bg-light rounded-3'>\n <div className='d-flex justify-content-center align-items-center'>\n <SvgContainer svgName={cvSvgLibrary.Play} className='w-33 opacity-25 text-gray-400' />\n </div>\n </div>\n }\n\n {props.showVideoCount &&\n <div className={`${styles.badge} d-flex align-items-center w-fit bg-dark bg-opacity-75 rounded-pill position-absolute bottom-0 end-0 ps-1 m-2`}>\n <SvgContainer svgName={cvSvgLibrary.Series} className='svg-container text-white me-1' />\n <p className='d-inline fw-semibold text-white mb-0'>\n <Text namespace={namespace} phrase='videos' options={{ count: videoCount, smartCount: videoCount }} />\n </p>\n </div>\n }\n </AppLink>\n\n </div>\n \n {showTexts &&\n <div className='mt-2 d-flex flex-column'>\n {props.subText &&\n <TitleSubText title={props.subText} appLink={props.subTextAppLink}>\n {props.subText}\n </TitleSubText>\n }\n {props.title &&\n <CollectionThumbnailTitle\n title={props.collection.name}\n appLink={props.titleAppLink}\n />\n }\n </div>\n }\n </div>\n );\n}","import { useEffect } from 'react';\n\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\n\nconst SCROLL_TOLERANCE = 400; // value in px\n\ninterface UseInfiniteScrollOptions {\n fetchNextPage: () => void;\n hasMore: boolean;\n isFetching: boolean;\n scrollContainer?: HTMLElement;\n}\n\nexport function useInfiniteScroll(options: UseInfiniteScrollOptions): void {\n const handleScroll = (): void => {\n if (options.isFetching)\n return;\n\n if (!options.scrollContainer) {\n const currentScrollHeight = window.innerHeight + document.documentElement.scrollTop;\n \n const totalHeight = document.documentElement.scrollHeight - SCROLL_TOLERANCE;\n \n if (currentScrollHeight < totalHeight)\n return;\n } else {\n const { scrollContainer } = options;\n const currentScrollHeight = scrollContainer.getBoundingClientRect().height + scrollContainer.scrollTop;\n \n const totalHeight = scrollContainer.scrollHeight - SCROLL_TOLERANCE;\n \n if (currentScrollHeight < totalHeight)\n return;\n }\n\n options.fetchNextPage();\n };\n\n useEffect(() => {\n const onScroll = FunctionHelper.throttle(handleScroll, 200);\n\n const scrollContainer = options.scrollContainer || window;\n\n if (options.hasMore)\n scrollContainer.addEventListener('scroll', onScroll);\n\n return () => scrollContainer.removeEventListener('scroll', onScroll);\n }, [ options.hasMore, options.fetchNextPage, options.scrollContainer ]);\n}","import { useEffect, useState } from 'react';\n\nimport { HttpStatus, HttpStatusClass } from 'libs/common/backbone/enums/HttpStatus';\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { BaseObject, BasePaginatedCollection } from 'libs/shared/interfaces';\n\nimport { useInfiniteScroll } from './UseInfiniteScroll';\nimport { useSelectAllPages } from './UseSelectAllPages';\n\nexport interface UseInfiniteListResult<T extends BaseObject> {\n items: T[];\n hasMore: boolean;\n isFetching: boolean;\n nextCursor: string;\n totalItems?: number;\n hasFirstPageCompleted: boolean;\n}\n\n/**\n * Hook to extract an infinite list from the application state,\n * save it locally in state and only update when new data\n * is fetched.\n * \n * @param getRequest - callback function to get the request for each page.\n * Can be false if the request requires data that hasn't yet been fetched - e.g. user id.\n * \n * @param fetchNext - callback function to fetch a page.\n * Can be false if the request requires data that hasn't yet been fetched - e.g. user id.\n */\nexport function useInfiniteList<TObject = BaseObject, TResponse = BasePaginatedCollection<TObject>>(\n getRequest: ((cursor?: string) => Flight.Request) | false,\n fetchNext: ((cursor?: string) => void) | false,\n onError?: (pageNumber: number, statusCode: HttpStatus) => void,\n getItems?: (responseData: TResponse) => TObject[],\n getCursor?: (responseData: TResponse) => string,\n scrollContainer?: HTMLElement\n): UseInfiniteListResult<TObject> {\n const [ pagesFetched, setPagesFetched ] = useState(0);\n\n const fetchNextFn = fetchNext as (cursor?: string) => void;\n\n function getKey(cursor?: string): string {\n if (!getRequest)\n return null;\n\n const request = getRequest(cursor);\n\n if (!request)\n return null;\n\n return request.key;\n }\n\n const response = useSelectAllPages<TObject, TResponse>(\n getKey,\n getItems,\n getCursor\n );\n\n function fetchNextPage(): void {\n if (!fetchNext || !getRequest || !response)\n return;\n\n setPagesFetched(currentVal => currentVal + 1);\n return fetchNextFn(response.nextCursor);\n }\n\n useInfiniteScroll({\n fetchNextPage,\n hasMore: !!response?.nextCursor,\n isFetching: response?.isFetching,\n scrollContainer\n });\n\n useEffect(() => {\n if (!response)\n return;\n\n if (response.shouldInitialFetch && fetchNext) {\n fetchNextFn();\n setPagesFetched(currentVal => currentVal + 1);\n }\n }, [ response?.shouldInitialFetch, fetchNext ]);\n\n useEffect(() => {\n if (!response?.statusCode || !FunctionHelper.isFunction(onError))\n return;\n\n const httpStatusClass: HttpStatusClass = +(response.statusCode?.toString()?.substr(0, 1));\n\n if (httpStatusClass !== HttpStatusClass.ClientError && httpStatusClass !== HttpStatusClass.ServerError)\n return;\n\n onError(pagesFetched, response.statusCode);\n }, [response?.statusCode]);\n\n return {\n items: response?.items,\n hasMore: !!response?.nextCursor,\n nextCursor: response?.nextCursor,\n isFetching: response?.isFetching,\n totalItems: response?.totalItems,\n hasFirstPageCompleted: response?.hasFirstPageCompleted\n };\n}","var EN_US = ['second', 'minute', 'hour', 'day', 'week', 'month', 'year'];\nexport default function (diff, idx) {\n if (idx === 0)\n return ['just now', 'right now'];\n var unit = EN_US[Math.floor(idx / 2)];\n if (diff > 1)\n unit += 's';\n return [diff + \" \" + unit + \" ago\", \"in \" + diff + \" \" + unit];\n}\n//# sourceMappingURL=en_US.js.map","var ZH_CN = ['秒', '分钟', '小时', '天', '周', '个月', '年'];\nexport default function (diff, idx) {\n if (idx === 0)\n return ['刚刚', '片刻后'];\n var unit = ZH_CN[~~(idx / 2)];\n return [diff + \" \" + unit + \"\\u524D\", diff + \" \" + unit + \"\\u540E\"];\n}\n//# sourceMappingURL=zh_CN.js.map","/**\n * Created by hustcc on 18/5/20.\n * Contract: i@hust.cc\n */\n/**\n * All supported locales\n */\nvar Locales = {};\n/**\n * register a locale\n * @param locale\n * @param func\n */\nexport var register = function (locale, func) {\n Locales[locale] = func;\n};\n/**\n * get a locale, default is en_US\n * @param locale\n * @returns {*}\n */\nexport var getLocale = function (locale) {\n return Locales[locale] || Locales['en_US'];\n};\n//# sourceMappingURL=register.js.map","/**\n * Created by hustcc on 18/5/20.\n * Contract: i@hust.cc\n */\nvar SEC_ARRAY = [\n 60,\n 60,\n 24,\n 7,\n 365 / 7 / 12,\n 12,\n];\n/**\n * format Date / string / timestamp to timestamp\n * @param input\n * @returns {*}\n */\nexport function toDate(input) {\n if (input instanceof Date)\n return input;\n // @ts-ignore\n if (!isNaN(input) || /^\\d+$/.test(input))\n return new Date(parseInt(input));\n input = (input || '')\n // @ts-ignore\n .trim()\n .replace(/\\.\\d+/, '') // remove milliseconds\n .replace(/-/, '/')\n .replace(/-/, '/')\n .replace(/(\\d)T(\\d)/, '$1 $2')\n .replace(/Z/, ' UTC') // 2017-2-5T3:57:52Z -> 2017-2-5 3:57:52UTC\n .replace(/([+-]\\d\\d):?(\\d\\d)/, ' $1$2'); // -04:00 -> -0400\n return new Date(input);\n}\n/**\n * format the diff second to *** time ago, with setting locale\n * @param diff\n * @param localeFunc\n * @returns\n */\nexport function formatDiff(diff, localeFunc) {\n /**\n * if locale is not exist, use defaultLocale.\n * if defaultLocale is not exist, use build-in `en`.\n * be sure of no error when locale is not exist.\n *\n * If `time in`, then 1\n * If `time ago`, then 0\n */\n var agoIn = diff < 0 ? 1 : 0;\n /**\n * Get absolute value of number (|diff| is non-negative) value of x\n * |diff| = diff if diff is positive\n * |diff| = -diff if diff is negative\n * |0| = 0\n */\n diff = Math.abs(diff);\n /**\n * Time in seconds\n */\n var totalSec = diff;\n /**\n * Unit of time\n */\n var idx = 0;\n for (; diff >= SEC_ARRAY[idx] && idx < SEC_ARRAY.length; idx++) {\n diff /= SEC_ARRAY[idx];\n }\n /**\n * Math.floor() is alternative of ~~\n *\n * The differences and bugs:\n * Math.floor(3.7) -> 4 but ~~3.7 -> 3\n * Math.floor(1559125440000.6) -> 1559125440000 but ~~1559125440000.6 -> 52311552\n *\n * More information about the performance of algebraic:\n * https://www.youtube.com/watch?v=65-RbBwZQdU\n */\n diff = Math.floor(diff);\n idx *= 2;\n if (diff > (idx === 0 ? 9 : 1))\n idx += 1;\n return localeFunc(diff, idx, totalSec)[agoIn].replace('%s', diff.toString());\n}\n/**\n * calculate the diff second between date to be formatted an now date.\n * @param date\n * @param relativeDate\n * @returns {number}\n */\nexport function diffSec(date, relativeDate) {\n var relDate = relativeDate ? toDate(relativeDate) : new Date();\n return (+relDate - +toDate(date)) / 1000;\n}\n/**\n * nextInterval: calculate the next interval time.\n * - diff: the diff sec between now and date to be formatted.\n *\n * What's the meaning?\n * diff = 61 then return 59\n * diff = 3601 (an hour + 1 second), then return 3599\n * make the interval with high performance.\n **/\nexport function nextInterval(diff) {\n var rst = 1, i = 0, d = Math.abs(diff);\n for (; diff >= SEC_ARRAY[i] && i < SEC_ARRAY.length; i++) {\n diff /= SEC_ARRAY[i];\n rst *= SEC_ARRAY[i];\n }\n d = d % rst;\n d = d ? rst - d : rst;\n return Math.ceil(d);\n}\n//# sourceMappingURL=date.js.map","import { formatDiff, diffSec } from './utils/date';\nimport { getLocale } from './register';\n/**\n * format a TDate into string\n * @param date\n * @param locale\n * @param opts\n */\nexport var format = function (date, locale, opts) {\n // diff seconds\n var sec = diffSec(date, opts && opts.relativeDate);\n // format it with locale\n return formatDiff(sec, getLocale(locale));\n};\n//# sourceMappingURL=format.js.map","/**\n * Created by hustcc on 18/5/20.\n * Contract: i@hust.cc\n */\nimport en_US from './lang/en_US';\nimport zh_CN from './lang/zh_CN';\nimport { register } from './register';\nregister('en_US', en_US);\nregister('zh_CN', zh_CN);\nexport { format } from './format';\nexport { render, cancel } from './realtime';\nexport { register };\n//# sourceMappingURL=index.js.map"],"names":["namespace","BASE_IMAGE_CLASS_NAME","InsightsMask","className","SharedObjectImage","props","ref","el","object","fixedHeight","style","width","offsetHeight","VideoHelper","typeId","MasterType","useVideoThumbnail","image","ImageHelper","imageType","imageClassName","imageFallbackComponent","ImageFallback","type","svgContainerClassName","url","getBgColorClass","name","extraClasses","getImageProps","showInsightsMask","AppLink","appLink","VideoThumbnail","video","imageOptions","textPosition","ThumbnailTextPosition","hideDuration","hideMask","requireMarking","Text","phrase","options","smartCount","CollectionThumbnail","collection","analyticsData","id","analyticsOptions","entity","ShareViewHelper","actionType","location","locationContext","showMask","showCollectionMask","showVideoCount","BaseImage","data","defaultProps","size","ShareHelper","groupByDateShared","dateToObjectMapping","Object","keys","sort","reverse","reduce","acc","date","heading","concat","mapActivityStatusToCheckMarkStatus","activityStatus","mapCheckMarkStatusToActivityStatus","checkMarkStatus","BaseCollectionThumbnailTitle","title","CollectionThumbnailTitle","firstVideo","collectionVideos","videos","count","playlist","clips","interactives","ArrayHelper","getFirstVideo","videoCount","totalCount","getVideoCount","showTexts","length","subText","toString","MasterTypeHelper","preventFocus","SvgContainer","svgName","hoverText","hideRating","hideVideoTypeBadge","TitleSubText","subTextAppLink","titleAppLink","SCROLL_TOLERANCE","useInfiniteList","getRequest","fetchNext","onError","getItems","getCursor","scrollContainer","handleScroll","useState","pagesFetched","setPagesFetched","fetchNextFn","response","cursor","request","key","fetchNextPage","currentVal","nextCursor","hasMore","isFetching","getBoundingClientRect","height","scrollTop","scrollHeight","window","innerHeight","document","documentElement","useEffect","onScroll","FunctionHelper","addEventListener","removeEventListener","shouldInitialFetch","statusCode","httpStatusClass","substr","HttpStatus","items","totalItems","hasFirstPageCompleted","EN_US","ZH_CN","Locales","register","locale","func","SEC_ARRAY","toDate","input","Date","isNaN","test","parseInt","trim","replace","format","opts","sec","relativeDate","diff","localeFunc","agoIn","totalSec","Math","abs","idx","floor","unit"],"sourceRoot":""}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[9040],{5255:(e,t,a)=>{a.d(t,{Y:()=>o});var n=a(20354),r=a(30439);function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function o(e){var t,a=n.a.useBasicFetch(e&&r.o.getAnonSessions(e));return(null===(t=a.data)||void 0===t?void 0:t.length)?a.data.reduce((function(e,t){return Object.assign(Object.assign({},e),(a={},n=t.sessionId,r=t,(n=function(e){var t=function(e){if("object"!=i(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var a=t.call(e,"string");if("object"!=i(a))return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==i(t)?t:t+""}(n))in a?Object.defineProperty(a,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):a[n]=r,a));var a,n,r}),{}):{}}},74901:(e,t,a)=>{function n(e){return function(e){if(Array.isArray(e))return r(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return r(e,t);var a={}.toString.call(e).slice(8,-1);return"Object"===a&&e.constructor&&(a=e.constructor.name),"Map"===a||"Set"===a?Array.from(e):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?r(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var a=0,n=Array(t);a<t;a++)n[a]=e[a];return n}a.d(t,{K:()=>i});var i=function(e){var t=[],a=[];return e.users&&t.push.apply(t,n(e.users)),e.classrooms&&a.push.apply(a,n(e.classrooms)),e.classroomGroups&&a.push.apply(a,n(e.classroomGroups)),{userId:t,groupId:a}}},94644:(e,t,a)=>{a.d(t,{r:()=>d});var n=a(50242),r=a(81886),i=a(67058),o=a(14553),s=a(49267),l=a(49075),c={notFound:i.d,forbidden:{rating:o.q,yearLevel:o.q,region:s.a,privacy:o.q},badRequest:l._,internalServerError:l._};function d(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(e){var i;i="number"==typeof e?e:e.status;var o=Object.assign(Object.assign({},c),t);i&&r.Q.Ry.isStatusCodeError(i)&&(i!==n.o.InternalServer?i!==n.o.NotFound?i!==n.o.Forbidden?a.badRequest||r.Q.Ry.throw(new o.badRequest):a.forbidden||r.Q.Ry.throw(new o.forbidden.privacy):a.notFound||r.Q.Ry.throw(new o.notFound):a.internalServerError||r.Q.Ry.throw(new l._))}}},17913:(e,t,a)=>{a.d(t,{u:()=>o});var n=a(97395),r=a(110),i=a(62875),o={individualEngagement:function(e,t,a,r){var o=Object.assign({objectId:e},t);return a&&(o.sharerId=a),r&&(o.includeAnonViews=!0),{url:n._.urlBuilder("{gateway}/v1/analytics/heat-map",o),key:(0,i.H)("engagement:".concat(e,":").concat(r),t,a),formatData:function(e){var t;return Object.assign(Object.assign({},e),{data:null===(t=e.data)||void 0===t?void 0:t.map((function(e){var t;return Object.assign(Object.assign({},e),{heatMap:null!==(t=e.heatMap)&&void 0!==t?t:[]})}))})},normalize:!1}},aggregateEngagement:function(e,t,a,r){var o=Object.assign({objectId:e},t);return a&&(o.sharerId=a),r&&(o.includeAnonViews=!0),{url:n._.urlBuilder("{gateway}/v1/analytics/heat-map/aggregations",o),key:(0,i.H)("aggregate:engagement:".concat(e,":").concat(r),t,a),formatData:function(e){var t;return Object.assign(Object.assign({},e),{heatMap:null!==(t=e.heatMap)&&void 0!==t?t:[]})},normalize:!1}},views:function(e,t,a,o){var s=Object.assign(Object.assign({},e),{timeOffset:r.O.getTimezoneOffset()});return t&&(s.objectId=t),a&&(s.sharerId=a),o&&(s.includeAnonViews=!0),{url:n._.urlBuilder("{gateway}/v1/analytics/video-views",s),key:(0,i.H)("video:views:".concat(t,":").concat(o),e,a),normalize:!1}}}},39902:(e,t,a)=>{a.d(t,{F:()=>v,f:()=>m});var n=a(32735),r=a(20354),i=a(75896);function o(e){return function(e){if(Array.isArray(e))return l(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||s(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function s(e,t){if(e){if("string"==typeof e)return l(e,t);var a={}.toString.call(e).slice(8,-1);return"Object"===a&&e.constructor&&(a=e.constructor.name),"Map"===a||"Set"===a?Array.from(e):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?l(e,t):void 0}}function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var a=0,n=Array(t);a<t;a++)n[a]=e[a];return n}function c(e){return c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},c(e)}function d(e,t,a){return(t=function(e){var t=function(e){if("object"!=c(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var a=t.call(e,"string");if("object"!=c(a))return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==c(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}var u=50;function m(e,t){var a=i.m.chunk(e,u).map((function(e){return t(i.m.uniq(e))})),n=r.a.useBasicFetchAll(a),o=i.m.flatten(n.data),s=n.data.length?o.reduce((function(e,t){return Object.assign(Object.assign({},e),d({},t.id,t))}),{}):null;return{itemsArr:o,items:s,isFetching:n.isFetching}}function v(e,t,a){var l,m,v,p,g=a||function(e){return"object"===c(e)?e.id:e},f=n.useRef(new Set),h=(v=n.useState([]),p=2,function(e){if(Array.isArray(e))return e}(v)||function(e,t){var a=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=a){var n,r,i,o,s=[],l=!0,c=!1;try{if(i=(a=a.call(e)).next,0===t){if(Object(a)!==a)return;l=!1}else for(;!(l=(n=i.call(a)).done)&&(s.push(n.value),s.length!==t);l=!0);}catch(e){c=!0,r=e}finally{try{if(!l&&null!=a.return&&(o=a.return(),Object(o)!==o))return}finally{if(c)throw r}}return s}}(v,p)||s(v,p)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),y=h[0],b=h[1];n.useEffect((function(){if(null==e?void 0:e.length){var a=[];e.forEach((function(e){var t=g(e);f.current.has(t)||(a.push(e),f.current.add(t))})),a.length&&b((function(e){return[].concat(o(e),o(i.m.chunk(a,u).map(t)))}))}}),[null==e?void 0:e.length]);var E=r.a.useBasicFetchAll(y),I=i.m.flatten(E.data),A=E.data.length?I.reduce((function(e,t){return Object.assign(Object.assign({},e),d({},g(t),t))}),{}):null;return{hasFirstRequestCompleted:!!(null===(m=null===(l=E.responses)||void 0===l?void 0:l[0])||void 0===m?void 0:m.hasCompleted),itemsArr:I,items:A,isFetching:E.isFetching}}},91286:(e,t,a)=>{a.d(t,{v:()=>o});var n=a(32735),r=a(94644);function i(e){return e.map((function(e){return e.statusCode})).join(":")}function o(e,t,a){var o=Array.isArray(e)?e:[e];(0,n.useEffect)((function(){o.forEach((function(e){(0,r.r)(e.statusCode,t,a)}))}),[i(o),t,a])}},62875:(e,t,a)=>{function n(e,t,a){var n="".concat(e,":").concat(t.start,":").concat(t.end),r=Array.isArray(t.userId)?t.userId.sort().join(":"):t.userId,i=Array.isArray(t.groupId)?t.groupId.sort().join(":"):t.groupId;return r&&(n+=":".concat(r)),i&&(n+=":".concat(i)),a&&(n+=":".concat(a)),n}a.d(t,{H:()=>n})},50782:(e,t,a)=>{a.d(t,{R:()=>A});var n=a(32735),r=a(82602),i=a(20354),o=a(74901),s=a(40003),l=a(30439),c=a(65853),d=a(64249),u=a(91693),m=a(83345),v=a(39151),p=a(1666),g=a(31949),f=a(17913),h=a(37802),y=a(35223),b=a(86099),E=a(24758),I="insights.shareInfo";function A(e){var t,a,A,w,S,j=i.a.useBasicFetch(v.L.config()),O=(0,h.r)(null).publicInteractiveAttempts,N=Object.assign(Object.assign({},(0,s.wO)((0,s.Hb)(),e.dateRangeAppLinkParams)),(0,o.K)(e.audienceAppLinkParams)),k=i.a.useBasicFetch(g.N.currentUser()),F=i.a.useBasicFetch(e.video&&l.o.getShareLinkByObjectId(e.video.id)),C=i.a.useBasicFetch(e.video&&l.o.getSentDirectShareByObjectId(e.video.id)),U=i.a.useBasicFetch((null===(t=k.data)||void 0===t?void 0:t.customerId)&&d.I.getDirectShareRecipientsRequest(k.data.customerId,C.data)),B=i.a.useBasicFetch(k.data&&e.video&&f.u.views(N,e.video.id,k.data.id,O)),L=i.a.useBasicFetch(e.video&&l.o.getPrivacy(e.video.id)),R=i.a.useBasicFetch((null===(a=k.data)||void 0===a?void 0:a.isAuthenticated)&&p.h.yearGroups(k.data.customerId)),P=F.hasCompleted&&!F.data&&C.hasCompleted&&!C.data,T=F.hasCompleted&&F.data||C.hasCompleted&&C.data&&(!F.data||L.data)&&(!F.data||R.data)&&U.data&&B.data,x=F.data&&L.data&&R.data&&c.R.getIconAndText({entity:e.video,entityTypeId:e.video.typeId,hasStudentExp:!1,isPasswordProtected:F.data.isPasswordProtected,linkExpireDate:F.data.linkExpireDate,privacy:L.data,status:F.data.status,yearGroups:R.data}),V=n.useMemo((function(){var e;return null===(e=B.data)||void 0===e?void 0:e.data.reduce((function(e,t){return t.count+e}),0)}),[B.data]),M=(null===(A=C.data)||void 0===A?void 0:A.dateCreated)||(null===(w=F.data)||void 0===w?void 0:w.dateCreated);return n.createElement("div",{className:"mb-4"},T&&n.createElement(n.Fragment,null,n.createElement("h2",{className:"h4"},n.createElement(m.x,{namespace:I,phrase:"shareInfo"})),n.createElement("div",{className:"d-flex border p-3 rounded-3 align-items-center justify-content-between"},n.createElement("div",{className:"d-flex align-items-center gap-2"},n.createElement(E.A,{shareRecipients:U.data,imageCdnUrl:null===(S=j.data)||void 0===S?void 0:S.imageCdnUrl,hasShareLink:!!F.data,maxAvatars:4,shareLinkText:null==x?void 0:x.text}),"·",n.createElement("p",{className:"mb-0"},(0,r.WU)(M)),!!V&&n.createElement(n.Fragment,null,"·",n.createElement("p",{className:"mb-0"},n.createElement(m.x,{namespace:I,phrase:"views",options:{smartCount:V}})))),n.createElement(u.h,{appLink:(0,b.YK)(e.video),svgName:y.vn.Share,className:"btn btn-outline-dark"},n.createElement(m.x,{namespace:I,phrase:"share"})))),!P&&!T&&n.createElement(n.Fragment,null,n.createElement("div",{className:"h4 partial-loading-background w-25"}," "),n.createElement("div",{className:"p-3 rounded partial-loading-background"},n.createElement("p",{className:"mb-1"}," "))))}},96049:(e,t,a)=>{a.r(t),a.d(t,{VideoInsightsOverviewView:()=>X});var n=a(32735),r=a(23481),i=a(2948),o=a(20354),s=a(75896),l=a(51870),c=a(50916),d=a(84621),u=a(98551),m=a(35223),v=r.T.encloseNamespace("shared.insightStudentsNotWatched");function p(e){var t,a=(null===(t=e.students)||void 0===t?void 0:t.filter((function(t){var a;return!(null===(a=e.watchedIds)||void 0===a?void 0:a.includes(t.id))})))||[];return n.createElement(d.L,{title:v("title"),svgName:m.vn.Puzzle,svgClassName:"bg-light-teal text-teal"},n.createElement(u.y,{students:a,imageCdnUrl:e.imageCdnUrl,imageUrl:e.imageUrl,description:v("studentsDisplay"),anonymiseUsers:e.anonymiseUsers}))}var g=r.T.encloseNamespace("shared.insightStudentsWatched");function f(e){return n.createElement(d.L,{title:g("title"),svgName:m.vn.Flag,svgClassName:"bg-light-indigo text-indigo",count:e.students.length},n.createElement(u.y,{students:e.students,imageCdnUrl:e.imageCdnUrl,imageUrl:e.imageUrl,description:g("studentsDisplay"),appLink:e.heatmapAppLink,appLinkText:g("viewAll"),anonymiseUsers:e.anonymiseUsers}))}var h=a(5255),y=a(26025),b=a(26136),E=a(74901),I=a(40003),A=a(30439),w=a(83345),S=a(38143),j=a(4594),O=a(16714),N=a(39151),k=a(31949),F=a(17913),C=a(39902),U=a(91286),B=a(93322),L=a(22902),R=a(79612),P=a(37802),T=a(31908),x=a(99742),V=a(88630),M=a(26203),_=a(53214),D=a(10447),q=a(50782);const H={partialInsights:"qm6HY"};function W(){return n.createElement("div",null,n.createElement("h2",{className:"h4 w-25 partial-loading-background"}," "),n.createElement("div",{className:"row g-3 mb-5"},n.createElement("div",{className:"col-12"},n.createElement("div",{className:"".concat(H.partialInsights," rounded partial-loading-background")}))),n.createElement("h2",{className:"h4 w-25 partial-loading-background"}," "),n.createElement("div",{className:"row g-3 mb-5"},n.createElement("div",{className:"col-6"},n.createElement("div",{className:"".concat(H.partialInsights," rounded partial-loading-background")})),n.createElement("div",{className:"col-6"},n.createElement("div",{className:"".concat(H.partialInsights," rounded partial-loading-background")}))))}var z=a(14070),G=a(97291);function Q(e){return function(e){if(Array.isArray(e))return $(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||Y(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Y(e,t){if(e){if("string"==typeof e)return $(e,t);var a={}.toString.call(e).slice(8,-1);return"Object"===a&&e.constructor&&(a=e.constructor.name),"Map"===a||"Set"===a?Array.from(e):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?$(e,t):void 0}}function $(e,t){(null==t||t>e.length)&&(t=e.length);for(var a=0,n=Array(t);a<t;a++)n[a]=e[a];return n}var K="insights.videoInsightsOverview",J=r.T.encloseNamespace(K);function X(e){var t,a,r,d,u,m,v,g,H,$=(g=(0,i.D)(S.g.ANONYMISE_USERS),H=1,function(e){if(Array.isArray(e))return e}(g)||function(e,t){var a=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=a){var n,r,i,o,s=[],l=!0,c=!1;try{if(i=(a=a.call(e)).next,0===t){if(Object(a)!==a)return;l=!1}else for(;!(l=(n=i.call(a)).done)&&(s.push(n.value),s.length!==t);l=!0);}catch(e){c=!0,r=e}finally{try{if(!l&&null!=a.return&&(o=a.return(),Object(o)!==o))return}finally{if(c)throw r}}return s}}(g,H)||Y(g,H)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}())[0];(0,B.F)();var X=(0,P.r)(null),Z=X.hasClassrooms,ee=X.hasShareFlowV2,te=(0,L.T)().hasPermissions,ae=(0,P.r)(null).publicInteractiveAttempts,ne=o.a.useBasicFetch(k.N.currentUser()),re=o.a.useBasicFetch(N.L.config()),ie=T.M.getVideoRequest(e.videoId,e.typeId),oe=o.a.useBasicFetch(ie),se=y.B.getAudienceAppLinkParams(),le=y.B.getDateRangeAppLinkParams(),ce=Object.assign(Object.assign({},(0,I.wO)((0,I.Hb)(),le)),(0,E.K)(se));(0,R.M)({title:oe.data?J("pageTitle",{video:null===(t=oe.data)||void 0===t?void 0:t.name}):null}),(0,U.v)(oe);var de=o.a.useBasicFetch(ne.data&&F.u.aggregateEngagement(e.videoId,ce,ne.data.id,ae)),ue=1===(null===(a=se.classrooms)||void 0===a?void 0:a.length)&&!(null===(r=se.classroomGroups)||void 0===r?void 0:r.length),me=o.a.useBasicFetch(ue&&V.F.getClassroomStudents(s.m.first(se.classrooms))),ve=(0,C.f)((null===(d=de.data)||void 0===d?void 0:d.userIds)||[],(function(e){return A.o.getRecipientsById(e,ne.data.customerId)})),pe=o.a.useBasicFetch(ne.data&&F.u.views(ce,e.videoId,ne.data.id,ae)),ge=o.a.useBasicFetch(A.o.getShareLinkByObjectId(e.videoId)),fe=o.a.useBasicFetch(A.o.getSentDirectShareByObjectId(e.videoId)),he=(0,h.Y)(null===(u=ge.data)||void 0===u?void 0:u.id),ye=!(!ge.data&&!fe.data);function be(){var e,t,a,n,r;if(!(null===(e=de.data)||void 0===e?void 0:e.userIds)&&!(null===(t=de.data)||void 0===t?void 0:t.sessionIds))return[];var i=null!==(a=ve.itemsArr)&&void 0!==a?a:[],o=(null===(r=null===(n=de.data)||void 0===n?void 0:n.sessionIds)||void 0===r?void 0:r.map((function(e){return(0,b.jP)(e,he)})))||[];return[].concat(Q(i),Q(o))}var Ee=ne.data&&re.data&&oe.data&&de.data&&(!ue||me.data),Ie=Object.assign(Object.assign({},se),le),Ae=function(e,t,a){return{heatmapAppLink:{application:G.O.INSIGHTS,action:t===j.E.Clip?z.e.Insights.CLIP_HEATMAP:z.e.Insights.VIDEO_HEATMAP,args:[e],params:a}}}(e.videoId,e.typeId,Ie);return n.createElement("div",{className:"px-3"},n.createElement(M.j,{video:oe.data,dateRangeAppLinkParams:le,tabs:function(){var e,t,a;return(null===(e=oe.data)||void 0===e?void 0:e.typeId)===j.E.Clip?(0,D.$o)(null===(t=oe.data)||void 0===t?void 0:t.id,"insights",Ie):(0,D.$6)(null===(a=oe.data)||void 0===a?void 0:a.id,"insights",Ie)}(),hasAnalytics:te(O.C.ViewCustomerAnalytics),analyticsWebUrl:null===(m=re.data)||void 0===m?void 0:m.analyticsWebUrl,hasShareFlowV2:ee,shareId:e.shareId}),n.createElement(q.R,{audienceAppLinkParams:se,dateRangeAppLinkParams:le,video:oe.data}),!Ee&&n.createElement(W,null),Ee&&n.createElement(_.u,{video:oe.data,hasShared:ye,hasShareFlowV2:ee,shareId:e.shareId},n.createElement("section",{className:"mb-5"},n.createElement("h2",{className:"h4"},n.createElement(w.x,{namespace:K,phrase:"studentViewing"}),n.createElement("span",null,": ",be().length,me.data?"/".concat(me.data.data.length):"")),n.createElement("div",{className:"row g-3"},ue&&n.createElement("div",{className:"col-12 col-md"},n.createElement(p,{students:me.data.data,watchedIds:de.data.userIds,imageCdnUrl:re.data.imageCdnUrl,heatmapAppLink:Ae.heatmapAppLink,imageUrl:x.W.Insights.AVATAR,anonymiseUsers:$})),n.createElement("div",{className:"col-12 col-md"},n.createElement(f,{students:be(),imageCdnUrl:re.data.imageCdnUrl,heatmapAppLink:Ae.heatmapAppLink,imageUrl:x.W.Insights.AVATAR,anonymiseUsers:$})))),n.createElement("section",{className:"mb-5"},n.createElement("h2",{className:"h4"},n.createElement(w.x,{namespace:K,phrase:Z?"classEngagement":"engagement"})),n.createElement("div",{className:"row g-3"},n.createElement("div",{className:"col-12 col-md-6"},n.createElement(l.i,{osCount:null===(v=pe.data)||void 0===v?void 0:v.osCount})),n.createElement("div",{className:"col-12 col-md-6"},n.createElement(c.b,{engagement:de.data,heatmapAppLink:Ae.heatmapAppLink}))))))}}}]);
|
|
2
|
-
//# sourceMappingURL=9040-9393c59004-lite.chunk.js.map
|