This commit is contained in:
janisslsm committed 2026-11-01 12:12:55 +02:00
1 parent 1781d25a15
commit 732c0ad767
33051 files changed
+2591613 -3019689

No files matched your search

@@ -0,0 +1,213 @@
// Metro module 14149 (f14150).
import * as Module19 from "react";
import { useState, useCallback, useContext, useLayoutEffect, useEffect, useMemo } from "react";
import { View, StyleSheet } from "react-native";
import { AnalyticEvents } from "../../../../Constants";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import VideoQuestModalContext, { useVideoQuestModalContext } from "./VideoQuestModalContext";
import { lockOrientation, restoreDefaultOrientation } from "../../../device/native/DeviceOrientation";
import { trackQuestEvent } from "../../lib/analytics/AnalyticsActions";
import { QuestDockGestureContext, QuestDockGestureContextProvider } from "../QuestDock/QuestDockGestureContext";
import useStateFromSharedValue from "../../../reanimated/native/useStateFromSharedValue";
import * as _ReanimatedRexport from "../../../reanimated/ReanimatedRexport";
import { useSharedValue, useAnimatedStyle } from "../../../reanimated/ReanimatedRexport";
import * as _spring from "../../../../design/animation/reanimated/spring/spring";
import useSafeAreaInsets_native from "../../../safe_area/useSafeAreaInsets.native";
import ReanimatedNativeView from "../../../core/native/ReanimatedNativeView";
import QuestModalContentCloudBackground from "../QuestModalContentCloudBackground";
import { SafeAreaPaddingView } from "../../../../components_native/common/SafeAreaView";
import VideoQuestModalContentInProgress from "./VideoQuestModalContentInProgress";
import VideoQuestModalContentCompleted from "./VideoQuestModalContentCompleted";
import { showQuestUnavailableAlert } from "../QuestUtils.native";
import { useNonNullableQuest } from "../../hooks/QuestHooks";
import { BillableAdPlacementImpressionTrackerNative } from "../QuestContentImpressionTracker.native";
import { QuestContent } from "../../QuestTypes";
import { Modal } from "../../../../design/components/Modal/native/Modal.native";
let initialRouteName;
const BACKGROUND_ENTRANCE_ANIMATION_SPRING_CONFIG = {
mass: 1.9,
damping: 18,
stiffness: 80,
overshootClamping: true
};
let c9903_10 = {
WATCH_VIDEO: 0,
0: "WATCH_VIDEO",
POST_WATCH_VIDEO: 1,
1: "POST_WATCH_VIDEO"
};
const useStyles = createStyles({
wrapper: {
flexDirection: "column",
flexGrow: 1,
flexShrink: 1,
zIndex: 1
},
contentWrapper: {
flex: 1
},
contentBackground: {
...StyleSheet.absoluteFillObject,
borderRadius: Module712.radii.lg,
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWEST
},
modalContentWrapper: {
zIndex: 2
},
backgroundWrapper: {
...StyleSheet.absoluteFillObject,
borderRadius: Module712.radii.lg,
flex: 1,
overflow: "hidden",
pointerEvents: "none",
zIndex: 1
}
});
const __initData = {
code: "function VideoQuestModalTsx1(){const{withSpring,clamp,postWatchAnimationState,BACKGROUND_ENTRANCE_ANIMATION_SPRING_CONFIG,interpolate,CLOUDS_BACKGROUND_INVISIBLE_OFFSET_Y}=this.__closure;return{opacity:withSpring(clamp(postWatchAnimationState.get(),0,1),BACKGROUND_ENTRANCE_ANIMATION_SPRING_CONFIG),transform:[{translateY:withSpring(interpolate(postWatchAnimationState.get(),[0,1],[CLOUDS_BACKGROUND_INVISIBLE_OFFSET_Y,0]),BACKGROUND_ENTRANCE_ANIMATION_SPRING_CONFIG)}]};}"
};
const __initData2 = {
code: "function VideoQuestModalTsx2(){const{withSpring,interpolate,postWatchAnimationState,safeAreaInsets,BACKGROUND_ENTRANCE_ANIMATION_SPRING_CONFIG}=this.__closure;return{transform:[{translateY:withSpring(interpolate(postWatchAnimationState.get(),[0,1],[safeAreaInsets.top,0]),BACKGROUND_ENTRANCE_ANIMATION_SPRING_CONFIG)}],opacity:withSpring(postWatchAnimationState.get(),BACKGROUND_ENTRANCE_ANIMATION_SPRING_CONFIG)};}"
};
let Component = Module19.memo(function({ onClose: onClose2, initialStep, sourceQuestContent }) {
let sharedValue, c20956_10;
const videoQuestModalContext = useVideoQuestModalContext();
const { quest, videoSessionId } = videoQuestModalContext;
const r36 = quest.userStatus?.completedAt != null;
let c20956_4 = r36;
const [state, setState] = useState(initialStep == null ? r36 ? c9903_10.POST_WATCH_VIDEO : c9903_10.WATCH_VIDEO : initialStep);
const [isFullscreen, setState2] = useState(false);
const callback = useCallback((a0) => {
if (a0) {
lockOrientation("LANDSCAPE", true);
} else {
lockOrientation("PORTRAIT", true);
}
setState2(a0);
trackQuestEvent({
questId: quest.id,
event: a0 ? AnalyticEvents.QUEST_VIDEO_FULLSCREEN_ENTERED : AnalyticEvents.QUEST_VIDEO_FULLSCREEN_EXITED,
properties: {
video_session_id: videoSessionId
},
sourceQuestContent
});
}, [quest.id, videoSessionId, sourceQuestContent]);
const windowDimensions = useContext(QuestDockGestureContext).windowDimensions;
const styles = useStyles();
const height = useStateFromSharedValue(windowDimensions).height;
useLayoutEffect(() => {
if (c20956_4 && initialStep == null) {
setState(c9903_10.POST_WATCH_VIDEO);
}
}, [r36, initialStep]);
const callback2 = useCallback(() => {
setState(c9903_10.WATCH_VIDEO);
}, []);
const callback3 = useCallback(() => {
callback(false);
setState(c9903_10.POST_WATCH_VIDEO);
}, [callback]);
sharedValue = useSharedValue(state === c9903_10.POST_WATCH_VIDEO ? 1 : 0);
const y = () => ({
opacity: _spring.withSpring(_ReanimatedRexport.clamp(sharedValue.get(), 0, 1), BACKGROUND_ENTRANCE_ANIMATION_SPRING_CONFIG),
transform: [{
translateY: _spring.withSpring(_ReanimatedRexport.interpolate(sharedValue.get(), [0, 1], [-100, 0]), BACKGROUND_ENTRANCE_ANIMATION_SPRING_CONFIG)
}]
});
y.__closure = {
withSpring: _spring.withSpring,
clamp: _ReanimatedRexport.clamp,
postWatchAnimationState: sharedValue,
BACKGROUND_ENTRANCE_ANIMATION_SPRING_CONFIG,
interpolate: _ReanimatedRexport.interpolate,
CLOUDS_BACKGROUND_INVISIBLE_OFFSET_Y: -100
};
y.__workletHash = 11571705142399;
y.__initData = __initData;
const animatedStyle2 = useAnimatedStyle(y);
const safeAreaInsets_native = useSafeAreaInsets_native();
c20956_10 = safeAreaInsets_native;
const M = () => ({
transform: [{
translateY: _spring.withSpring(_ReanimatedRexport.interpolate(sharedValue.get(), [0, 1], [c20956_10.top, 0]), BACKGROUND_ENTRANCE_ANIMATION_SPRING_CONFIG)
}],
opacity: _spring.withSpring(sharedValue.get(), BACKGROUND_ENTRANCE_ANIMATION_SPRING_CONFIG)
});
M.__closure = {
withSpring: _spring.withSpring,
interpolate: _ReanimatedRexport.interpolate,
postWatchAnimationState: sharedValue,
safeAreaInsets: safeAreaInsets_native,
BACKGROUND_ENTRANCE_ANIMATION_SPRING_CONFIG
};
M.__workletHash = 9769051401109;
M.__initData = __initData2;
const animatedStyle = useAnimatedStyle(M);
useEffect(() => {
sharedValue.set(state === c9903_10.POST_WATCH_VIDEO ? 1 : 0);
}, [sharedValue, state]);
return <View>
<ReanimatedNativeView style={styles.modalContentWrapper}>
<View style={[styles.backgroundWrapper, {
height
}]}>
<ReanimatedNativeView style={[styles.contentBackground, {
top: safeAreaInsets_native.top
}]} />
<ReanimatedNativeView style={[styles.contentBackground, animatedStyle]} />
<ReanimatedNativeView style={animatedStyle2}>
<QuestModalContentCloudBackground align="top" />
</ReanimatedNativeView>
</View>
<SafeAreaPaddingView top style={[styles.wrapper, {
height
}]}>
<View style={styles.contentWrapper}>
{state === c9903_10.WATCH_VIDEO && <VideoQuestModalContentInProgress isFullscreen={isFullscreen} onNavigateToPostWatchVideo={callback3} onClose={onClose2} onEnd={callback3} setIsFullscreen={callback} sourceQuestContent={sourceQuestContent} />}
{state === c9903_10.POST_WATCH_VIDEO && <VideoQuestModalContentCompleted onClose={onClose2} onRestartVideo={callback2} sourceQuestContent={sourceQuestContent} />}
</View>
</SafeAreaPaddingView>
</ReanimatedNativeView>
</View>;
});
initialRouteName = "watch_mobile_video_quest";
const r73 = Module19.memo(function VideoQuestModal(props) {
const { questId, questContentPosition, onClose, videoSessionId: videoSessionId2, initialStep: initialStep2, sourceQuestContent: sourceQuestContent2 } = props;
const nonNullableQuest = useNonNullableQuest(questId, useCallback(() => {
showQuestUnavailableAlert();
onClose();
}, [onClose]));
const memo = useMemo(() => {
let r1 = null;
if (nonNullableQuest != null) {
const r7 = {};
r7[initialRouteName] = {
fullscreen: true,
headerLeft: () => null,
render: () => <VideoQuestModalContext.Provider value={{
quest: nonNullableQuest,
videoSessionId: videoSessionId2
}}>
<QuestDockGestureContextProvider>
<BillableAdPlacementImpressionTrackerNative overrideVisibility questContent={QuestContent.VIDEO_MODAL_MOBILE} questOrQuests={nonNullableQuest} questContentPosition={questContentPosition} sourceQuestContent={sourceQuestContent2}>
{function children() {
return <Component initialStep={initialStep2} onClose={onClose} sourceQuestContent={sourceQuestContent2} />;
}}
</BillableAdPlacementImpressionTrackerNative>
</QuestDockGestureContextProvider>
</VideoQuestModalContext.Provider>
};
r1 = r7;
}
return r1;
}, [onClose, nonNullableQuest, videoSessionId2, questContentPosition, initialStep2, sourceQuestContent2]);
useLayoutEffect(() => {
lockOrientation("PORTRAIT", true);
return restoreDefaultOrientation;
}, []);
return nonNullableQuest == null ? null : memo == null ? null : <Modal hideTitle initialRouteName={initialRouteName} screens={memo} />;
});
export default r73;
export { c9903_10 as VideoQuestModalSteps };
@@ -0,0 +1,15 @@
// Metro module 14173 (f14174).
import Module712 from "../../../../_bundle/Module712";
import { PressableOpacity } from "../../../../design/void/Pressables/native/Pressables";
import { intl, t } from "../../../../intl/index.native";
import { XSmallIcon } from "../../../../design/components/Icon/native/redesign/generated/XSmallIcon";
export default function VideoQuestModalCloseButton(props) {
const { onClose, iconColor = Module712.colors.MOBILE_TEXT_HEADING_PRIMARY, style } = props;
return <PressableOpacity accessibilityLabel={intl.string(t.cpT0Cq)} accessibilityRole="button" hitSlop={12} onPress={onClose} style={[{
flexShrink: 0,
minWidth: 24,
minHeight: 24
}, style]}>
<XSmallIcon color={iconColor} />
</PressableOpacity>;
};
@@ -0,0 +1,210 @@
// Metro module 14182 (f14183).
import * as Module19 from "react";
import { useMemo, useEffect, useCallback, useLayoutEffect, useContext, useState } from "react";
import { ActivityIndicator, ScrollView, View } from "react-native";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import { useVideoQuestModalContext } from "./VideoQuestModalContext";
import { getQuestAsset, QuestAssetType } from "../../lib/AssetUtils";
import { useVideoQuestClickCtaAndMaybeCloseModal } from "./useVideoQuestClickCtaAndMaybeCloseModal";
import { useQuestRewardClaimHandler } from "../QuestBottomSheet/QuestBottomSheetFooter";
import ProductPurchaseSuccessActionCreators from "../../../collectibles/native/ProductPurchaseSuccessActionCreators";
import * as _ReanimatedRexport from "../../../reanimated/ReanimatedRexport";
import { useSharedValue, useAnimatedStyle } from "../../../reanimated/ReanimatedRexport";
import * as _spring from "../../../../design/animation/reanimated/spring/spring";
import * as _QuestUtils from "../../utils/QuestUtils";
import { showShareActionSheet } from "../../../action_sheet/native/showShareActionSheet";
import { getQuestUrl, getExternalCtaLabel } from "../../utils/QuestCopyUtils";
import { lockOrientation } from "../../../device/native/DeviceOrientation";
import { QuestDockGestureContext } from "../QuestDock/QuestDockGestureContext";
import { QUEST_PROGRESS_DIAMETER_BY_SIZE } from "../QuestProgressIndicator";
import { SafeAreaPaddingView } from "../../../../components_native/common/SafeAreaView";
import { Stack } from "../../../../design/components/Stack/native/Stack.native";
import { Heading, Text } from "../../../../design/components/Text/native/Text";
import { intl, t } from "../../../../intl/index.native";
import VideoQuestModalCloseButton from "./VideoQuestModalCloseButton";
import ReanimatedNativeView from "../../../core/native/ReanimatedNativeView";
import VideoQuestModalReward from "./VideoQuestModalReward";
import { Button } from "../../../../design/components/Button/native/Button.native";
import { PressableOpacity } from "../../../../design/void/Pressables/native/Pressables";
import { RetryIcon } from "../../../../design/components/Icon/native/redesign/generated/RetryIcon";
import FastImage from "../../../../components_native/common/FastImage";
import { ShareIcon } from "../../../../design/components/Icon/native/redesign/generated/ShareIcon";
const ANIMATED_CONTENT_SPRING_CONFIG = {
mass: 1.9,
damping: 18,
stiffness: 80,
overshootClamping: false
};
const useStyles = createStyles({
wrapper: {
flexGrow: 1,
flexShrink: 1
},
headerContentCopy: {
flexGrow: 1,
flexShrink: 1
},
closeButton: {
opacity: 0.5
},
scroll: {
flexGrow: 1,
flexShrink: 1
},
scrollContent: {
flexGrow: 1
},
content: {
padding: Module712.space.PX_16
},
contentRewardsAnimatedWrapper: {
flexGrow: 1,
flexShrink: 0
},
contentRewardsWrapper: {
flexGrow: 1,
flexShrink: 0
},
contentRewards: {
alignItems: "center"
},
contentRewardsCopy: {
textAlign: "center"
},
contentEndCardHeader: {
marginBottom: Module712.space.PX_16
},
contentEndCardHeaderCopy: {
flexGrow: 1,
flexShrink: 1
},
contentEndCard: {
borderTopWidth: 1,
borderTopColor: Module712.colors.BORDER_STRONG,
paddingTop: Module712.space.PX_24,
flexShrink: 0
},
image: {
height: 210,
marginBottom: Module712.space.PX_24,
borderRadius: Module712.radii.xl
}
});
const __initData = {
code: "function VideoQuestModalContentCompletedTsx1(){const{withDelay,ANIMATION_DELAY,withSpring,isComponentMounted,ANIMATED_CONTENT_SPRING_CONFIG,interpolate,ANIMATED_CONTENT_OFFSET_Y}=this.__closure;return{opacity:withDelay(ANIMATION_DELAY,withSpring(isComponentMounted.get(),ANIMATED_CONTENT_SPRING_CONFIG)),transform:[{translateY:withDelay(ANIMATION_DELAY,withSpring(interpolate(isComponentMounted.get(),[0,1],[ANIMATED_CONTENT_OFFSET_Y,0]),ANIMATED_CONTENT_SPRING_CONFIG))}]};}"
};
const r73 = Module19.memo(function VideoQuestModalContentCompleted(props) {
let sharedValue, isShareableQuest;
const { onClose, onRestartVideo, sourceQuestContent } = props;
const styles = useStyles();
const quest = useVideoQuestModalContext().quest;
const memo = useMemo(() => getQuestAsset(quest, QuestAssetType.VIDEO_PLAYER_THUMBNAIL, void 0, true), [quest]);
const videoQuestClickCtaAndMaybeCloseModal = useVideoQuestClickCtaAndMaybeCloseModal({
quest,
onClose,
sourceQuestContent
});
const questRewardClaimHandler = useQuestRewardClaimHandler({
quest,
onSuccess: ProductPurchaseSuccessActionCreators.close,
sourceQuestContent
});
const { isLoading, isClaiming, claim } = questRewardClaimHandler;
const r59 = quest.userStatus?.claimedAt != null;
sharedValue = useSharedValue(0);
const u = function u() {
return {
opacity: _ReanimatedRexport.withDelay(125, _spring.withSpring(sharedValue.get(), ANIMATED_CONTENT_SPRING_CONFIG)),
transform: [{
translateY: _ReanimatedRexport.withDelay(125, _spring.withSpring(_ReanimatedRexport.interpolate(sharedValue.get(), [0, 1], [75, 0]), ANIMATED_CONTENT_SPRING_CONFIG))
}]
};
};
u.__closure = {
withDelay: _ReanimatedRexport.withDelay,
ANIMATION_DELAY: 125,
withSpring: _spring.withSpring,
isComponentMounted: sharedValue,
ANIMATED_CONTENT_SPRING_CONFIG,
interpolate: _ReanimatedRexport.interpolate,
ANIMATED_CONTENT_OFFSET_Y: 75
};
u.__workletHash = 2704439293952;
u.__initData = __initData;
const animatedStyle = useAnimatedStyle(u);
useEffect(() => {
sharedValue.set(1);
}, [sharedValue]);
let r19 = _QuestUtils.isShareableQuest(quest.config);
isShareableQuest = r19;
const callback = useCallback(() => {
if (isShareableQuest) {
showShareActionSheet({
message: getQuestUrl(quest.id)
}, "Video Quest Modal");
}
}, [isShareableQuest, quest.id]);
useLayoutEffect(() => {
lockOrientation("PORTRAIT", true);
}, []);
const windowDimensions = useContext(QuestDockGestureContext).windowDimensions;
const r5 = windowDimensions.get().height < 800;
const size = windowDimensions.get().height < 760 ? "md" : r5 ? "md-lg" : "lg";
let [state, setState] = useState(null);
const callback2 = useCallback((a0) => {
setState(a0.nativeEvent.layout.height);
}, []);
if (state == null) {
state = QUEST_PROGRESS_DIAMETER_BY_SIZE[size];
}
const minHeight = state + 2 * Module712.space.PX_16;
const r162 = [<Stack align="center" direction="horizontal" justify="space-between" style={styles.content}>
<Heading variant="heading-sm/semibold" color="text-subtle" style={styles.headerContentCopy}>
{intl.formatToPlainString(t.EAYZAr, {
questName: quest.config.messages.questName
})}
</Heading>
<VideoQuestModalCloseButton onClose={onClose} style={styles.closeButton} />
</Stack>, ,];
const r226 = [<ReanimatedNativeView style={[styles.contentRewardsAnimatedWrapper, {
minHeight
}, animatedStyle]}>
<Stack align="center" justify="center" spacing={Module712.space.PX_24} style={[styles.content, styles.contentRewardsWrapper]}>
{isLoading && !isClaiming ? <ActivityIndicator /> : <View style={styles.contentRewards} onLayout={callback2}>
<VideoQuestModalReward withQuestName={false} withRewardAvailableCopy={false} size={size} withRewardTileAnimation />
<Heading color="text-strong" style={styles.contentRewardsCopy} variant="heading-lg/semibold">
{r59 ? intl.string(t["EMp8/M"]) : intl.string(t.qyKLdg)}
</Heading>
</View>}
{r59 ? !r59 : <Button grow variant="secondary" loading={isClaiming} disabled={isClaiming} onPress={claim} text={intl.string(t.cfY4PE)} />}
</Stack>
</ReanimatedNativeView>, ,];
const r289 = [<Stack direction="horizontal" justify="space-between" style={styles.contentEndCardHeader}>
<Stack spacing={Module712.space.PX_4} style={styles.contentEndCardHeaderCopy}>
<Heading variant="heading-md/semibold" color="mobile-text-heading-primary">{quest.config.messages.gameTitle}</Heading>
<Text variant="text-sm/medium" color="text-subtle">{quest.config.messages.gamePublisher}</Text>
</Stack>
<PressableOpacity accessibilityRole="button" accessibilityLabel={intl.string(t.YsCuyF)} onPress={onRestartVideo}>
<RetryIcon color={Module712.colors.INTERACTIVE_TEXT_DEFAULT} />
</PressableOpacity>
</Stack>, memo != null && <PressableOpacity accessibilityRole="button" accessibilityLabel={intl.formatToPlainString(t.r8BzFT, {
gameTitle: quest.config.messages.gameTitle
})} onPress={videoQuestClickCtaAndMaybeCloseModal}>
<FastImage style={styles.image} source={{
uri: memo.url
}} resizeMode="cover" />
</PressableOpacity>, ,];
const r332 = [<Button grow variant="expressive" onPress={videoQuestClickCtaAndMaybeCloseModal} text={getExternalCtaLabel(quest)} />, ,];
if (isShareableQuest) {
r19 = <PressableOpacity accessibilityRole="button" accessibilityLabel={intl.string(t.Ej3B3Y)} onPress={callback}>
<ShareIcon color={Module712.colors.INTERACTIVE_TEXT_DEFAULT} />
</PressableOpacity>;
}
r332[1] = r19;
r289[2] = <Stack direction="horizontal" spacing={Module712.space.PX_16} align="center">{r332}</Stack>;
r226[1] = <View style={[styles.content, styles.contentEndCard]}>{r289}</View>;
r162[1] = <ScrollView style={styles.scroll} contentContainerStyle={styles.scrollContent} showsVerticalScrollIndicator={false} alwaysBounceVertical={false}>{r226}</ScrollView>;
return <SafeAreaPaddingView bottom style={styles.wrapper}>{r162}</SafeAreaPaddingView>;
});
export default r73;
@@ -0,0 +1,544 @@
// Metro module 14154 (f14155).
import * as Module19 from "react";
import { useMemo, useContext, useState, useCallback, useEffect, forwardRef } from "react";
import { ScrollView, StyleSheet, View } from "react-native";
import { QuestsExperimentLocations } from "../../QuestConstants";
import { ThemeTypes } from "../../../../_bundle/Module505";
import Module689 from "../../../../_bundle/Module689";
import Module712 from "../../../../_bundle/Module712";
import QuestProgressIndicator, { QUEST_PROGRESS_DIAMETER_BY_SIZE } from "../QuestProgressIndicator";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import { isAndroid } from "../../../../utils/PlatformUtils";
import { getQuestAsset, QuestAssetType } from "../../lib/AssetUtils";
import { VideoQuestPlayerRefactorExperiment } from "../../experiments/index";
import { VideoQuestPlayer } from "./VideoQuestPlayerRefactor";
import * as _VideoQuestPlayer from "./VideoQuestPlayer";
import { QuestDockGestureContext } from "../QuestDock/QuestDockGestureContext";
import * as _ReanimatedRexport from "../../../reanimated/ReanimatedRexport";
import { useSharedValue, useDerivedValue, useAnimatedStyle, useAnimatedProps } from "../../../reanimated/ReanimatedRexport";
import * as _timing from "../../../../design/animation/reanimated/timing/timing";
import useSafeAreaInsets_native from "../../../safe_area/useSafeAreaInsets.native";
import { SafeAreaPaddingView } from "../../../../components_native/common/SafeAreaView";
import { ThemeContextProvider } from "../../../../_bundle/Module3901";
import VideoQuestModalCloseButton from "./VideoQuestModalCloseButton";
import ReanimatedNativeView from "../../../core/native/ReanimatedNativeView";
import VideoQuestModalReward from "./VideoQuestModalReward";
import QuestModalContentCloudBackground from "../QuestModalContentCloudBackground";
import QuestGameLogotype from "../QuestGameLogotype";
import { Stack } from "../../../../design/components/Stack/native/Stack.native";
import { PressableOpacity } from "../../../../design/void/Pressables/native/Pressables";
import { Text } from "../../../../design/components/Text/native/Text";
import QuestContextMenu from "../QuestContextMenu";
import FastImage from "../../../../components_native/common/FastImage";
import { Button } from "../../../../design/components/Button/native/Button.native";
import { getExternalCtaLabel, getQuestUrl } from "../../utils/QuestCopyUtils";
import { IconButton } from "../../../../design/components/Button/native/IconButton.native";
import { intl, t } from "../../../../intl/index.native";
import Module12238 from "../../../../_bundle/Module12238";
import Module10195 from "../../../../_bundle/Module10195";
import { useQuestTaskDetails } from "../../hooks/QuestHooks";
import { getVideoQuestProgressRemainingAccessibilityLabel, getVideoOrientation } from "../../utils/VideoQuestUtils";
import Module4611 from "../../../../_bundle/Module4611";
import VideoQuestModalHeader from "./VideoQuestModalHeader";
import { ArrowSmallRightIcon } from "../../../../design/components/Icon/native/redesign/generated/ArrowSmallRightIcon";
import { TranscriptOutlineIcon } from "../../../../design/components/Icon/native/redesign/generated/TranscriptOutlineIcon";
import { ClosedCaptionsOutlineIcon } from "../../../../design/components/Icon/native/redesign/generated/ClosedCaptionsOutlineIcon";
import { ShareIcon } from "../../../../design/components/Icon/native/redesign/generated/ShareIcon";
import { MoreHorizontalIcon } from "../../../../design/components/Icon/native/redesign/generated/MoreHorizontalIcon";
import { useVideoQuestModalContext } from "./VideoQuestModalContext";
import ActionSheetActionCreators from "../../../action_sheet/native/ActionSheetActionCreators";
import { useGetQuestImpressionId } from "../../lib/analytics/ContentImpressionTrackerHooks";
import * as _QuestUtils from "../../utils/QuestUtils";
import { shouldMigrateToAdAnalyticsInterface, AdAnalyticsInterfaceExperimentStep } from "../../experiments/AdAnalyticsInterfaceExperiment";
import { captureAdUserAction } from "../../../ads/analytics/captureAdUserAction";
import { AdUserActionType } from "../../../ads/analytics/captureAdUserActionTypes";
import { AdCreativeType } from "../../../../_bundle/Module6013";
import { QuestContentCTA } from "../../lib/analytics/AnalyticsTypes";
import { QuestContent } from "../../QuestTypes";
import { trackQuestContentClicked } from "../../lib/analytics/AnalyticsActions";
import { showShareActionSheet } from "../../../action_sheet/native/showShareActionSheet";
import { useVideoQuestClickCtaAndMaybeCloseModal } from "./useVideoQuestClickCtaAndMaybeCloseModal";
import { openRewardDetailsBottomSheet } from "../QuestUtils.native";
import { useVideoExternallyPaused } from "./hooks/useVideoExternallyPaused";
import { FirstPartyQuestTaskTypes } from "../../../../_bundle/Module5040";
let __initData, __initData2, __initData3, __initData4, Component3, Component2, useStyles2, FooterButton;
const start = {
x: 0,
y: 0
};
const end = {
x: 0,
y: 1
};
const colors = [Module689(Module712.unsafe_rawColors.PLUM_23).alpha(0.4).hex(), Module689(Module712.unsafe_rawColors.PLUM_23).alpha(0).hex()];
const colors2 = [Module689(Module712.unsafe_rawColors.PLUM_23).alpha(0).hex(), Module689(Module712.unsafe_rawColors.PLUM_23).alpha(0.4).hex()];
const contentInsets = {
bottom: 158,
top: 64,
left: 16,
right: 16
};
const contentInsets2 = {
bottom: 16,
left: 16,
right: 16
};
const useStyles = createStyles((a0) => ({
wrapper: {
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWEST,
flex: 1
},
wrapperPortrait: {
borderTopLeftRadius: Module712.radii.lg,
borderTopRightRadius: Module712.radii.lg,
justifyContent: a0 ? "flex-start" : "center"
},
videoLandscape: {
width: "100%",
position: "relative"
},
videoLandscape9by16: {
aspectRatio: 1.7777777777777777,
flexShrink: 0
},
landscapeContentScroll: {
flex: 1
},
landscapeContentScrollContent: {
flexGrow: 1
},
videoLandscapeFullscreen: {
flexGrow: 1,
flexShrink: 1
},
videoWrapper: {
borderRadius: Module712.radii.lg,
flexGrow: 0,
flexShrink: 0,
overflow: "hidden"
},
videoWrapperLandscape: {
flexGrow: 1,
borderTopLeftRadius: Module712.radii.none,
borderTopRightRadius: Module712.radii.none
},
videoWrapperFullscreen: {
borderRadius: Module712.radii.none
},
videoContentWrapper: {
flexDirection: "column",
pointerEvents: "box-none",
flexGrow: 1,
flexShrink: 0,
justifyContent: "space-between",
padding: Module712.space.PX_16
},
videoContentWrapperLandscape: {
padding: 0
},
videoContentWrapperPortrait: {
...StyleSheet.absoluteFillObject
},
rewardContainer: {
justifyContent: "center",
flexGrow: 1,
flexShrink: 0
},
rewardContentCentered: {
position: "absolute",
top: Module712.space.PX_16,
left: Module712.space.PX_16,
right: Module712.space.PX_16,
bottom: Module712.space.PX_16,
alignItems: "center",
justifyContent: "center"
},
modalBackground: {
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWEST
},
questDetailsLandscape: {
borderTopWidth: 1,
borderColor: Module712.colors.BACKGROUND_MOD_STRONG,
paddingHorizontal: Module712.space.PX_16,
paddingTop: Module712.space.PX_24
},
questDetailsPrimary: {
flexGrow: 0,
flexShrink: 1
},
questDetailsSecondary: {
flexGrow: 0,
flexShrink: 0
},
footer: {
paddingHorizontal: Module712.space.PX_16,
paddingVertical: Module712.space.PX_8
},
icon: {
color: Module712.colors.INTERACTIVE_TEXT_ACTIVE
},
iconDisabled: {
color: Module712.colors.INTERACTIVE_TEXT_DEFAULT
},
closeButtonLandscape: {
position: "absolute",
top: Module712.space.PX_16,
left: Module712.space.PX_16
},
gradientTop: {
...StyleSheet.absoluteFillObject,
bottom: void 0,
height: 70
},
gradientBottom: {
...StyleSheet.absoluteFillObject,
top: void 0,
height: 150
},
textShadow: {
margin: -15,
padding: 15,
textShadowColor: Module712.colors.BLACK,
textShadowOffset: {
width: 0,
height: 0
},
textShadowRadius: 15
},
viewRewardBtn: {
marginRight: "auto"
},
playerThumbnail: {
borderRadius: Module712.radii.lg,
height: 96,
width: "100%"
},
cloudsBackground: {
zIndex: -1
},
questDetailsSubheader: {
opacity: 0.6
}
}));
__initData = {
code: "function VideoQuestModalContentInProgressTsx1(){const{withDelay,LOGO_REWARD_TRANSITION_DELAY_MS,withTiming,isComponentMounted,LOGO_REWARD_TRANSITION_DURATION_MS}=this.__closure;return withDelay(LOGO_REWARD_TRANSITION_DELAY_MS,withTiming(isComponentMounted.get(),{duration:LOGO_REWARD_TRANSITION_DURATION_MS}));}"
};
__initData2 = {
code: "function VideoQuestModalContentInProgressTsx2(){const{animation}=this.__closure;return{opacity:animation.get()};}"
};
__initData3 = {
code: "function VideoQuestModalContentInProgressTsx3(){const{animation}=this.__closure;return{opacity:1-animation.get()};}"
};
__initData4 = {
code: "function VideoQuestModalContentInProgressTsx4(){const{animation}=this.__closure;return{pointerEvents:animation.get()>0.3?'auto':'none'};}"
};
Component3 = Module19.memo(function(a0) {
let setState, setState2, sharedValue, derivedValue;
const { quest, captionsEnabled, handleClose, handlePrimaryCtaPress, handleShareQuest, handleOpenTranscript, handleToggleCaptions, isFullscreen, onNavigateToPostWatchVideo, onEnd, setIsFullscreen, externallyPaused, sourceQuestContent: sourceQuestContent2, hasCaptionAsset, hasTranscriptAsset } = a0;
let isShareable = a0.isShareable;
setState = void 0;
setState2 = void 0;
sharedValue = void 0;
derivedValue = void 0;
const styles = useStyles(isAndroid());
const memo2 = useMemo(() => getQuestAsset(quest, QuestAssetType.HERO), [quest]);
let r24 = quest.userStatus?.completedAt != null;
const Component = VideoQuestPlayerRefactorExperiment.useConfig({
location: QuestsExperimentLocations.VIDEO_MODAL_MOBILE
}).enabled ? VideoQuestPlayer : _VideoQuestPlayer.VideoQuestPlayer;
const windowDimensions2 = useContext(QuestDockGestureContext).windowDimensions;
let state;
[state, setState] = useState(null);
const callback = useCallback((a0) => {
setState(a0.nativeEvent.layout.height);
}, []);
let state2;
[state2, setState2] = useState(null);
const callback2 = useCallback((a0) => {
setState2(Module712.space.PX_24 + a0.nativeEvent.layout.height);
}, []);
const r90 = state != null ? state - 2 * Module712.space.PX_16 : null;
let r96 = "md";
let size = "md";
if (r90 != null) {
const r97 = state2 == null;
size = "md";
if (!r97) {
const r102 = QUEST_PROGRESS_DIAMETER_BY_SIZE.lg + state2;
let r103 = "lg";
if (!(r90 >= r102)) {
if (r90 >= QUEST_PROGRESS_DIAMETER_BY_SIZE["md-lg"] + state2) {
r96 = "md-lg";
}
r103 = r96;
}
size = r103;
}
}
const md = QUEST_PROGRESS_DIAMETER_BY_SIZE.md;
if (state2 == null) {
state2 = 0;
}
const minHeight = md + state2 + 2 * Module712.space.PX_16;
sharedValue = useSharedValue(0);
useEffect(() => {
sharedValue.set(1);
}, [sharedValue]);
const te = function te() {
return _ReanimatedRexport.withDelay(3000, _timing.withTiming(sharedValue.get(), {
duration: 1000
}));
};
te.__closure = {
withDelay: _ReanimatedRexport.withDelay,
LOGO_REWARD_TRANSITION_DELAY_MS: 3000,
withTiming: _timing.withTiming,
isComponentMounted: sharedValue,
LOGO_REWARD_TRANSITION_DURATION_MS: 1000
};
te.__workletHash = 12561024953493;
te.__initData = __initData;
derivedValue = useDerivedValue(te);
const ne = () => ({
opacity: derivedValue.get()
});
ne.__closure = {
animation: derivedValue
};
ne.__workletHash = 17463485679217;
ne.__initData = __initData2;
const animatedStyle2 = useAnimatedStyle(ne);
const oe = () => ({
opacity: 1 - derivedValue.get()
});
oe.__closure = {
animation: derivedValue
};
oe.__workletHash = 9103187579788;
oe.__initData = __initData3;
const animatedStyle = useAnimatedStyle(oe);
const se = () => ({
pointerEvents: derivedValue.get() > 0.3 ? "auto" : "none"
});
se.__closure = {
animation: derivedValue
};
se.__workletHash = 11833431315705;
se.__initData = __initData4;
const animatedProps = useAnimatedProps(se);
const safeAreaInsets_native = useSafeAreaInsets_native();
const callback3 = useCallback(({ orientation }) => {
let r6 = isFullscreen;
if (!isFullscreen) {
r6 = orientation !== "landscape";
}
setIsFullscreen((r6 ? "PORTRAIT" : "LANDSCAPE") === "LANDSCAPE");
}, [isFullscreen, setIsFullscreen]);
const style = [styles.videoWrapper, styles.videoWrapperLandscape, isFullscreen ? styles.videoWrapperFullscreen : isFullscreen];
const r203 = [<ThemeContextProvider theme={ThemeTypes.DARKER}>
<Component captionsEnabled={captionsEnabled} orientation="landscape" style={[styles.videoLandscape, isFullscreen ? !isFullscreen : styles.videoLandscape9by16, isFullscreen ? styles.videoLandscapeFullscreen : isFullscreen]} contentInsets={contentInsets2} handleOpenTranscript={handleOpenTranscript} handleToggleCaptions={handleToggleCaptions} isFullscreen={isFullscreen} externallyPaused={externallyPaused} onEnd={onEnd} onToggleFullscreen={callback3} sourceQuestContent={sourceQuestContent2} hasCaptionAsset={hasCaptionAsset} hasTranscriptAsset={hasTranscriptAsset} />
<VideoQuestModalCloseButton onClose={handleClose} style={[styles.closeButtonLandscape, (isFullscreen ? safeAreaInsets_native != null : isFullscreen) && {
left: safeAreaInsets_native.left
}]} />
</ThemeContextProvider>, ,];
let r204 = !isFullscreen;
if (!isFullscreen) {
const r267 = [<View style={[styles.rewardContainer, {
minHeight
}]} onLayout={callback}>
<ReanimatedNativeView style={[styles.rewardContentCentered, animatedStyle2]} animatedProps={animatedProps}>
<VideoQuestModalReward size={size} onTextBlockLayout={callback2} />
</ReanimatedNativeView>
<ReanimatedNativeView style={[styles.rewardContentCentered, isAndroid() && styles.modalBackground, animatedStyle]} pointerEvents="none">
{isAndroid() && <QuestModalContentCloudBackground align="top" style={styles.cloudsBackground} />}
<QuestGameLogotype assetUrl={getQuestAsset(quest, QuestAssetType.LOGO_TYPE, "dark").url} maxHeight={90} maxWidth={windowDimensions2.get().width - 120} />
</ReanimatedNativeView>
</View>, <QuestModalContentCloudBackground align="top" style={styles.cloudsBackground} />, ,];
const r323 = [<Stack direction="horizontal" justify="space-between" spacing={Module712.space.PX_8}>
<PressableOpacity style={styles.questDetailsPrimary} onPress={handlePrimaryCtaPress}>
<Text variant="heading-lg/semibold" color="mobile-text-heading-primary" accessibilityRole="header">{quest.config.messages.gameTitle}</Text>
<Text variant="heading-sm/semibold" color="text-subtle">{quest.config.messages.gamePublisher}</Text>
</PressableOpacity>
<View style={styles.questDetailsSecondary}>
<QuestContextMenu quest={quest} location={QuestsExperimentLocations.VIDEO_MODAL_MOBILE} sourceQuestContent={sourceQuestContent2} />
</View>
</Stack>, memo2 != null && <PressableOpacity onPress={handlePrimaryCtaPress}>
<FastImage source={{
uri: memo2.url
}} style={styles.playerThumbnail} />
</PressableOpacity>, ,];
const r353 = [<Button grow variant="expressive" onPress={handlePrimaryCtaPress} text={getExternalCtaLabel(quest)} />, , ,];
if (isShareable) {
isShareable = <IconButton accessibilityLabel={intl.string(t.Ej3B3Y)} icon={Module12238} onPress={handleShareQuest} variant="secondary" />;
}
r353[1] = isShareable;
if (r24) {
r24 = <IconButton accessibilityLabel={intl.string(t.cfY4PE)} icon={Module10195} onPress={onNavigateToPostWatchVideo} variant="secondary" />;
}
r353[2] = r24;
r323[2] = <Stack direction="horizontal" spacing={Module712.space.PX_16}>{r353}</Stack>;
r267[2] = <Stack direction="vertical" spacing={Module712.space.PX_24} style={styles.questDetailsLandscape}>{r323}</Stack>;
r204 = <ScrollView style={styles.landscapeContentScroll} contentContainerStyle={styles.landscapeContentScrollContent} showsVerticalScrollIndicator={false} alwaysBounceVertical={false}>
<View style={[styles.videoContentWrapper, styles.videoContentWrapperLandscape]}>{r267}</View>
</ScrollView>;
}
r203[1] = r204;
return <SafeAreaPaddingView bottom style={styles.wrapper}>
<View style={style}>{r203}</View>
</SafeAreaPaddingView>;
});
Component2 = Module19.memo(function(a0) {
let c20959_2, state, setState3;
const { quest: quest3, captionsEnabled, handleClose, handlePrimaryCtaPress, handleRewardDetailsPress, handleShareQuest, handleOpenTranscript, handleToggleCaptions, isFullscreen: isFullscreen2, onNavigateToPostWatchVideo, onEnd, externallyPaused, sourceQuestContent: sourceQuestContent2 } = a0;
let hasCaptionAsset = a0.hasCaptionAsset;
let hasTranscriptAsset = a0.hasTranscriptAsset;
let isShareable = a0.isShareable;
c20959_2 = void 0;
state = void 0;
setState3 = void 0;
const questTaskDetails = useQuestTaskDetails(quest3);
const r50 = quest3.userStatus?.completedAt != null;
const videoQuestProgressRemainingAccessibilityLabel = getVideoQuestProgressRemainingAccessibilityLabel(questTaskDetails, r50);
const Component = VideoQuestPlayerRefactorExperiment.useConfig({
location: QuestsExperimentLocations.VIDEO_MODAL_MOBILE
}).enabled ? VideoQuestPlayer : _VideoQuestPlayer.VideoQuestPlayer;
const windowDimensions = useContext(QuestDockGestureContext).windowDimensions;
const memo = useMemo(() => Math.floor(windowDimensions.get().width / 0.5625), [windowDimensions]);
const callback = useCallback(() => {}, []);
const safeAreaInsets_native = useSafeAreaInsets_native();
c20959_2 = safeAreaInsets_native;
[state, setState3] = useState(64);
const callback2 = useCallback((a0) => {
setState3(a0.nativeEvent.layout.height);
}, []);
const memo2 = useMemo(() => {
const r3 = Math;
const height = windowDimensions.get().height;
return r3.min(height - c20959_2.top - c20959_2.bottom - state, memo);
}, [memo, state, windowDimensions, safeAreaInsets_native]);
const styles = useStyles(windowDimensions.get().height - memo2 - state < 200);
const style = [styles.videoWrapper, memo2 == null ? {
flexGrow: 1
} : {
height: memo2
}];
const r211 = [<View style={style}>
<ThemeContextProvider theme={ThemeTypes.DARKER}>
<Component captionsEnabled={captionsEnabled} onLoad={callback} externallyPaused={externallyPaused} orientation="portrait" contentInsets={contentInsets} handleOpenTranscript={handleOpenTranscript} handleToggleCaptions={handleToggleCaptions} isFullscreen={isFullscreen2} onEnd={onEnd} sourceQuestContent={sourceQuestContent2} hasCaptionAsset={hasCaptionAsset} hasTranscriptAsset={hasTranscriptAsset} />
</ThemeContextProvider>
<Module4611 start={start} end={end} style={styles.gradientTop} colors={colors} />
<Module4611 start={start} end={end} style={styles.gradientBottom} colors={colors2} />
<View style={[styles.videoContentWrapper, styles.videoContentWrapperPortrait]}>
<VideoQuestModalHeader closeButtonIconColor={Module712.colors.WHITE} onClose={handleClose} showCurrentVideoTime withTextShadow />
<Stack direction="vertical" spacing={Module712.space.PX_24}>
<Stack direction="horizontal" justify="space-between" spacing={Module712.space.PX_8}>
<PressableOpacity style={styles.questDetailsPrimary} onPress={handlePrimaryCtaPress}>
<Text variant="heading-lg/semibold" color="text-overlay-light" style={styles.textShadow} accessibilityRole="header">{quest3.config.messages.gameTitle}</Text>
<Text variant="heading-sm/semibold" color="text-overlay-light" style={[styles.textShadow, styles.questDetailsSubheader]}>{quest3.config.messages.gamePublisher}</Text>
</PressableOpacity>
<View style={styles.questDetailsSecondary}>
<QuestProgressIndicator quest={quest3} size="x-sm" progress={questTaskDetails.percentComplete} hasConfetti onPress={handleRewardDetailsPress} accessibilityLabel={videoQuestProgressRemainingAccessibilityLabel} />
</View>
</Stack>
<Button grow variant="expressive" onPress={handlePrimaryCtaPress} text={getExternalCtaLabel(quest3)} />
</Stack>
</View>
</View>, ,];
const r243 = [r50 && <View style={styles.viewRewardBtn}>
<Button icon={<ArrowSmallRightIcon size="sm" />} iconPosition="end" onPress={onNavigateToPostWatchVideo} variant="secondary" size="sm" text={intl.string(t["jyYgZ+"])} />
</View>, , , , ,];
if (hasTranscriptAsset) {
hasTranscriptAsset = <FooterButton accessibilityLabel={intl.string(t.KCzjTi)} onPress={handleOpenTranscript}>
<TranscriptOutlineIcon color={styles.iconDisabled.color} />
</FooterButton>;
}
r243[1] = hasTranscriptAsset;
if (hasCaptionAsset) {
hasCaptionAsset = <FooterButton accessibilityLabel={intl.string(t.bDSZO1)} onPress={handleToggleCaptions}>
<ClosedCaptionsOutlineIcon color={captionsEnabled ? styles.icon.color : styles.iconDisabled.color} />
</FooterButton>;
}
r243[2] = hasCaptionAsset;
if (isShareable) {
isShareable = <FooterButton accessibilityLabel={intl.string(t.Ej3B3Y)} onPress={handleShareQuest}>
<ShareIcon color={Module712.colors.TEXT_DEFAULT} />
</FooterButton>;
}
r243[3] = isShareable;
r243[4] = <QuestContextMenu quest={quest3} location={QuestsExperimentLocations.VIDEO_MODAL_MOBILE} sourceQuestContent={sourceQuestContent2}>
{function children({ ref, ...props }) {
return <FooterButton accessibilityLabel={intl.string(t.PdRCRg)} ref={ref} {...props}>
<MoreHorizontalIcon color={Module712.colors.TEXT_DEFAULT} />
</FooterButton>;
}}
</QuestContextMenu>;
r211[1] = <Stack direction="horizontal" justify="flex-end" align="center" style={styles.footer} spacing={Module712.space.PX_4} onLayout={callback2}>{r243}</Stack>;
return <SafeAreaPaddingView bottom style={[styles.wrapper, styles.wrapperPortrait]}>{r211}</SafeAreaPaddingView>;
});
useStyles2 = createStyles({
footerButton: {
padding: Module712.space.PX_8
}
});
FooterButton = forwardRef(function FooterButton(props, a1) {
return <PressableOpacity accessibilityRole="button" style={useStyles2().footerButton} {...props} ref={a1} />;
});
const r114 = Module19.memo(function VideoQuestModalContentInProgress(props) {
let getQuestImpressionId, isShareableQuest;
const { isFullscreen: isFullscreen2, onClose, onNavigateToPostWatchVideo, onEnd, setIsFullscreen: setIsFullscreen2, sourceQuestContent } = props;
const quest2 = useVideoQuestModalContext().quest;
const memo2 = useMemo(() => getQuestAsset(quest2, QuestAssetType.VIDEO_PLAYER_CAPTION, void 0, true), [quest2]);
const memo3 = useMemo(() => getQuestAsset(quest2, QuestAssetType.VIDEO_PLAYER_TRANSCRIPT, void 0, true), [quest2]);
let [captionsEnabled, setState4] = useState(false);
const callback = useCallback(() => setState4((prevState4) => !prevState4), []);
const callback2 = useCallback(() => {
ActionSheetActionCreators.openLazy(import("./VideoQuestTranscriptActionSheet"), `transcript-${quest2.id}`, {
quest: quest2
});
}, [quest2]);
getQuestImpressionId = useGetQuestImpressionId();
const [state, setState5] = useState(false);
isShareableQuest = _QuestUtils.isShareableQuest(quest2.config);
const callback3 = useCallback(() => {
if (isShareableQuest) {
if (shouldMigrateToAdAnalyticsInterface(AdAnalyticsInterfaceExperimentStep.STEP_2_CLICKED_INTERNAL, "video_quest_modal_in_progress")) {
captureAdUserAction({
type: AdUserActionType.CLICK_INTERNAL,
adCreativeType: AdCreativeType.QUEST,
adCreativeId: quest2.id,
questContentCTA: QuestContentCTA.MOBILE_SHARESHEET,
surfaceId: QuestContent.VIDEO_MODAL_MOBILE,
sourceQuestContent,
impressionId: getQuestImpressionId()
});
} else {
trackQuestContentClicked({
questId: quest2.id,
questContent: QuestContent.VIDEO_MODAL_MOBILE,
questContentCTA: QuestContentCTA.MOBILE_SHARESHEET,
impressionId: getQuestImpressionId(),
sourceQuestContent
});
}
setState5(true);
showShareActionSheet({
message: getQuestUrl(quest2.id),
iOSOnlyShareCallback: () => setState5(false)
}, `Video Quest Modal - ${quest2.id}`);
}
}, [isShareableQuest, quest2.id, getQuestImpressionId, sourceQuestContent]);
const videoQuestClickCtaAndMaybeCloseModal = useVideoQuestClickCtaAndMaybeCloseModal({
quest: quest2,
onClose,
sourceQuestContent
});
const callback4 = useCallback(() => {
openRewardDetailsBottomSheet({
questId: quest2.id
});
}, [quest2.id]);
const videoExternallyPaused = useVideoExternallyPaused(quest2.id, state);
const r85 = quest2.config.taskConfigV2.tasks[FirstPartyQuestTaskTypes.WATCH_VIDEO_ON_MOBILE];
return r85 == null || getVideoOrientation(r85) === "portrait" ? <Component2 quest={quest2} captionsEnabled={captionsEnabled} handleClose={onClose} handlePrimaryCtaPress={videoQuestClickCtaAndMaybeCloseModal} handleRewardDetailsPress={callback4} handleShareQuest={callback3} handleOpenTranscript={callback2} handleToggleCaptions={callback} isFullscreen={isFullscreen2} onNavigateToPostWatchVideo={onNavigateToPostWatchVideo} onEnd={onEnd} setIsFullscreen={setIsFullscreen2} externallyPaused={videoExternallyPaused} sourceQuestContent={sourceQuestContent} hasCaptionAsset={memo2 != null} hasTranscriptAsset={memo3 != null} isShareable={isShareableQuest} /> : <Component3 quest={quest2} captionsEnabled={captionsEnabled} handleClose={onClose} handlePrimaryCtaPress={videoQuestClickCtaAndMaybeCloseModal} handleRewardDetailsPress={callback4} handleShareQuest={callback3} handleOpenTranscript={callback2} handleToggleCaptions={callback} isFullscreen={isFullscreen2} onNavigateToPostWatchVideo={onNavigateToPostWatchVideo} onEnd={onEnd} setIsFullscreen={setIsFullscreen2} externallyPaused={videoExternallyPaused} sourceQuestContent={sourceQuestContent} hasCaptionAsset={memo2 != null} hasTranscriptAsset={memo3 != null} isShareable={isShareableQuest} />;
});
export default r114;
@@ -0,0 +1,13 @@
// Metro module 14150 (f14151).
import { createContext, useContext } from "react";
import Module38 from "../../../../_bundle/Module38";
const context = createContext({
quest: null,
videoSessionId: ""
});
export default context;
export function useVideoQuestModalContext() {
const context2 = useContext(context);
Module38(context2 != null, "useVideoQuestModalContext must be used within a VideoQuestModalProvider");
return context2;
}
@@ -0,0 +1,76 @@
// Metro module 14178 (f14179).
import { View } from "react-native";
import { useVideoQuestUIStore } from "../../VideoQuestUIStore";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import { useVideoQuestModalContext } from "./VideoQuestModalContext";
import { useQuestTaskDetails } from "../../hooks/QuestHooks";
import { parseMinutesAndSecondsFromSeconds, formatWatchTaskTime } from "../../utils/QuestTaskUtils";
import { shallow } from "../../../../_bundle/Module3802";
import { getVideoQuestProgressRemainingAccessibilityLabel } from "../../utils/VideoQuestUtils";
import { Text } from "../../../../design/components/Text/native/Text";
import { intl, t } from "../../../../intl/index.native";
import VideoQuestModalCloseButton from "./VideoQuestModalCloseButton";
const useStyles = createStyles({
videoContentHeaderWrapper: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "flex-start"
},
videoContentHeading: {
flexDirection: "column",
flexShrink: 1,
gap: Module712.space.PX_4
},
subheader: {
opacity: 0.6
},
textShadow: {
margin: -15,
padding: 15,
textShadowColor: Module712.colors.BLACK,
textShadowOffset: {
width: 0,
height: 0
},
textShadowRadius: 15
}
});
export default function VideoQuestModalHeader(props) {
const { closeButtonIconColor, onClose, style, showCurrentVideoTime = false, withTextShadow } = props;
let r19 = withTextShadow !== void 0 && withTextShadow;
const styles = useStyles();
const quest = useVideoQuestModalContext().quest;
const questTaskDetails = useQuestTaskDetails(quest);
const videoQuestUIStore = useVideoQuestUIStore((a0) => {
let r9 = a0.videoProgress[quest.id];
if (r9 == null) {
r9 = {
timestampSec: questTaskDetails.progressSeconds,
duration: questTaskDetails.targetSeconds,
maxTimestampSec: questTaskDetails.progressSeconds
};
}
const r22 = parseMinutesAndSecondsFromSeconds(r9.duration - r9.timestampSec);
return formatWatchTaskTime(r22.minutes, r22.seconds);
}, shallow);
const r42 = quest.userStatus?.completedAt != null;
const accessibilityLabel = r42 ? showCurrentVideoTime ? getVideoQuestProgressRemainingAccessibilityLabel(questTaskDetails, r42) : void 0 : getVideoQuestProgressRemainingAccessibilityLabel(questTaskDetails, r42);
const r66 = [<Text variant="heading-md/semibold" color="text-overlay-light" style={r19 ? styles.textShadow : r19}>
{intl.formatToPlainString(t.EQa7os, {
questName: quest.config.messages.questName
})}
</Text>, ,];
const style2 = [styles.subheader, ,];
if (r19) {
r19 = styles.textShadow;
}
style2[1] = r19;
r66[1] = <Text variant="heading-sm/semibold" color="text-overlay-light" accessibilityLabel={accessibilityLabel} style={style2}>
{r42 ? showCurrentVideoTime ? videoQuestUIStore : quest.config.messages.gamePublisher : videoQuestUIStore}
</Text>;
return <View style={[styles.videoContentHeaderWrapper, style]}>
<View style={styles.videoContentHeading}>{r66}</View>
<VideoQuestModalCloseButton iconColor={closeButtonIconColor} onClose={onClose} />
</View>;
};
@@ -0,0 +1,49 @@
// Metro module 14174 (f14175).
import { memo, useCallback } from "react";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import { useVideoQuestModalContext } from "./VideoQuestModalContext";
import { useQuestTaskDetails } from "../../hooks/QuestHooks";
import { openRewardDetailsBottomSheet } from "../QuestUtils.native";
import { Stack } from "../../../../design/components/Stack/native/Stack.native";
import Module712 from "../../../../_bundle/Module712";
import QuestProgressIndicator from "../QuestProgressIndicator";
import { Text } from "../../../../design/components/Text/native/Text";
import { intl, t } from "../../../../intl/index.native";
const useStyles = createStyles({
questName: {
textAlign: "center"
}
});
const r27 = memo(function VideoQuestModalReward(props) {
const { style, withQuestName } = props;
let r9 = withQuestName === void 0 || withQuestName;
const withRewardAvailableCopy = props.withRewardAvailableCopy;
let r8 = withRewardAvailableCopy === void 0 || withRewardAvailableCopy;
const { size: size2 = "lg", withRewardTileAnimation, onTextBlockLayout } = props;
const quest = useVideoQuestModalContext().quest;
const questTaskDetails = useQuestTaskDetails(quest);
const callback = useCallback(() => {
openRewardDetailsBottomSheet({
questId: quest.id
});
}, [quest.id]);
const styles = useStyles();
const r48 = [<QuestProgressIndicator hasConfetti quest={quest} size={size2} progress={questTaskDetails.percentComplete} onPress={callback} withAnimation={withRewardTileAnimation} />, ,];
if (r9) {
r9 = <Text variant="heading-lg/semibold" color="text-strong" style={styles.questName}>
{intl.formatToPlainString(t.EAYZAr, {
questName: quest.config.messages.questName
})}
</Text>;
}
const r75 = [r9, ,];
if (r8) {
r8 = <Text variant="heading-sm/medium" color="text-subtle">
{intl.string(t["1Wvve2"])}
</Text>;
}
r75[1] = r8;
r48[1] = <Stack align="center" spacing={Module712.space.PX_4} onLayout={onTextBlockLayout}>{r75}</Stack>;
return <Stack justify="center" align="center" spacing={Module712.space.PX_24} style={style}>{r48}</Stack>;
});
export default r27;
@@ -0,0 +1,891 @@
// Metro module 14160 (f14161).
import * as Module19 from "react";
import { useRef, useMemo, useState, useCallback, useEffect, useLayoutEffect } from "react";
import { ActivityIndicator, Pressable, View, StyleSheet } from "react-native";
import AppStateStore from "../../../../stores/native/AppStateStore";
import VideoQuestUIStore from "../../VideoQuestUIStore";
import { QuestsExperimentLocations } from "../../QuestConstants";
import { AppStates, ComponentActions } from "../../../../Constants";
import Module712 from "../../../../_bundle/Module712";
import Video from "../../../../_bundle/Video_8143";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module689 from "../../../../_bundle/Module689";
import { useVideoQuestModalContext } from "./VideoQuestModalContext";
import { useQuestTaskDetails } from "../../hooks/QuestHooks";
import { getQuestAsset, QuestAssetType } from "../../lib/AssetUtils";
import { shallow } from "../../../../_bundle/Module3802";
import ReanimatedRexport, { useSharedValue, useAnimatedStyle } from "../../../reanimated/ReanimatedRexport";
import * as _spring from "../../../../design/animation/reanimated/spring/spring";
import * as _springPresets from "../../../../design/animation/reanimated/spring/springPresets";
import * as _timing from "../../../../design/animation/reanimated/timing/timing";
import * as _timingPresets from "../../../../design/animation/reanimated/timing/timingPresets";
import useVideoQuestPlayerAnalytics from "./hooks/useVideoQuestPlayerAnalytics";
import { getDefaultWatchVideoTask } from "../../utils/QuestTaskUtils";
import { getVideoQoEMetricsConfig, MobileMuxWrapper } from "../../../video-qoe/index";
import { getConstants } from "../../../../utils/native/ClientInfoUtils";
import { isAndroid, isIOS } from "../../../../utils/PlatformUtils";
import { ComponentDispatch } from "../../../../utils/ComponentDispatchUtils";
import { sendVideoProgress } from "../../utils/VideoQuestUtils";
import { updateOptimisticProgress } from "../../QuestActionCreators";
import { useStateFromStores } from "../../../../_bundle/Module589";
import SentryUtils_native from "../../../../utils/SentryUtils.native";
import useSafeAreaInsets_native from "../../../safe_area/useSafeAreaInsets.native";
import { intl, t } from "../../../../intl/index.native";
import { VideoQuestCaptions } from "./captions/VideoQuestCaptions";
import { PressableOpacity } from "../../../../design/void/Pressables/native/Pressables";
import { ClosedCaptionsOutlineIcon } from "../../../../design/components/Icon/native/redesign/generated/ClosedCaptionsOutlineIcon";
import { TranscriptOutlineIcon } from "../../../../design/components/Icon/native/redesign/generated/TranscriptOutlineIcon";
import { VideoQuestPlayerControlButton } from "./VideoQuestPlayerControlButton";
import { SkipBackwardIcon } from "./icons/SkipBackwardIcon";
import { RetryIcon } from "../../../../design/components/Icon/native/redesign/generated/RetryIcon";
import { PlayIcon } from "../../../../design/components/Icon/native/redesign/generated/PlayIcon";
import { PauseIcon } from "../../../../design/components/Icon/native/redesign/generated/PauseIcon";
import { SkipForwardIcon } from "./icons/SkipForwardIcon";
import { FullscreenEnterIcon } from "../../../../design/components/Icon/native/redesign/generated/FullscreenEnterIcon";
let hasVideoEnded, canSeekForward, useStyles, PlayerState, __initData, __initData2, __initData3;
let c9911_15 = {
left: Module712.space.PX_16,
right: Module712.space.PX_16,
top: Module712.space.PX_16,
bottom: Module712.space.PX_16
};
let Component = Module19.memo(Video);
const hasVideoEnded2 = function hasVideoEnded(a0, a1) {
return a0 >= a1 - 1;
};
hasVideoEnded2.__closure = {};
hasVideoEnded2.__workletHash = 3281537893520;
hasVideoEnded2.__initData = {
code: "function hasVideoEnded_VideoQuestPlayerTsx1(currentTime,videoDuration){return currentTime>=videoDuration-1;}"
};
hasVideoEnded = hasVideoEnded2;
const canSeekForward2 = function canSeekForward(a0, a1, a2, a3) {
const r2 = a0 >= a2 - 1;
return r2 ? !r2 : a3 ? a3 : a0 <= a1 - 1;
};
canSeekForward2.__closure = {
hasVideoEnded
};
canSeekForward2.__workletHash = 741911733910;
canSeekForward2.__initData = {
code: "function canSeekForward_VideoQuestPlayerTsx2(currentTime,maxTimestamp,videoDuration,isQuestCompleted){const{hasVideoEnded}=this.__closure;return!hasVideoEnded(currentTime,videoDuration)&&(isQuestCompleted||currentTime<=maxTimestamp-1);}"
};
canSeekForward = canSeekForward2;
useStyles = createStyles({
container: {
...StyleSheet.absoluteFillObject
},
loadingContainer: {
...StyleSheet.absoluteFillObject,
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWEST,
justifyContent: "center",
alignItems: "center"
},
bufferingSpinner: {
position: "absolute"
},
bufferingSpinnerCentered: {
...StyleSheet.absoluteFillObject,
justifyContent: "center",
alignItems: "center"
},
video: {
height: "100%",
width: "100%"
},
videoContainer: {
position: "relative",
height: "100%",
width: "100%"
},
controls: {
...StyleSheet.absoluteFillObject,
backgroundColor: Module689(Module712.unsafe_rawColors.BLACK).alpha(0.5).hex(),
justifyContent: "center",
alignItems: "center",
flexDirection: "column"
},
controlsTopBottom: {
flexDirection: "row",
justifyContent: "flex-end",
padding: Module712.space.PX_8,
position: "absolute",
left: 0,
right: 0
},
controlsMiddle: {
justifyContent: "center",
alignItems: "center",
flexGrow: 1,
flexDirection: "row",
gap: Module712.space.PX_24,
pointerEvents: "box-none"
},
controlsTop: {
top: 0
},
controlsBottom: {
bottom: 0
},
progressContainer: {
position: "absolute",
bottom: 0,
right: 0,
left: 0,
justifyContent: "flex-end",
height: Module712.space.PX_16,
overflow: "hidden"
},
progress: {
height: 1,
backgroundColor: Module712.colors.WHITE,
shadowOffset: {
width: 0,
height: 0
},
shadowRadius: 6,
shadowOpacity: 1,
elevation: 5,
shadowColor: "#FFFFFF"
},
icon: {
color: Module712.colors.TEXT_DEFAULT
},
iconDisabled: {
color: Module712.colors.TEXT_SUBTLE
},
controlButton: {
padding: Module712.space.PX_8
}
});
PlayerState = {
PAUSED: "paused",
PLAYING: "playing",
ENDED: "ended",
LOADING: "loading",
ERRORED: "errored"
};
__initData = {
code: "function shouldShowControls_VideoQuestPlayerTsx3(){const{hasLoaded,showControls,playerState,PlayerState,isVideoEnded,externallyPaused}=this.__closure;return hasLoaded&&(showControls.get()||playerState===PlayerState.PAUSED||playerState===PlayerState.ENDED||playerState===PlayerState.ERRORED||isVideoEnded||externallyPaused);}"
};
__initData2 = {
code: "function VideoQuestPlayerTsx4(){const{shouldShowControls,withSpring,SUBTLE_SPRING}=this.__closure;const show=shouldShowControls();return{opacity:withSpring(show?1:0,SUBTLE_SPRING),pointerEvents:show?'auto':'none'};}"
};
__initData3 = {
code: "function VideoQuestPlayerTsx5(){const{withTiming,progress,timingFast}=this.__closure;return{width:withTiming(progress.get()*100+\"%\",timingFast,'animate-always')};}"
};
const r159 = Module19.memo(function(a0) {
let r420, R3aFPe, children2, children3, props4;
let memo2, state, setState, targetSeconds, c20965_14, c20965_15, state2, setState2, ref2, state3, setState3, ref3, ref4, ref5, ref6, c20965_25, sharedValue, shouldShowControls2, sharedValue2, ref7, handleEndAnalytics, handleErrorAnalytics, handleLoadAnalytics, handleLoadStartAnalytics, handlePausePlaybackAnalytics, handleProgressAnalytics, handleReadyForDisplayAnalytics, handleResumePlaybackAnalytics, handleSeekAnalytics, ref8, id, gameTitle, url, videoTitle, videoStreamType, setState4, callback, callback2, callback3, callback4, c20965_50, ref9, ref10, callback5;
const { style, onLoad, onEnd, onToggleFullscreen, orientation, contentInsets, handleToggleCaptions, handleOpenTranscript, isFullscreen, externallyPaused, captionsEnabled = false, sourceQuestContent } = a0;
let hasCaptionAsset = a0.hasCaptionAsset;
if (hasCaptionAsset === void 0) {
hasCaptionAsset = true;
}
let hasTranscriptAsset = a0.hasTranscriptAsset;
if (hasTranscriptAsset === void 0) {
hasTranscriptAsset = true;
}
memo2 = void 0;
state = void 0;
setState = void 0;
targetSeconds = void 0;
c20965_14 = void 0;
c20965_15 = void 0;
state2 = void 0;
setState2 = void 0;
ref2 = void 0;
state3 = void 0;
setState3 = void 0;
ref3 = void 0;
ref4 = void 0;
ref5 = void 0;
ref6 = void 0;
c20965_25 = void 0;
sharedValue = void 0;
shouldShowControls2 = void 0;
sharedValue2 = void 0;
ref7 = void 0;
handleEndAnalytics = void 0;
handleErrorAnalytics = void 0;
handleLoadAnalytics = void 0;
handleLoadStartAnalytics = void 0;
handlePausePlaybackAnalytics = void 0;
handleProgressAnalytics = void 0;
handleReadyForDisplayAnalytics = void 0;
handleResumePlaybackAnalytics = void 0;
handleSeekAnalytics = void 0;
ref8 = void 0;
id = void 0;
gameTitle = void 0;
url = void 0;
videoTitle = void 0;
videoStreamType = void 0;
setState4 = void 0;
callback = void 0;
callback2 = void 0;
callback3 = void 0;
callback4 = void 0;
c20965_50 = void 0;
ref9 = void 0;
ref10 = void 0;
callback5 = void 0;
const styles = useStyles();
const ref = useRef(null);
const videoQuestModalContext = useVideoQuestModalContext();
const { quest, videoSessionId } = videoQuestModalContext;
const questTaskDetails = useQuestTaskDetails(quest);
let isQuestCompleted = quest.userStatus?.completedAt != null;
let c20965_8 = isQuestCompleted;
const memo = useMemo(() => getQuestAsset(quest, QuestAssetType.VIDEO_PLAYER_VIDEO, void 0, true), [quest]);
memo2 = useMemo(() => getQuestAsset(quest, QuestAssetType.VIDEO_PLAYER_VIDEO_HLS, void 0, true), [quest]);
const videoAssetId = memo2?.url != null ? QuestAssetType.VIDEO_PLAYER_VIDEO_HLS : QuestAssetType.VIDEO_PLAYER_VIDEO;
[state, setState] = useState(questTaskDetails.targetSeconds);
targetSeconds = questTaskDetails.targetSeconds;
const r58 = VideoQuestUIStore((a0) => a0.setVideoProgress);
c20965_14 = r58;
const r45 = VideoQuestUIStore((a0) => {
let r8 = a0.videoProgress[quest.id];
if (r8 == null) {
r8 = {
timestampSec: questTaskDetails.progressSeconds,
duration: state,
maxTimestampSec: questTaskDetails.progressSeconds
};
}
return r8;
}, shallow);
c20965_15 = r45;
[state2, setState2] = useState(PlayerState.LOADING);
ref2 = useRef(false);
let state4;
[state4, setState3] = useState(false);
state3 = state4;
ref3 = useRef(questTaskDetails.progressSeconds);
ref4 = useRef([]);
ref5 = useRef(null);
ref6 = useRef(0);
const isVideoEnded = (state3 ? state2 === PlayerState.ENDED : state3) && r45.timestampSec >= r45.duration - 1;
c20965_25 = isVideoEnded;
sharedValue = useSharedValue(false);
const shouldShowControls = function shouldShowControls() {
let r1 = state3;
if (state3) {
r1 = sharedValue.get() || state2 === PlayerState.PAUSED || state2 === PlayerState.ENDED || state2 === PlayerState.ERRORED || c20965_25 || externallyPaused;
}
return r1;
};
shouldShowControls.__closure = {
hasLoaded: state3,
showControls: sharedValue,
playerState: state2,
PlayerState,
isVideoEnded,
externallyPaused
};
shouldShowControls.__workletHash = 11602236169344;
shouldShowControls.__initData = __initData;
shouldShowControls2 = shouldShowControls;
const G = function G() {
let r5 = state3;
if (state3) {
r5 = sharedValue.get() || state2 === PlayerState.PAUSED || state2 === PlayerState.ENDED || state2 === PlayerState.ERRORED || c20965_25 || externallyPaused;
}
return {
opacity: _spring.withSpring(r5 ? 1 : 0, _springPresets.SUBTLE_SPRING),
pointerEvents: r5 ? "auto" : "none"
};
};
G.__closure = {
shouldShowControls: shouldShowControls2,
withSpring: _spring.withSpring,
SUBTLE_SPRING: _springPresets.SUBTLE_SPRING
};
G.__workletHash = 6174625876255;
G.__initData = __initData2;
const animatedStyle = useAnimatedStyle(G);
if (state3) {
state4 = sharedValue.get() || state2 === PlayerState.PAUSED || state2 === PlayerState.ENDED || state2 === PlayerState.ERRORED || isVideoEnded || externallyPaused;
}
sharedValue2 = useSharedValue(0);
const U = () => ({
width: _timing.withTiming(100 * sharedValue2.get() + "%", _timingPresets.timingFast, "animate-always")
});
U.__closure = {
withTiming: _timing.withTiming,
progress: sharedValue2,
timingFast: _timingPresets.timingFast
};
U.__workletHash = 4647711667921;
U.__initData = __initData3;
const animatedStyle2 = useAnimatedStyle(U);
ref7 = useRef(-1);
const callback6 = useCallback((c27647_0) => function(...args) {
clearTimeout(ref7.current);
sharedValue.set(true);
ref7.current = setTimeout(() => {
sharedValue.set(false);
}, 2000);
if (c27647_0 != null) {
return c27647_0.apply(void 0, [...args]);
}
}, [sharedValue]);
const videoQuestPlayerAnalytics = useVideoQuestPlayerAnalytics({
duration: state,
isQuestCompleted,
playerState: state2,
questId: quest.id,
videoSessionId,
videoAssetId,
sourceQuestContent
});
const handleBufferAnalytics2 = videoQuestPlayerAnalytics.handleBufferAnalytics;
handleEndAnalytics = videoQuestPlayerAnalytics.handleEndAnalytics;
handleErrorAnalytics = videoQuestPlayerAnalytics.handleErrorAnalytics;
handleLoadAnalytics = videoQuestPlayerAnalytics.handleLoadAnalytics;
handleLoadStartAnalytics = videoQuestPlayerAnalytics.handleLoadStartAnalytics;
handlePausePlaybackAnalytics = videoQuestPlayerAnalytics.handlePausePlaybackAnalytics;
handleProgressAnalytics = videoQuestPlayerAnalytics.handleProgressAnalytics;
handleReadyForDisplayAnalytics = videoQuestPlayerAnalytics.handleReadyForDisplayAnalytics;
handleResumePlaybackAnalytics = videoQuestPlayerAnalytics.handleResumePlaybackAnalytics;
handleSeekAnalytics = videoQuestPlayerAnalytics.handleSeekAnalytics;
ref8 = useRef(null);
id = quest.id;
gameTitle = quest.config.messages.gameTitle;
let r64 = memo2?.url;
if (r64 == null) {
r64 = memo?.url;
}
url = r64;
const defaultWatchVideoTask = getDefaultWatchVideoTask(quest.config);
videoTitle = defaultWatchVideoTask == null ? void 0 : defaultWatchVideoTask.messages.videoTitle;
videoStreamType = memo2?.url != null ? "hls" : "mp4";
useEffect(() => {
if (ref.current != null && url != null && url.length !== 0 && getVideoQoEMetricsConfig({
location: QuestsExperimentLocations.VIDEO_MODAL_MOBILE
}).externalAnalyticsEnabled) {
const constants = getConstants();
ref8.current = new MobileMuxWrapper({
videoRef: ref.current,
feature: "quests",
appVersion: constants.Version,
releaseChannel: constants.ReleaseChannel,
contentMetadata: {
contentId: url,
videoStreamType,
contentType: "quests",
durationMs: 1000 * targetSeconds,
title: videoTitle,
questId: id,
gameName: gameTitle
}
});
ref8.current.initialize();
return () => {
if (ref8.current != null) {
ref8.current.onProgress(ref3.current);
ref8.current.destroy();
ref8.current = null;
}
};
}
}, [id, gameTitle, targetSeconds, url, videoTitle, videoStreamType]);
let state5;
[state5, setState4] = useState(false);
const callback7 = useCallback(() => {
handleReadyForDisplayAnalytics();
const current2 = ref8.current;
if (current2 != null) {
current2.onReadyForDisplay();
}
setState4(true);
}, [handleReadyForDisplayAnalytics]);
callback = useCallback((a0) => {
if (ref.current != null) {
const current2 = Math.max(0, Math.min(a0, c20965_15.maxTimestampSec));
if (isAndroid()) {
ref6.current = (ref6.current + 1) % 100;
ref.current.seek(current2 + 0.0001 * ref6.current);
} else {
ref.current.seek(current2);
}
ref5.current = current2;
}
}, [r45.maxTimestampSec]);
const callback8 = useCallback((a0) => {
const { duration, videoTracks, trackId, naturalSize } = a0;
setState(duration);
setState3(true);
handleLoadAnalytics();
const current2 = ref8.current;
if (current2 != null) {
current2.onLoad(duration);
}
if (naturalSize != null) {
const current3 = ref8.current;
if (current3 != null) {
current3.updateVideoSourceDimensions(naturalSize.width, naturalSize.height);
}
}
if (videoTracks != null && videoTracks.length > 0 && trackId != null && trackId.length > 0) {
const current4 = ref8.current;
if (current4 != null) {
current4.onVideoTrackChange(trackId, videoTracks);
}
}
if (ref.current != null) {
const timestampSec = c20965_15.timestampSec;
if ((c20965_8 ? !c20965_8 : timestampSec > 5) && timestampSec < duration - 3) {
callback(timestampSec - 1);
}
setState2(PlayerState.PLAYING);
if (onLoad != null) {
onLoad(a0);
}
}
}, [isQuestCompleted, r45.timestampSec, handleLoadAnalytics, onLoad, callback]);
callback2 = useCallback(function(r3 = {}) {
let shouldRestartVideo = r3.shouldRestartVideo;
if (shouldRestartVideo === void 0) {
shouldRestartVideo = true;
}
L16: {
L14: {
if (state2 !== PlayerState.ERRORED) {
if (c20965_25 && shouldRestartVideo) {
break L14;
}
if (state2 !== PlayerState.PAUSED && state2 !== PlayerState.LOADING) {
if (state2 !== PlayerState.PLAYING) {
break L16;
}
setState2(PlayerState.PAUSED);
handlePausePlaybackAnalytics();
const current2 = ref8.current;
if (current2 == null) {
break L16;
}
current2.onPause();
break L16;
}
setState2(PlayerState.PLAYING);
handleResumePlaybackAnalytics();
const current3 = ref8.current;
if (current3 == null) {
break L16;
}
current3.onPlay();
break L16;
}
}
callback(0);
setState2(PlayerState.PLAYING);
handleResumePlaybackAnalytics();
const current4 = ref8.current;
if (current4 != null) {
current4.onPlay();
}
}
}, [state2, handlePausePlaybackAnalytics, handleResumePlaybackAnalytics, isVideoEnded, callback]);
const callback9 = useCallback(() => callback2(), [callback2]);
callback3 = useCallback(() => {
ref2.current = false;
if (state2 === PlayerState.PLAYING) {
ref2.current = true;
setState2(PlayerState.PAUSED);
handlePausePlaybackAnalytics();
const current2 = ref8.current;
if (current2 != null) {
current2.onPause();
}
}
}, [state2, handlePausePlaybackAnalytics]);
callback4 = useCallback(() => {
if (ref2.current) {
ref2.current = false;
if (state2 !== PlayerState.ERRORED) {
setState2(PlayerState.PLAYING);
handleResumePlaybackAnalytics();
const current2 = ref8.current;
if (current2 != null) {
current2.onPlay();
}
}
}
}, [state2, handleResumePlaybackAnalytics]);
useEffect(() => {
ComponentDispatch.subscribe(ComponentActions.QUEST_GAME_LINK_OPENED, callback3);
ComponentDispatch.subscribe(ComponentActions.QUEST_APP_STORE_OVERLAY_FINISHED, callback4);
return () => {
ComponentDispatch.unsubscribe(ComponentActions.QUEST_GAME_LINK_OPENED, callback3);
ComponentDispatch.unsubscribe(ComponentActions.QUEST_APP_STORE_OVERLAY_FINISHED, callback4);
};
}, [callback3, callback4]);
const callback10 = useCallback(() => {
if (onToggleFullscreen != null) {
onToggleFullscreen({
orientation
});
}
}, [onToggleFullscreen, orientation]);
const callback11 = useCallback(() => {
if (sharedValue.get()) {
sharedValue.set(false);
}
callback2({
shouldRestartVideo: false
});
}, [sharedValue, callback2]);
const callback12 = useCallback((a0) => {
let r7 = ref4.current.shift();
if (r7 == null) {
r7 = null;
}
if (ref.current != null) {
ref3.current = a0.currentTime;
ref5.current = null;
if (state > 0) {
sharedValue2.set(a0.currentTime / state);
c20965_14(quest.id, a0.currentTime, state);
}
handleSeekAnalytics(r7, a0.currentTime);
const current2 = ref8.current;
if (current2 != null) {
current2.updatePlayheadTime(a0.currentTime);
}
const current3 = ref8.current;
if (current3 != null) {
current3.onSeek();
}
}
}, [state, sharedValue2, handleSeekAnalytics, quest.id, r58]);
let disabled = state2 === PlayerState.ERRORED;
if (!disabled) {
const { timestampSec, maxTimestampSec } = r45;
const r10 = timestampSec >= r45.duration - 1;
let r8 = !r10;
if (!r10) {
if (!isQuestCompleted) {
isQuestCompleted = timestampSec <= maxTimestampSec - 1;
}
r8 = isQuestCompleted;
}
disabled = !r8;
}
c20965_50 = disabled;
const callback13 = useCallback(() => {
if (!c20965_50) {
let current2 = ref5.current;
if (current2 == null) {
current2 = sharedValue2.get() * state;
}
ref4.current.push(current2);
callback(current2 + 10);
}
}, [callback, state, sharedValue2, disabled]);
const onPress = callback6(useCallback(() => {
let current2 = ref5.current;
if (current2 == null) {
current2 = sharedValue2.get() * state;
}
ref4.current.push(current2);
callback(current2 - 10);
if (state2 === PlayerState.ENDED) {
setState2(PlayerState.PLAYING);
}
}, [callback, state, sharedValue2, state2]));
const onPress2 = callback6(callback13);
ref9 = useRef(0);
ref10 = useRef(0);
const callback14 = useCallback((a0) => {
const r7 = a0.seekableDuration !== 0 ? a0.currentTime / a0.seekableDuration : 0;
ref3.current = a0.currentTime;
if (a0.currentTime >= ref9.current) {
sendVideoProgress(quest, a0.currentTime);
handleProgressAnalytics(r7, a0.seekableDuration, a0.currentTime);
ref9.current = a0.currentTime + 6 + 2 * Math.random();
}
if (a0.currentTime >= ref10.current) {
updateOptimisticProgress(quest.id, questTaskDetails.taskType, a0.currentTime);
ref10.current = a0.currentTime + 1;
}
c20965_14(quest.id, a0.currentTime, a0.seekableDuration);
sharedValue2.set(r7);
const current2 = ref8.current;
if (current2 != null) {
current2.onProgress(a0.currentTime);
}
}, [sharedValue2, quest, ref9, ref10, questTaskDetails.taskType, r58, handleProgressAnalytics]);
const callback15 = useCallback(() => {
sendVideoProgress(quest, state);
handleEndAnalytics();
setState2(PlayerState.ENDED);
const current2 = ref8.current;
if (current2 != null) {
current2.onProgress(state);
}
const current3 = ref8.current;
if (current3 != null) {
current3.onEnd();
}
if (onEnd != null) {
onEnd();
}
}, [state, quest, handleEndAnalytics, onEnd]);
const callback16 = useCallback(() => {
setState2(PlayerState.LOADING);
handleLoadStartAnalytics();
const current2 = ref8.current;
if (current2 != null) {
current2.onLoadStart();
}
const current3 = ref8.current;
if (current3 != null) {
current3.onPlay();
}
}, [handleLoadStartAnalytics]);
const callback17 = useCallback((a0) => {
setState2(PlayerState.ERRORED);
handleErrorAnalytics(a0);
const current2 = ref8.current;
if (current2 != null) {
current2.onError(a0);
}
}, [handleErrorAnalytics]);
const callback18 = useCallback((a0) => {
if (a0 != null && a0.videoTracks != null && a0.videoTracks.length > 0 && a0.selectedVideoTrackId != null && a0.selectedVideoTrackId.length > 0) {
const current2 = ref8.current;
if (current2 != null) {
current2.onVideoTrackChange(a0.selectedVideoTrackId, a0.videoTracks);
}
}
}, []);
const callback19 = useCallback((a0) => {
if ((a0 == null ? void 0 : a0.nativeEvent?.layout) != null) {
const layout = a0.nativeEvent.layout;
const { width, height } = layout;
if (width > 0 && height > 0) {
const current2 = ref8.current;
if (current2 != null) {
current2.updateVideoDimensions(width, height);
}
}
}
}, []);
const r320 = useStateFromStores([AppStateStore], () => AppStateStore.getState()) === AppStates.ACTIVE;
const memo3 = useMemo(() => {
const r1 = memo == null;
let r2 = null;
if (!r1) {
let uri = memo2?.url;
if (uri == null) {
uri = memo.url;
}
r2 = {
uri
};
}
return r2;
}, [memo2, memo]);
useLayoutEffect(() => {
if (isAndroid()) {
const current = ref.current;
return () => {
try {
if (current != null) {
const setNativeProps = current.setNativeProps;
if (setNativeProps != null) {
setNativeProps.call(current, {
paused: true,
src: {
uri: null
}
});
}
}
} catch ($e) {
SentryUtils_native.captureException($e);
}
};
}
}, []);
const paused = (r320 ? state2 === PlayerState.PAUSED : !r320) || state2 === PlayerState.LOADING || externallyPaused;
const handleBufferAnalytics = handleBufferAnalytics2;
const ref11 = ref8;
const ref12 = useRef(false);
let [state6, setState5] = useState(false);
callback5 = useCallback((a0) => {
setState5(a0);
if (a0 !== ref12.current) {
ref12.current = a0;
handleBufferAnalytics(a0);
const current2 = ref11.current;
if (current2 != null) {
current2.onBuffer(a0);
}
}
}, [handleBufferAnalytics, ref8]);
const callback20 = useCallback((a0) => {
let isBuffering;
L6: {
L4: {
isBuffering = a0.isBuffering;
if (isBuffering) {
if (state2 !== PlayerState.LOADING && isIOS()) {
break L4;
}
callback5(true);
break L6;
}
}
if (!isBuffering) {
callback5(false);
}
}
}, [callback5, state2]);
const callback21 = useCallback(() => {
if (isIOS()) {
callback5(true);
}
}, [callback5]);
const callback22 = useCallback(() => {
if (isIOS()) {
callback5(false);
}
}, [callback5]);
const safeAreaInsets_native = useSafeAreaInsets_native();
if (memo3 == null) {
return null;
}
const r359 = isFullscreen && safeAreaInsets_native != null && {
paddingRight: Math.max(safeAreaInsets_native.right, c9911_15.right),
paddingLeft: Math.max(safeAreaInsets_native.left, c9911_15.left)
};
const props = {
style: [styles.container, style],
accessible: false,
children: null
};
const props2 = {
style: [styles.videoContainer],
onPress: callback11,
accessible: !state4,
accessibilityLabel: intl.string(paused ? t.R3aFPe : t.fTMEUi),
children: null
};
const children = [state2 !== PlayerState.ERRORED && <Component mixWithOthers="inherit" ref={ref} accessible={false} importantForAccessibility="no-hide-descendants" accessibilityRole="none" style={styles.video} paused={paused} source={memo3} onBuffer={callback20} onPlaybackStalled={callback21} onPlaybackResume={callback22} onLoad={callback8} onSeek={callback12} onProgress={callback14} onLoadStart={callback16} onEnd={callback15} onError={callback17} onReadyForDisplay={callback7} onVideoTracks={callback18} onLayout={callback19} resizeMode="contain" />, , , , , ,];
let top = contentInsets?.top;
if (top == null) {
top = 0;
}
let bottom = contentInsets?.bottom;
if (bottom == null) {
bottom = 0;
}
let left = contentInsets?.left;
if (left == null) {
left = 0;
}
let right = contentInsets?.right;
if (right == null) {
right = 0;
}
children[1] = <VideoQuestCaptions quest={quest} currentTime={r45.timestampSec} visible={captionsEnabled} style={{
top,
bottom,
left,
right
}} />;
if (state6) {
const style2 = [styles.bufferingSpinner, ,];
if (!isFullscreen && orientation !== "landscape") {
let top2 = contentInsets?.top;
if (top2 == null) {
top2 = 0;
}
let left2 = contentInsets?.left;
if (left2 == null) {
left2 = 0;
}
r420 = {
top: top2,
left: left2
};
} else {
r420 = styles.bufferingSpinnerCentered;
}
style2[1] = r420;
state6 = <ActivityIndicator animating style={style2} color={Module712.unsafe_rawColors.WHITE} />;
}
children[2] = state6;
children[3] = state5 ? !state5 : <View style={styles.loadingContainer}>
<ActivityIndicator animating />
</View>;
const props3 = {
style: [styles.controls, animatedStyle],
accessible: false,
children: null
};
let r441 = orientation === "landscape";
let r442 = r441;
if (r441) {
if (hasCaptionAsset) {
hasCaptionAsset = <PressableOpacity accessibilityRole="button" accessibilityLabel={intl.string(t.bDSZO1)} onPress={handleToggleCaptions} style={styles.controlButton}>
<ClosedCaptionsOutlineIcon color={captionsEnabled ? styles.icon.color : styles.iconDisabled.color} />
</PressableOpacity>;
}
const r469 = [hasCaptionAsset, ,];
if (hasTranscriptAsset) {
hasTranscriptAsset = <PressableOpacity accessibilityRole="button" accessibilityLabel={intl.string(t.KCzjTi)} onPress={handleOpenTranscript} style={styles.controlButton}>
<TranscriptOutlineIcon color={styles.iconDisabled.color} />
</PressableOpacity>;
}
r469[1] = hasTranscriptAsset;
r442 = <View style={[styles.controlsTopBottom, styles.controlsTop, r359]}>{r469}</View>;
}
L117: {
children2 = [r442, , ,];
props4 = {
style: styles.controlsMiddle,
children: null
};
children3 = [<VideoQuestPlayerControlButton disabled={state2 === PlayerState.ERRORED} accessibilityRole="button" accessibilityLabel={intl.string(t.r9s3Uv)} onPress={onPress}>
<SkipBackwardIcon color={styles.icon.color} width={16} height={16} />
</VideoQuestPlayerControlButton>, , ,];
if (!isVideoEnded && state2 !== PlayerState.ERRORED) {
if (paused) {
R3aFPe = t.R3aFPe;
break L117;
}
R3aFPe = t.fTMEUi;
} else {
R3aFPe = t.K0e7M9;
}
}
children3[1] = <VideoQuestPlayerControlButton accessibilityRole="button" accessibilityLabel={intl.string(R3aFPe)} onPress={callback9}>
{!isVideoEnded && state2 !== PlayerState.ERRORED ? paused ? <PlayIcon size="lg" /> : <PauseIcon size="lg" /> : <RetryIcon size="lg" />}
</VideoQuestPlayerControlButton>;
children3[2] = <VideoQuestPlayerControlButton disabled={disabled} accessibilityRole="button" accessibilityLabel={intl.string(t.zWDcNP)} onPress={onPress2}>
<SkipForwardIcon color={styles.icon.color} width={16} height={16} />
</VideoQuestPlayerControlButton>;
props4.children = children3;
children2[1] = <View {...props4} />;
children2[2] = r441 ? <View style={[styles.controlsTopBottom, styles.controlsBottom, r359]}>
<PressableOpacity accessibilityRole="button" accessibilityLabel={intl.string(t.vKZT5t)} onPress={callback10} style={styles.controlButton}>
<FullscreenEnterIcon />
</PressableOpacity>
</View> : r441;
props3.children = children2;
children[4] = <ReanimatedRexport.View {...props3} />;
if (r441) {
r441 = <View style={styles.progressContainer}>
<ReanimatedRexport.View style={[styles.progress, animatedStyle2]} />
</View>;
}
children[5] = r441;
props2.children = children;
props.children = <Pressable {...props2} />;
return <View {...props} />;
});
exports.PlayerState = PlayerState;
export { r159 as VideoQuestPlayer };
@@ -0,0 +1,27 @@
// Metro module 14050 (f14051).
import { memo } from "react";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import Module689 from "../../../../_bundle/Module689";
import { PressableOpacity } from "../../../../design/void/Pressables/native/Pressables";
import VisualEffectView from "../../../visual_effect_view/native/VisualEffectView";
const useStyles = createStyles({
disabled: {
opacity: 0.5
},
container: {
borderRadius: Module712.radii.round,
overflow: "hidden"
},
blur: {
backgroundColor: Module689(Module712.unsafe_rawColors.BLACK).alpha(0.5).hex(),
padding: Module712.space.PX_12
}
});
const r48 = memo(function({ style, children, ...props }) {
const styles = useStyles();
return <PressableOpacity style={[styles.container, props.disabled && styles.disabled, style]} {...props}>
<VisualEffectView style={styles.blur} blurAmount={0.2} blurStyle="default" blurTheme="dark">{children}</VisualEffectView>
</PressableOpacity>;
});
export { r48 as VideoQuestPlayerControlButton };
@@ -0,0 +1,331 @@
// Metro module 14157 (f14158).
import * as Module19 from "react";
import { useMemo, useState, useRef, useEffect, useCallback } from "react";
import VideoQuestUIStore from "../../VideoQuestUIStore";
import { QuestsExperimentLocations } from "../../QuestConstants";
import { useVideoQuestModalContext } from "./VideoQuestModalContext";
import { useQuestTaskDetails } from "../../hooks/QuestHooks";
import { getQuestAsset, QuestAssetType } from "../../lib/AssetUtils";
import { shallow } from "../../../../_bundle/Module3802";
import * as _AdVideoPlayer from "../AdVideoPlayer";
import { AdVideoPlayer } from "../AdVideoPlayer";
import useVideoQuestPlayerAnalytics from "./hooks/useVideoQuestPlayerAnalytics";
import { getDefaultWatchVideoTask } from "../../utils/QuestTaskUtils";
import { getVideoQoEMetricsConfig, MobileMuxWrapper } from "../../../video-qoe/index";
import { getConstants } from "../../../../utils/native/ClientInfoUtils";
import { sendVideoProgress } from "../../utils/VideoQuestUtils";
import { updateOptimisticProgress } from "../../QuestActionCreators";
import { VideoQuestCaptions } from "./captions/VideoQuestCaptions";
const r27 = Module19.memo(function(a0) {
let memo2, state, setState, targetSeconds, c20962_13, ref, setState2, ref2, handleBufferAnalytics, handleEndAnalytics, handleErrorAnalytics, handleLoadAnalytics, handleLoadStartAnalytics, handlePausePlaybackAnalytics, handleProgressAnalytics, handleReadyForDisplayAnalytics, handleResumePlaybackAnalytics, handleSeekAnalytics, ref3, id, gameTitle, url, videoTitle, videoStreamType, ref4, ref5;
const { style, onLoad, onEnd, onToggleFullscreen, orientation, contentInsets, handleToggleCaptions, handleOpenTranscript, isFullscreen, externallyPaused, captionsEnabled = false } = a0;
const visible = captionsEnabled;
const { sourceQuestContent, hasCaptionAsset = true, hasTranscriptAsset = true } = a0;
memo2 = void 0;
state = void 0;
setState = void 0;
targetSeconds = void 0;
c20962_13 = void 0;
ref = void 0;
setState2 = void 0;
ref2 = void 0;
handleBufferAnalytics = void 0;
handleEndAnalytics = void 0;
handleErrorAnalytics = void 0;
handleLoadAnalytics = void 0;
handleLoadStartAnalytics = void 0;
handlePausePlaybackAnalytics = void 0;
handleProgressAnalytics = void 0;
handleReadyForDisplayAnalytics = void 0;
handleResumePlaybackAnalytics = void 0;
handleSeekAnalytics = void 0;
ref3 = void 0;
id = void 0;
gameTitle = void 0;
url = void 0;
videoTitle = void 0;
videoStreamType = void 0;
ref4 = void 0;
ref5 = void 0;
const videoQuestModalContext = useVideoQuestModalContext();
const { quest, videoSessionId } = videoQuestModalContext;
const questTaskDetails = useQuestTaskDetails(quest);
const isQuestCompleted = quest.userStatus?.completedAt != null;
const memo = useMemo(() => getQuestAsset(quest, QuestAssetType.VIDEO_PLAYER_VIDEO, void 0, true), [quest]);
memo2 = useMemo(() => getQuestAsset(quest, QuestAssetType.VIDEO_PLAYER_VIDEO_HLS, void 0, true), [quest]);
const videoAssetId = memo2?.url != null ? QuestAssetType.VIDEO_PLAYER_VIDEO_HLS : QuestAssetType.VIDEO_PLAYER_VIDEO;
[state, setState] = useState(questTaskDetails.targetSeconds);
targetSeconds = questTaskDetails.targetSeconds;
const r17 = VideoQuestUIStore((a0) => a0.setVideoProgress);
c20962_13 = r17;
const initialProgress = VideoQuestUIStore((a0) => {
let r8 = a0.videoProgress[quest.id];
if (r8 == null) {
r8 = {
timestampSec: questTaskDetails.progressSeconds,
duration: state,
maxTimestampSec: questTaskDetails.progressSeconds
};
}
return r8;
}, shallow);
ref = useRef(null);
let playerState;
[playerState, setState2] = useState(_AdVideoPlayer.PlayerState.LOADING);
ref2 = useRef(questTaskDetails.progressSeconds);
const videoQuestPlayerAnalytics = useVideoQuestPlayerAnalytics({
duration: state,
isQuestCompleted,
playerState,
questId: quest.id,
videoSessionId,
videoAssetId,
sourceQuestContent
});
handleBufferAnalytics = videoQuestPlayerAnalytics.handleBufferAnalytics;
handleEndAnalytics = videoQuestPlayerAnalytics.handleEndAnalytics;
handleErrorAnalytics = videoQuestPlayerAnalytics.handleErrorAnalytics;
handleLoadAnalytics = videoQuestPlayerAnalytics.handleLoadAnalytics;
handleLoadStartAnalytics = videoQuestPlayerAnalytics.handleLoadStartAnalytics;
handlePausePlaybackAnalytics = videoQuestPlayerAnalytics.handlePausePlaybackAnalytics;
handleProgressAnalytics = videoQuestPlayerAnalytics.handleProgressAnalytics;
handleReadyForDisplayAnalytics = videoQuestPlayerAnalytics.handleReadyForDisplayAnalytics;
handleResumePlaybackAnalytics = videoQuestPlayerAnalytics.handleResumePlaybackAnalytics;
handleSeekAnalytics = videoQuestPlayerAnalytics.handleSeekAnalytics;
ref3 = useRef(null);
id = quest.id;
gameTitle = quest.config.messages.gameTitle;
let r46 = memo2?.url;
if (r46 == null) {
r46 = memo?.url;
}
url = r46;
const defaultWatchVideoTask = getDefaultWatchVideoTask(quest.config);
videoTitle = defaultWatchVideoTask == null ? void 0 : defaultWatchVideoTask.messages.videoTitle;
videoStreamType = memo2?.url != null ? "hls" : "mp4";
useEffect(() => {
if (url != null && url.length !== 0 && ref.current != null && getVideoQoEMetricsConfig({
location: QuestsExperimentLocations.VIDEO_MODAL_MOBILE
}).externalAnalyticsEnabled) {
const constants = getConstants();
ref3.current = new MobileMuxWrapper({
videoRef: ref.current,
feature: "quests",
appVersion: constants.Version,
releaseChannel: constants.ReleaseChannel,
contentMetadata: {
contentId: url,
videoStreamType,
contentType: "quests",
durationMs: 1000 * targetSeconds,
title: videoTitle,
questId: id,
gameName: gameTitle
}
});
ref3.current.initialize();
return () => {
if (ref3.current != null) {
ref3.current.onProgress(ref2.current);
ref3.current.destroy();
ref3.current = null;
}
};
}
}, [id, gameTitle, targetSeconds, url, videoTitle, videoStreamType]);
const callback = useCallback((a0) => {
setState2(a0);
}, []);
const callback2 = useCallback(() => {
handleReadyForDisplayAnalytics();
const current = ref3.current;
if (current != null) {
current.onReadyForDisplay();
}
}, [handleReadyForDisplayAnalytics]);
const callback3 = useCallback((a0) => {
const { duration, videoTracks, trackId, naturalSize } = a0;
setState(duration);
handleLoadAnalytics();
const current = ref3.current;
if (current != null) {
current.onLoad(duration);
}
if (naturalSize != null) {
const current2 = ref3.current;
if (current2 != null) {
current2.updateVideoSourceDimensions(naturalSize.width, naturalSize.height);
}
}
if (videoTracks != null && videoTracks.length > 0 && trackId != null && trackId.length > 0) {
const current3 = ref3.current;
if (current3 != null) {
current3.onVideoTrackChange(trackId, videoTracks);
}
}
if (onLoad != null) {
onLoad(a0);
}
}, [handleLoadAnalytics, onLoad]);
const callback4 = useCallback((a0) => {
const fromTimeSec = a0.fromTimeSec;
ref2.current = a0.currentTime;
if (state > 0) {
c20962_13(quest.id, a0.currentTime, state);
}
handleSeekAnalytics(fromTimeSec, a0.currentTime);
const current = ref3.current;
if (current != null) {
current.updatePlayheadTime(a0.currentTime);
}
const current2 = ref3.current;
if (current2 != null) {
current2.onSeek();
}
}, [state, handleSeekAnalytics, quest.id, r17]);
ref4 = useRef(0);
ref5 = useRef(0);
const callback5 = useCallback((a0) => {
ref2.current = a0.currentTime;
if (a0.currentTime >= ref4.current) {
sendVideoProgress(quest, a0.currentTime);
handleProgressAnalytics(a0.progress, a0.seekableDuration, a0.currentTime);
ref4.current = a0.currentTime + 6 + 2 * Math.random();
}
if (a0.currentTime >= ref5.current) {
updateOptimisticProgress(quest.id, questTaskDetails.taskType, a0.currentTime);
ref5.current = a0.currentTime + 1;
}
c20962_13(quest.id, a0.currentTime, a0.seekableDuration);
const current = ref3.current;
if (current != null) {
current.onProgress(a0.currentTime);
}
}, [quest, questTaskDetails.taskType, handleProgressAnalytics, r17]);
const callback6 = useCallback(() => {
sendVideoProgress(quest, state);
handleEndAnalytics();
const current = ref3.current;
if (current != null) {
current.onProgress(state);
}
const current2 = ref3.current;
if (current2 != null) {
current2.onEnd();
}
if (onEnd != null) {
onEnd();
}
}, [state, quest, handleEndAnalytics, onEnd]);
const callback7 = useCallback(() => {
handleLoadStartAnalytics();
const current = ref3.current;
if (current != null) {
current.onLoadStart();
}
const current2 = ref3.current;
if (current2 != null) {
current2.onPlay();
}
}, [handleLoadStartAnalytics]);
const callback8 = useCallback((a0) => {
handleErrorAnalytics(a0);
const current = ref3.current;
if (current != null) {
current.onError(a0);
}
}, [handleErrorAnalytics]);
const callback9 = useCallback(({ videoTracks, selectedVideoTrackId }) => {
if (videoTracks != null && videoTracks.length > 0 && selectedVideoTrackId != null && selectedVideoTrackId.length > 0) {
const current = ref3.current;
if (current != null) {
current.onVideoTrackChange(selectedVideoTrackId, videoTracks);
}
}
}, []);
const callback10 = useCallback((a0) => {
if ((a0 == null ? void 0 : a0.nativeEvent?.layout) != null) {
const layout = a0.nativeEvent.layout;
const { width, height } = layout;
if (width > 0 && height > 0) {
const current = ref3.current;
if (current != null) {
current.updateVideoDimensions(width, height);
}
}
}
}, []);
const callback11 = useCallback(() => {
handleResumePlaybackAnalytics();
const current = ref3.current;
if (current != null) {
current.onPlay();
}
}, [handleResumePlaybackAnalytics]);
const callback12 = useCallback(() => {
handlePausePlaybackAnalytics();
const current = ref3.current;
if (current != null) {
current.onPause();
}
}, [handlePausePlaybackAnalytics]);
const callback13 = useCallback((a0) => {
handleBufferAnalytics(a0);
const current = ref3.current;
if (current != null) {
current.onBuffer(a0);
}
}, [handleBufferAnalytics]);
const callback14 = useCallback((a0) => {
let top = contentInsets?.top;
if (top == null) {
top = 0;
}
let bottom = contentInsets?.bottom;
if (bottom == null) {
bottom = 0;
}
let left = contentInsets?.left;
if (left == null) {
left = 0;
}
let right = contentInsets?.right;
if (right == null) {
right = 0;
}
return <VideoQuestCaptions quest={quest} currentTime={a0} visible={visible} style={{
top,
bottom,
left,
right
}} />;
}, [quest, visible, contentInsets]);
const memo3 = useMemo(() => {
const r1 = memo == null;
let r2 = null;
if (!r1) {
let uri = memo2?.url;
if (uri == null) {
uri = memo.url;
}
r2 = {
uri
};
}
return r2;
}, [memo2, memo]);
const callback15 = useCallback(() => {
if (onToggleFullscreen != null) {
onToggleFullscreen({
orientation
});
}
}, [onToggleFullscreen, orientation]);
if (memo3 == null) {
return null;
}
const showFullscreenButton = orientation === "landscape";
return <AdVideoPlayer source={memo3} initialProgress={initialProgress} contentDuration={targetSeconds} allowUnrestrictedSeeking={isQuestCompleted} disableResumeOnLoad={isQuestCompleted} style={style} isFullscreen={isFullscreen} externallyPaused={externallyPaused} contentInsets={contentInsets} renderCaptions={callback14} onLoadStart={callback7} onLoad={callback3} onReadyForDisplay={callback2} onSeek={callback4} onBuffer={callback13} onError={callback8} onEnd={callback6} onPlayerStateChange={callback} onResumePlayback={callback11} onPausePlayback={callback12} onProgress={callback5} onVideoTracks={callback9} onVideoLayout={callback10} videoRef={ref} bufferingSpinnerPlacement={showFullscreenButton ? "center" : "top-left"} captionsEnabled={visible} showCaptionsButton={showFullscreenButton ? hasCaptionAsset : showFullscreenButton} showTranscriptButton={showFullscreenButton && hasTranscriptAsset} showFullscreenButton={showFullscreenButton} showProgress={showFullscreenButton} onToggleCaptions={handleToggleCaptions} onOpenTranscript={handleOpenTranscript} onToggleFullscreen={callback15} />;
});
export const PlayerState = _AdVideoPlayer.PlayerState;
export { r27 as VideoQuestPlayer };
@@ -0,0 +1,48 @@
// Metro module 14179 (f14180).
import { useEffect, useMemo } from "react";
import { ActivityIndicator } from "react-native";
import { FetchStatus, useVideoQuestUIStore } from "../../VideoQuestUIStore";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import useSafeAreaInsets_native from "../../../safe_area/useSafeAreaInsets.native";
import { getQuestAsset, QuestAssetType } from "../../lib/AssetUtils";
import { fetchVideoTranscript } from "../../QuestActionCreators";
import { ActionSheet } from "../../../../design/components/Sheet/native/ActionSheet.native";
import { BottomSheetTitleHeader } from "../../../../design/components/Sheet/native/BottomSheetTitleHeader.native";
import { intl, t } from "../../../../intl/index.native";
import { BottomSheetScrollView } from "../../../../_bundle/Module5245";
import { Stack } from "../../../../design/components/Stack/native/Stack.native";
import { Text } from "../../../../design/components/Text/native/Text";
const useStyles = createStyles({
content: {
paddingBottom: Module712.space.PX_8
},
loadingSpinner: {
height: 100
}
});
export default function VideoQuestTranscriptActionSheet(props) {
const quest = props.quest;
const styles = useStyles();
const videoQuestUIStore = useVideoQuestUIStore((a0) => a0.transcript);
const bottom = useSafeAreaInsets_native().bottom;
useEffect(() => {
const questAsset = getQuestAsset(quest, QuestAssetType.VIDEO_PLAYER_TRANSCRIPT, void 0, true);
if (videoQuestUIStore == null || videoQuestUIStore.questId !== quest.id || videoQuestUIStore.fetchStatus === FetchStatus.NONE || videoQuestUIStore.fetchStatus === FetchStatus.SUCCESS && questAsset?.url !== videoQuestUIStore.url) {
fetchVideoTranscript(quest, true);
}
}, [quest, videoQuestUIStore]);
const memo = useMemo(() => videoQuestUIStore?.text == null ? [] : videoQuestUIStore.text.split("\n").map((item) => item.trim()).filter((item) => item.length > 0), [videoQuestUIStore?.text]);
return <ActionSheet scrollable header={<BottomSheetTitleHeader title={intl.string(t["1YS80z"])} />}>
<BottomSheetScrollView contentContainerStyle={{
paddingBottom: bottom
}}>
<Stack spacing={16} style={styles.content}>
{videoQuestUIStore?.fetchStatus === FetchStatus.FETCHING && <ActivityIndicator style={styles.loadingSpinner} size="large" />}
{memo.length > 0 && memo.map((item, index) => <Text key={index} variant="heading-md/normal" color="text-muted">
{item}
</Text>)}
</Stack>
</BottomSheetScrollView>
</ActionSheet>;
};
@@ -0,0 +1,43 @@
// Metro module 14169 (f14170).
import { useMemo } from "react";
import { View } from "react-native";
import { createStyles } from "../../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../../_bundle/Module712";
import Module689 from "../../../../../_bundle/Module689";
import { useVideoQuestCaptions } from "../hooks/useVideoQuestCaptions";
import { findActiveCaption } from "./VideoQuestCaptionsUtils";
import VisualEffectView from "../../../../visual_effect_view/native/VisualEffectView";
import { Text } from "../../../../../design/components/Text/native/Text";
const useStyles = createStyles({
container: {
position: "absolute",
bottom: Module712.space.PX_32,
left: Module712.space.PX_16,
right: Module712.space.PX_16,
alignItems: "center",
justifyContent: "flex-end"
},
captionBox: {
backgroundColor: Module689(Module712.unsafe_rawColors.BLACK).alpha(0.35).hex(),
padding: Module712.space.PX_8,
borderRadius: Module712.radii.sm,
overflow: "hidden"
},
captionText: {
color: Module712.colors.WHITE,
textAlign: "center"
}
});
export function VideoQuestCaptions(props) {
const { quest, currentTime, style, visible = true } = props;
let c21001_1 = visible;
const styles = useStyles();
const videoQuestCaptions = useVideoQuestCaptions(quest);
const { captions, status } = videoQuestCaptions;
const memo = useMemo(() => captions != null ? c21001_1 ? findActiveCaption(captions, currentTime) : null : null, [captions, currentTime, visible]);
return status === "success" ? memo == null ? null : <View style={[styles.container, style]} importantForAccessibility="no-hide-descendants" accessibilityRole="none" accessible={false}>
<VisualEffectView style={styles.captionBox} blurTheme="dark" blurStyle="default" blurAmount={0.2}>
<Text variant="heading-sm/medium" style={styles.captionText}>{memo.text}</Text>
</VisualEffectView>
</View> : null;
}
@@ -0,0 +1,25 @@
// Metro module 14172 (f14173).
export function findActiveCaption(a0, a1) {
let r21;
let r1 = a0.length - 1;
let r8 = 0;
while (r8 <= r1) {
const r13 = Math.floor((r8 + r1) / 2);
const r15 = a0[r13];
const start = r15.start;
let r17 = r1;
const r18 = r8;
if (a1 >= start && a1 <= r15.end) {
return r15;
}
if (a1 < r15.start) {
r17 = r13 - 1;
r21 = r18;
} else {
r21 = r13 + 1;
}
r1 = r17;
r8 = r21;
}
return null;
}
@@ -0,0 +1,200 @@
// Metro module 14171 (f14172).
import { HermesBuiltin, $callWithNewTarget } from "../../../../../_hermes/prelude";
let c9947_1;
class VttParserError extends Error {
constructor(a0, a1) {
super(a0);
this.error = a1;
this.name = "ParserError";
}
}
c9947_1 = /([0-9]+)?:?([0-9]{2}):([0-9]{2}\.[0-9]{2,3})/;
export { VttParserError };
export function parseVtt(a0, r4 = {}) {
const meta = r4.meta;
let r8 = meta !== void 0 && meta;
const strict2 = r4.strict;
const strict3 = strict2 === void 0 || strict2;
const r29 = a0.trim().replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n\n");
const r31 = r29.shift();
if (r31.startsWith("WEBVTT")) {
const r43 = r31.split("\n");
const r47 = r43[0].replace("WEBVTT", "");
if (r47.length > 0 && r47[0] !== " " && r47[0] !== "\t") {
const prototypeOf3 = Object.getPrototypeOf(VttParserError);
const r111 = Object.create(VttParserError.prototype);
const r114 = $callWithNewTarget(prototypeOf3, r111, VttParserError, "Header comment must start with space or tab");
const r115 = r114 instanceof Object ? r114 : r111;
r115.error = void 0;
r115.name = "ParserError";
throw r115;
}
if (r29.length === 0 && r43.length === 1) {
return {
valid: true,
strict: strict3,
cues: [],
errors: []
};
}
if (!r8 && r43.length > 1 && r43[1] !== "") {
const prototypeOf2 = Object.getPrototypeOf(VttParserError);
const r64 = Object.create(VttParserError.prototype);
const r67 = $callWithNewTarget(prototypeOf2, r64, VttParserError, "Missing blank line after signature");
const r68 = r67 instanceof Object ? r67 : r64;
r68.error = void 0;
r68.name = "ParserError";
throw r68;
}
const strict = strict3;
const errors = [];
let c21003_1 = errors;
const cues = r29.map((item, index) => {
let r7;
try {
r7 = (function parseCue(a0, a1, a2) {
const r9 = a0.split("\n").filter(Boolean);
if (r9.length > 0 && r9[0].trim().startsWith("NOTE")) {
return null;
}
if (r9.length === 1 && !r9[0].includes("-->")) {
const r41 = `Cue identifier cannot be standalone (cue #${a1})`;
const prototypeOf = Object.getPrototypeOf(VttParserError);
const r46 = Object.create(VttParserError.prototype);
const r48 = $callWithNewTarget(prototypeOf, r46, VttParserError, r41);
const r49 = r48 instanceof Object ? r48 : r46;
r49.error = void 0;
r49.name = "ParserError";
throw r49;
}
if (r9.length > 1 && !r9[0].includes("-->") && !r9[1].includes("-->")) {
const r65 = `Cue identifier needs to be followed by timestamp (cue #${a1})`;
const prototypeOf2 = Object.getPrototypeOf(VttParserError);
const r71 = Object.create(VttParserError.prototype);
const r74 = $callWithNewTarget(prototypeOf2, r71, VttParserError, r65);
const r75 = r74 instanceof Object ? r74 : r71;
r75.error = void 0;
r75.name = "ParserError";
throw r75;
}
const identifier = r9.length > 1 && r9[1].includes("-->") ? r9.shift() : "";
const r89 = r9[0].split(" --> ");
if (r89.length === 2 && c9947_1.test(r89[0]) && c9947_1.test(r89[1])) {
const r100 = r89[0].match(c9947_1);
const r4 = r100 == null;
let start = 0;
if (!r4) {
const r18 = parseFloat;
let r17 = r100[1];
if (r17 == null) {
r17 = "0";
}
start = 60 * r18(r17) * 60 + 60 * parseFloat(r100[2]) + parseFloat(r100[3]);
}
const r116 = r89[1].match(c9947_1);
const r117 = r116 == null;
let end = 0;
if (!r117) {
const r119 = parseFloat;
let r120 = r116[1];
if (r120 == null) {
r120 = "0";
}
end = 60 * r119(r120) * 60 + 60 * parseFloat(r116[2]) + parseFloat(r116[3]);
}
if (a2) {
if (start > end) {
const r190 = `Start timestamp greater than end (cue #${a1})`;
const prototypeOf5 = Object.getPrototypeOf(VttParserError);
const r196 = Object.create(VttParserError.prototype);
const r199 = $callWithNewTarget(prototypeOf5, r196, VttParserError, r190);
const r200 = r199 instanceof Object ? r199 : r196;
r200.error = void 0;
r200.name = "ParserError";
throw r200;
}
if (end <= start) {
const r171 = `End must be greater than start (cue #${a1})`;
const prototypeOf4 = Object.getPrototypeOf(VttParserError);
const r177 = Object.create(VttParserError.prototype);
const r180 = $callWithNewTarget(prototypeOf4, r177, VttParserError, r171);
const r181 = r180 instanceof Object ? r180 : r177;
r181.error = void 0;
r181.name = "ParserError";
throw r181;
}
}
if (!a2 && end < start) {
const r139 = `End must be greater or equal to start when not strict (cue #${a1})`;
const prototypeOf3 = Object.getPrototypeOf(VttParserError);
const r145 = Object.create(VttParserError.prototype);
const r148 = $callWithNewTarget(prototypeOf3, r145, VttParserError, r139);
const r149 = r148 instanceof Object ? r148 : r145;
r149.error = void 0;
r149.name = "ParserError";
throw r149;
}
const styles = r89[1].replace(c9947_1, "").trim();
r9.shift();
const text = r9.join("\n");
if (text.trim() === "") {
return false;
}
return {
identifier,
start,
end,
text,
styles
};
}
const r209 = `Invalid cue timestamp (cue #${a1})`;
const prototypeOf6 = Object.getPrototypeOf(VttParserError);
const r215 = Object.create(VttParserError.prototype);
const r218 = $callWithNewTarget(prototypeOf6, r215, VttParserError, r209);
const r219 = r218 instanceof Object ? r218 : r215;
r219.error = void 0;
r219.name = "ParserError";
throw r219;
})(item, index, strict);
} catch ($e) {
c21003_1.push($e);
return null;
}
return r7;
}).filter((item) => item !== null && item !== false);
if (strict && errors.length > 0) {
throw errors[0];
}
let meta2 = null;
if (r8) {
const r82 = {};
let c21004_0 = r82;
r43.slice(1).forEach((item) => {
const r6 = item.indexOf(":");
c21004_0[item.slice(0, r6).trim()] = item.slice(r6 + 1).trim();
});
meta2 = Object.keys(r82).length > 0 ? r82 : null;
}
const r97 = {
valid: errors.length === 0,
strict,
cues,
errors
};
if (r8) {
r8 = {
meta: meta2
};
}
HermesBuiltin.copyDataProperties(r97, r8);
return r97;
}
const prototypeOf = Object.getPrototypeOf(VttParserError);
const r12 = Object.create(VttParserError.prototype);
const r38 = $callWithNewTarget(prototypeOf, r12, VttParserError, "Must start with \"WEBVTT\"");
const r39 = r38 instanceof Object ? r38 : r12;
r39.error = void 0;
r39.name = "ParserError";
throw r39;
}
@@ -0,0 +1,16 @@
// Metro module 14181 (f14182).
import ActionSheetStore from "../../../../action_sheet/native/ActionSheetStore";
import { useActiveContextMenu } from "../../../../../design/components/ContextMenu/native/ContextMenuState.native";
import { useOpenModalKey } from "../../../../main_tabs_v2/helpers/NavigationRouteUtils.native";
import { getVideoQuestModalKey } from "../../../utils/VideoQuestUtils";
import { useStateFromStores } from "../../../../../_bundle/Module589";
import { useAlertStore } from "../../../../../design/components/AlertModal/native/useAlertStore.native";
import { isIOS } from "../../../../../utils/PlatformUtils";
export function useVideoExternallyPaused(a0, a1) {
const activeContextMenu = useActiveContextMenu();
const openModalKey = useOpenModalKey();
const videoQuestModalKey = getVideoQuestModalKey(a0);
const stateFromStores = useStateFromStores([ActionSheetStore], () => ActionSheetStore.getKey());
const r2 = useAlertStore((a0) => a0.alerts).length > 0;
return isIOS() && a1 || stateFromStores != null || activeContextMenu != null || openModalKey !== videoQuestModalKey || r2;
}
@@ -0,0 +1,40 @@
// Metro module 14170 (f14171).
import { useState, useEffect } from "react";
import { getQuestAsset, QuestAssetType } from "../../../lib/AssetUtils";
import { HTTP } from "../../../../../_bundle/sendRequest";
import { parseVtt } from "../captions/VttParser";
let c9946_4 = {
NONE: "none",
LOADING: "loading",
SUCCESS: "success",
ERROR: "error"
};
export const useVideoQuestCaptions = (a0) => {
const url2 = getQuestAsset(a0, QuestAssetType.VIDEO_PLAYER_CAPTION, void 0, true)?.url;
const url = url2;
const [status, setState] = useState(c9946_4.NONE);
const [captions, setState2] = useState(null);
useEffect(() => {
if (url != null) {
HTTP.get({
url,
rejectWithError: true
}).then((result) => {
try {
setState2(parseVtt(result.text).cues);
setState(c9946_4.SUCCESS);
} catch ($e) {
setState(c9946_4.ERROR);
}
}).catch(() => {
setState(c9946_4.ERROR);
});
} else {
setState(c9946_4.NONE);
}
}, [url]);
return {
captions,
status
};
};
@@ -0,0 +1,269 @@
// Metro module 14158 (f14159).
import { useRef, useEffect, useCallback } from "react";
import { AppState } from "react-native";
import NetworkStore from "../../../../../stores/NetworkStore";
import { AnalyticEvents } from "../../../../../Constants";
import { useQuestImpression } from "../../../lib/analytics/ContentImpressionTrackerHooks";
import { trackQuestEvent } from "../../../lib/analytics/AnalyticsActions";
import { formatVideoProgressRatio } from "../../../utils/VideoQuestUtils";
import useVideoSegmentAnalytics, { SEGMENT_ANALYTICS_EMIT_INTERVAL_MS, SEGMENT_ANALYTICS_MIN_DURATION_MS } from "../../../../video_player/useVideoSegmentAnalytics";
import { PlayerState } from "../VideoQuestPlayer";
import { VideoPlayerState } from "../../../../../_bundle/Module5988";
import { VideoPauseReason } from "../../../QuestTypes";
import { isSourceError } from "../../AdsVideoUtils";
import MonitoringAgent from "../../../../monitoring/MonitoringAgent";
import { MetricEvents } from "../../../../../_bundle/Module5872";
export default function useVideoQuestPlayerAnalytics({ duration, isQuestCompleted, playerState, questId, sourceQuestContent, videoAssetId, videoSessionId }) {
let handlePlayerStateChange, handleLoadEnd, handleFirstFrame, handleSeek, ref3, ref4, ref5;
const ref = useRef(null);
const ref2 = useRef(null);
const questImpression = useQuestImpression();
useEffect(() => {
ref2.current = Date.now();
}, []);
useEffect(() => {
let c27646_0 = AppState.addEventListener("change", (a0) => {
if (ref.current != null) {
trackQuestEvent({
questId,
event: a0 === "active" ? AnalyticEvents.QUEST_VIDEO_APP_FOCUSED : AnalyticEvents.QUEST_VIDEO_APP_UNFOCUSED,
properties: {
video_timestamp_seconds: ref.current,
video_state: playerState,
video_session_id: videoSessionId,
impression_id: questImpression == null ? void 0 : questImpression.getId()
},
sourceQuestContent
});
}
});
return () => {
c27646_0.remove();
};
}, [questId, videoSessionId, playerState, questImpression, sourceQuestContent]);
const callback2 = useCallback((a0) => {
if (ref.current != null) {
trackQuestEvent({
questId,
event: AnalyticEvents.QUEST_VIDEO_SEGMENT_WATCHED,
properties: {
...a0,
video_asset_id: videoAssetId,
quest_completed: isQuestCompleted,
video_duration_sec: duration,
video_progress: formatVideoProgressRatio(a0.segment_end_sec, ref.current),
video_session_id: videoSessionId,
impression_id: questImpression == null ? void 0 : questImpression.getId()
},
sourceQuestContent
});
}
}, [questId, videoAssetId, isQuestCompleted, videoSessionId, duration, questImpression, sourceQuestContent]);
const videoSegmentAnalytics = useVideoSegmentAnalytics({
getCurrentVideoTime: useCallback(() => ref.current, []),
onAnalytics: callback2,
emitIntervalMs: SEGMENT_ANALYTICS_EMIT_INTERVAL_MS,
minSegmentDurationMs: SEGMENT_ANALYTICS_MIN_DURATION_MS
});
handlePlayerStateChange = videoSegmentAnalytics.handlePlayerStateChange;
handleLoadEnd = videoSegmentAnalytics.handleLoadEnd;
handleFirstFrame = videoSegmentAnalytics.handleFirstFrame;
handleSeek = videoSegmentAnalytics.handleSeek;
useEffect(() => {
if (PlayerState.PLAYING === playerState) {
handlePlayerStateChange(VideoPlayerState.PLAYING, null);
} else if (PlayerState.PAUSED === playerState) {
handlePlayerStateChange(VideoPlayerState.PAUSED, null);
} else if (PlayerState.ENDED === playerState) {
handlePlayerStateChange(VideoPlayerState.ENDED, null);
} else if (PlayerState.ERRORED === playerState) {
handlePlayerStateChange(VideoPlayerState.PAUSED, null);
}
}, [playerState, handlePlayerStateChange]);
ref3 = useRef(null);
const callback3 = useCallback(() => {
const duration2 = ref3.current != null ? Date.now() - ref3.current : null;
handleLoadEnd(duration2);
handleFirstFrame(0);
trackQuestEvent({
questId,
event: AnalyticEvents.QUEST_VIDEO_LOADING_ENDED,
properties: {
video_asset_id: videoAssetId,
network_connection_speed: NetworkStore.getEffectiveConnectionSpeed(),
duration: duration2,
video_session_id: videoSessionId,
impression_id: questImpression == null ? void 0 : questImpression.getId()
},
sourceQuestContent
});
}, [handleLoadEnd, handleFirstFrame, questId, videoAssetId, videoSessionId, questImpression, sourceQuestContent]);
const callback4 = useCallback(() => {
handlePlayerStateChange(VideoPlayerState.ENDED, null);
}, [handlePlayerStateChange]);
const callback5 = useCallback(() => {
ref3.current = Date.now();
trackQuestEvent({
questId,
event: AnalyticEvents.QUEST_VIDEO_LOADING_STARTED,
properties: {
video_asset_id: videoAssetId,
network_connection_speed: NetworkStore.getEffectiveConnectionSpeed(),
video_session_id: videoSessionId,
is_hls_supported: true,
impression_id: questImpression == null ? void 0 : questImpression.getId()
},
sourceQuestContent
});
}, [questId, videoSessionId, videoAssetId, questImpression, sourceQuestContent]);
ref4 = useRef(null);
ref5 = useRef(-1);
const callback = useCallback((a0) => {
const effectiveConnectionSpeed = NetworkStore.getEffectiveConnectionSpeed();
if (a0) {
ref4.current = Date.now();
ref5.current = ref5.current + 1;
trackQuestEvent({
questId,
event: AnalyticEvents.QUEST_VIDEO_BUFFERING_STARTED,
properties: {
video_asset_id: videoAssetId,
network_connection_speed: effectiveConnectionSpeed,
buffer_index: ref5.current,
video_session_id: videoSessionId,
impression_id: questImpression == null ? void 0 : questImpression.getId()
},
sourceQuestContent
});
} else {
trackQuestEvent({
questId,
event: AnalyticEvents.QUEST_VIDEO_BUFFERING_ENDED,
properties: {
video_asset_id: videoAssetId,
network_connection_speed: effectiveConnectionSpeed,
duration: ref4.current != null ? Date.now() - ref4.current : null,
buffer_index: ref5.current,
video_session_id: videoSessionId,
impression_id: questImpression == null ? void 0 : questImpression.getId()
},
sourceQuestContent
});
}
}, [questId, videoAssetId, videoSessionId, questImpression, sourceQuestContent]);
const callback6 = useCallback(() => {
if (ref2.current != null) {
trackQuestEvent({
questId,
event: AnalyticEvents.QUEST_VIDEO_TIME_TO_FIRST_FRAME,
properties: {
duration_ms: Date.now() - ref2.current,
video_session_id: videoSessionId,
video_asset_id: videoAssetId,
impression_id: questImpression == null ? void 0 : questImpression.getId()
},
sourceQuestContent
});
}
}, [questId, videoSessionId, videoAssetId, questImpression, sourceQuestContent]);
const callback7 = useCallback(() => {
trackQuestEvent({
questId,
event: AnalyticEvents.QUEST_VIDEO_RESUMED,
properties: {
video_timestamp_seconds: ref.current,
pause_reason: VideoPauseReason.PAUSE_BUTTON,
video_session_id: videoSessionId,
impression_id: questImpression == null ? void 0 : questImpression.getId()
},
sourceQuestContent
});
}, [questId, videoSessionId, questImpression, sourceQuestContent]);
const callback8 = useCallback(() => {
trackQuestEvent({
questId,
event: AnalyticEvents.QUEST_VIDEO_PAUSED,
properties: {
video_timestamp_seconds: ref.current,
reason: VideoPauseReason.PAUSE_BUTTON,
video_session_id: videoSessionId,
impression_id: questImpression == null ? void 0 : questImpression.getId()
},
sourceQuestContent
});
}, [questId, videoSessionId, questImpression, sourceQuestContent]);
return {
handleBufferAnalytics: callback,
handleEndAnalytics: callback4,
handleErrorAnalytics: useCallback((a0) => {
let current = ref.current;
if (current == null) {
current = 0;
}
const properties = {
video_progress: formatVideoProgressRatio(duration, current),
video_error_type: null,
video_asset_id: videoAssetId,
network_connection_speed: null,
video_session_id: videoSessionId,
video_error_code: a0 == null ? void 0 : a0.error.code,
video_error_message: null,
video_network_state: null,
impression_id: null
};
let video_error_message = a0 == null ? void 0 : a0.error.localizedDescription;
if (video_error_message == null) {
video_error_message = a0 == null ? void 0 : a0.error.errorString;
}
properties.video_error_message = video_error_message;
properties.impression_id = questImpression == null ? void 0 : questImpression.getId();
trackQuestEvent({
questId,
event: AnalyticEvents.QUEST_VIDEO_ERROR,
properties,
sourceQuestContent
});
if (isSourceError(a0)) {
MonitoringAgent.increment({
name: MetricEvents.QUEST_VIDEO_ERROR,
tags: [`quest_id:${questId}`, "error_type:SOURCE_ERROR"]
});
}
}, [duration, questId, videoAssetId, videoSessionId, questImpression, sourceQuestContent]),
handleLoadAnalytics: callback3,
handleLoadStartAnalytics: callback5,
handlePausePlaybackAnalytics: callback8,
handleProgressAnalytics: useCallback((a0, a1, a2) => {
ref.current = a2;
trackQuestEvent({
questId,
event: AnalyticEvents.QUEST_VIDEO_PROGRESSED,
properties: {
progress: a0,
video_timestamp_seconds: a1,
video_session_id: videoSessionId,
impression_id: questImpression == null ? void 0 : questImpression.getId()
},
sourceQuestContent
});
}, [questId, videoSessionId, questImpression, sourceQuestContent]),
handleReadyForDisplayAnalytics: callback6,
handleResumePlaybackAnalytics: callback7,
handleSeekAnalytics: useCallback((a0, a1) => {
handleSeek();
if (a0 != null) {
trackQuestEvent({
questId,
event: AnalyticEvents.QUEST_VIDEO_SEEKED,
properties: {
from_time_sec: a0,
to_time_sec: a1,
video_session_id: videoSessionId,
impression_id: questImpression == null ? void 0 : questImpression.getId()
},
sourceQuestContent
});
}
}, [handleSeek, questId, videoSessionId, questImpression, sourceQuestContent])
};
};
@@ -0,0 +1,10 @@
// Metro module 14051 (f14052).
import Module8531, { Path } from "../../../../../_bundle/Module8531";
export function SkipBackwardIcon(props) {
const { width = 24, height = 24, color = "currentColor", ...rest } = props;
return <Module8531 {...rest} width={width} height={height} viewBox="0 0 32 32" fill="none">
<Path d="M169.545 229.312v7.919l14.838-10.253v46.348h7.669v-55.434h-6.169l-16.338 11.42ZM225.979 274.576c13.087 0 21.34-11.003 21.34-28.842 0-17.756-8.253-29.093-21.34-29.093-13.004 0-21.173 11.254-21.173 29.009 0 17.923 8.169 28.926 21.173 28.926Zm0-7.335c-8.419 0-13.004-8.336-13.004-21.591 0-13.087 4.585-21.673 13.004-21.673 8.503 0 13.171 8.669 13.171 21.757 0 13.171-4.668 21.507-13.171 21.507Z" fill={color} fillRule="nonzero" transform="translate(-25.102 -30.774) scale(.19361)" />
<Path d="M137.108 31.459a160.22 160.22 0 0 0-30.316-2.894c-88.439 0-160.24 71.801-160.24 160.241 0 88.439 71.801 160.24 160.24 160.24 88.499 0 160.241-71.742 160.241-160.24h-31.365c0 71.176-57.699 128.876-128.876 128.876-71.128 0-128.876-57.748-128.876-128.876 0-71.129 57.748-128.877 128.876-128.877 8.183 0 16.347.78 24.382 2.328l5.934-30.798Z" fill={color} transform="matrix(-.0886 .03775 .03775 .0886 17.716 -4.317)" />
<Path d="M144.616 190.007V96.608l197.822 69.184-197.822 69.185v-44.97Z" fill={color} transform="matrix(-.0222 .01458 .04451 .06777 3.48 -8.53)" />
</Module8531>;
}
@@ -0,0 +1,10 @@
// Metro module 14052 (f14053).
import { forwardRef } from "react";
import Module8531, { Path } from "../../../../../_bundle/Module8531";
const r21 = forwardRef(({ width = 24, height = 24, color = "currentColor", ...rest }, a1) => <Module8531 {...rest} width={width} height={height} viewBox="0 0 32 32" fill="none" ref={a1}>
<Path d="M169.545 229.312v7.919l14.838-10.253v46.348h7.669v-55.434h-6.169l-16.338 11.42ZM225.979 274.576c13.087 0 21.34-11.003 21.34-28.842 0-17.756-8.253-29.093-21.34-29.093-13.004 0-21.173 11.254-21.173 29.009 0 17.923 8.169 28.926 21.173 28.926Zm0-7.335c-8.419 0-13.004-8.336-13.004-21.591 0-13.087 4.585-21.673 13.004-21.673 8.503 0 13.171 8.669 13.171 21.757 0 13.171-4.668 21.507-13.171 21.507Z" fill={color} fillRule="nonzero" transform="translate(-24.102 -30.774) scale(.19361)" />
<Path d="M137.108 31.459a160.22 160.22 0 0 0-30.316-2.894c-88.439 0-160.24 71.801-160.24 160.241 0 88.439 71.801 160.24 160.24 160.24 88.499 0 160.241-71.742 160.241-160.24h-31.365c0 71.176-57.699 128.876-128.876 128.876-71.128 0-128.876-57.748-128.876-128.876 0-71.129 57.748-128.877 128.876-128.877 8.183 0 16.347.78 24.382 2.328l5.934-30.798Z" fill={color} transform="matrix(.0886 .03775 -.03775 .0886 14.284 -4.317)" />
<Path d="M144.616 190.007V96.608l197.822 69.184-197.822 69.185v-44.97Z" fill={color} transform="matrix(.0222 .01458 -.04451 .06777 28.52 -8.53)" />
</Module8531>);
r21.displayName = "SkipForwardIcon";
export { r21 as SkipForwardIcon };
@@ -0,0 +1,19 @@
// Metro module 14148 (f14149).
import { v4 } from "../../../../_bundle/Module514";
import ModalActionCreators from "../../../../actions/ModalActionCreators";
import { handleVideoQuestModalClose, getVideoQuestModalKey } from "../../utils/VideoQuestUtils";
export default function openVideoQuestModal({ questId, sourceQuestContent, questContentPosition, initialStep }) {
const videoSessionId = v4();
return ModalActionCreators.pushLazy(import("./VideoQuestModal"), {
questId,
questContentPosition,
videoSessionId,
initialStep,
onClose: () => handleVideoQuestModalClose({
questId,
sourceQuestContent,
videoSessionId
}),
sourceQuestContent
}, getVideoQuestModalKey(questId));
};
@@ -0,0 +1,22 @@
// Metro module 14180 (f14181).
import { useCallback } from "react";
import { useGetQuestImpressionId } from "../../lib/analytics/ContentImpressionTrackerHooks";
import URLUtils from "../../../../utils/URLUtils";
import { getCtaLink } from "../../utils/QuestCopyUtils";
import { openGameLinkDirectly } from "../../utils/QuestPlatformUtils";
import { QuestContent } from "../../QuestTypes";
import { QuestContentCTA } from "../../lib/analytics/AnalyticsTypes";
export function useVideoQuestClickCtaAndMaybeCloseModal({ quest, onClose, sourceQuestContent }) {
const getQuestImpressionId = useGetQuestImpressionId();
return useCallback(() => {
if (URLUtils.isDiscordUrl(getCtaLink(quest.config), true)) {
onClose();
}
openGameLinkDirectly(quest, {
content: QuestContent.VIDEO_MODAL_MOBILE,
ctaContent: QuestContentCTA.OPEN_GAME_LINK,
impressionId: getQuestImpressionId(),
sourceQuestContent
});
}, [quest, getQuestImpressionId, sourceQuestContent, onClose]);
}