{"version":3,"sources":["webpack:///./app/javascript/components_v2/VideoPlayer/vjsComponents/SeekForward.js","webpack:///./app/javascript/components_v2/VideoPlayer/vjsComponents/SeekBackward.js","webpack:///./app/javascript/components_v2/VideoPlayer/VideoPlayerContext/customEvents.js","webpack:///./app/javascript/components_v2/VideoPlayer/vjsComponents/Settings.js","webpack:///./app/javascript/components_v2/VideoPlayer/VideoPlayerContext/reducer.js","webpack:///./app/javascript/components_v2/VideoPlayer/VideoPlayerContext/VideoPlayerContext.js","webpack:///./app/javascript/components_v2/VideoPlayer/VideoPlayerContext/index.js","webpack:///./app/javascript/components_v2/VideoPlayer/_videoPlayerStyles.js","webpack:///./app/javascript/components_v2/VideoPlayer/MusicPlayer/MusicPlayerContext.js","webpack:///./app/javascript/components_v2/VideoPlayer/MusicPlayer/_musicPlayerStyles.js","webpack:///./app/javascript/components_v2/VideoPlayer/MusicPlayer/FeedFMDisclimer.js","webpack:///./app/javascript/components_v2/VideoPlayer/MusicPlayer/MusicMarquee.js","webpack:///./app/javascript/components_v2/VideoPlayer/MusicPlayer/MusicPlayerCard.js","webpack:///./app/javascript/components_v2/VideoPlayer/MusicPlayer/MusicPlayer.js","webpack:///./app/javascript/components_v2/VideoPlayer/MusicPlayer/index.js","webpack:///./app/javascript/components_v2/VideoPlayer/SettingsPopout.js","webpack:///./app/javascript/components_v2/VideoPlayer/useVideoTracking.js","webpack:///./app/javascript/components_v2/VideoPlayer/VideoPlayerLayout.js","webpack:///./app/javascript/components_v2/VideoPlayer/VideoPlayerLocked.js","webpack:///./app/javascript/components_v2/VideoPlayer/VideoPlayer.js","webpack:///./app/javascript/components_v2/VideoPlayer/VideoPlayerLite.js","webpack:///./app/javascript/components_v2/VideoPlayer/index.js"],"names":["vjsComponent","videojs","getComponent","SeekForward","_vjsComponent","_inherits","_super","_createSuper","player","_this","_classCallCheck","call","state","seek","bind","_assertThisInitialized","ready","mountElement","on","ReactDOM","unmountComponentAtNode","el","key","value","render","this","renderSeekerButton","currentTime","React","createElement","SVGImage","width","height","SVG","Forward15","alt","registerComponent","SeekBackward","Rewind15","SHOW_SETTINGS_EVENT","Settings","toggleShow","toggleShowSettings","renderSettingsButton","trigger","SettingsIcon","INIT_RESOLUTIONS","SET_FIRST_PLAY","SET_METADATA","SET_BITRATE","TOGGLE_SETTINGS","UPDATE_TIME","UPDATE_VIDEO_PLAYER_STATUS","TRIAL_EXTEND","AUTO_BITRATE","initialState","currentBitrate","meta","playStarted","resolutions","showSettings","time","playerSatus","trialExtend","initializeState","JSON","parse","window","localStorage","getItem","_objectSpread","reducer","action","type","payload","currVal","require","Chromecast","Store","createContext","useVideoPlayerContext","useContext","SOURCE_TYPES","m3u8","mp4","webm","mov","VideoPlayerContext","_ref","src","poster","videoId","planMeta","children","videoRef","useRef","_useState2","_slicedToArray","useState","videoPlayer","setVideoPlayer","throttleTime","_useReducer2","useReducer","dispatch","toggleSettings","setFirstPlay","setBitrate","useCallback","bitrate","setItem","qualityLevels","i","length","level","enabled","useEffect","params","URLSearchParams","location","search","get","uuid","referrer","document","current","srcType","getFileExtension","options","controls","bigPlayButton","controlBar","pictureInPictureToggle","volumePanel","sources","techOrder","queryString","includes","substring","indexOf","Vhs","xhr","beforeRequest","test","uri","vjsPlayer","chromecast","buttonPositionIndex","dispose","setStatus","_ref2","e","qualityLevel","contentEl","oncontextmenu","hotkeys","volumeStep","seekStep","enableMute","enableFullscreen","enableVolumeScroll","casting_initiated_event","isSafari","isiPhone","resolution","push","sort","a","b","addChild","currentVideoTime","Math","floor","one","actions","Provider","Overlay","styled","withConfig","displayName","componentId","TitleContainer","VideoPlayerContainer","props","theme","colors","primary","fonts","Proxima","grey1","grey2","grey6","base","mediaQueries","small","BlackButton","useMusicContext","MusicContextProvider","musicEvents","_useVideoPlayerContex","musicPlayer","setMusicPlayer","_useState4","shouldPlayMusic","setShouldPlayMusic","_useState6","preferencesLoaded","setPreferencesLoaded","_useState8","eventVolume","setEventVolume","_useState10","parseInt","userVolume","setUserVolume","debouncedUserVolume","useDebounce","_useState12","stationId","setStationId","_useState14","stationsObject","setStationsObject","_useState16","currentSong","setCurrentSong","_useState18","showMarquee","setShowMarquee","_useState20","marqueeExiting","setMarqueeExiting","chromeCastRef","globalUserPreferencesFetch","Promise","resolve","reject","fetch","then","res","json","data","response","setupPlayer","_regeneratorRuntime","mark","_callee","wrap","_context","prev","next","axios","version","sent","token","secret","Feed","Player","initializeAudio","tune","t0","stop","apply","arguments","updateCurrentSong","event","album","audio_file","release","title","artist","name","song","track","concat","stations","forEach","station","stationID","id","configureStationsObject","getCurrentState","pause","desiredVolume","setVolume","feedStationId","handleChangeVolumeEvent","startTime","endTime","_event$data","eventStationId","startVolume","endVolume","stepAmount","newVolume","paused","play","handleFixedVolumeEvent","_event$data2","volume","_step","_iterator","_createForOfIteratorHelper","s","n","done","isInRange","eventType","err","f","checkEventTrack","contextValue","handleHideMarquee","setTimeout","handleUserVolumeChange","target","toggleShouldPlay","put","music_enabled","skipMusic","maybeCanSkip","skip","MusicContainer","Box","expand","MusicInfoBlock","FeedFMCopyright","Flex","FeedFMDisclimerModalWrapper","div","Disclaimer","P","css","fontSize","lineHeight","letterSpacing","marginTop","Title","H2","textAlign","color","FeedFMDisclimer","modal","useWindowResize","ContentModal","position","margin","left","top","borderRadius","useModal","MusicMarquee","skipError","_useMusicContext","useMemo","Marquee","callback","callbackTimeout","Caption","mt","whiteSpace","fontFamily","fontStyle","fontWeight","SkipButtonWrapper","MusicPlayerCard","isVideoPlayerIsPlay","setSkipError","clickedTimes","setClickedTimes","useModal_deprecated","skipMusicFunc","_window$dataLayer","isSkipped","dataLayer","status","_state$meta","videoOriginType","client_uuid","uuidv4","postBody","planId","planEntryId","video_origin_type","video_origin_subtype","occurred_at","Date","toUTCString","post","ga4Event","console","log","Fragment","className","justifyContent","pr","m","onClick","open","InfoIcon","Switch","label","checked","onChange","Transition","in","timeout","mountOnEnter","unmountOnExit","alignItems","style","cursor","MediaForward","MediaForwardDisabled","mr","MusicVolumeIcon","RangeSlider","min","max","ml","MusicPlayer","setMusicEvents","fetchRef","setAlert","useAlert","getMusicEvents","message","cta","text","link","MusicPlayerContext","ErrorBoundary","Container","show","RadioButtonContainer","SettingsPopup","ref","useOutsideClick","getElementsByClassName","setAttribute","p","as","CloseButton","variant","HR","RadioButton","mb","map","index","useVideoTracking","_ref3","_ref3$setSubscription","setSubscriptionEndTime","timeupdateEvents","setTimeupdateEvents","additionalData","setAdditionalData","completed","setCompleted","triggeredTimeArray","setTriggeredTimeArray","axiosPlain","ga4_event","getTimeupdateEvents","_asyncToGenerator","video_id","timestamps","getSuggestion","suggestion","_state$meta2","Array","isArray","_toConsumableArray","plan_entry_id","progress_seconds","_res$data","progress_percentage","duration","_res$data2","obj","Object","fromEntries","entries","replace","match","toLowerCase","resp","_resp$data","subscriptionEndTime","date","humanReadableDate","VideoPlayerLayout","assign","preload","SettingsPopout","Notification","mainText","ctaText","ctaLink","onLearnMoreClick","LockedImage","Image","VideoPlayerLocked","thumbnail","setThumbnail","fetchThumbnail","zIndex","href","unlock_membership_event","Locked","fill","flexDirection","H3","H6","VideoPlayer","_useFetchAPI2$","useFetchAPI","video","videoLoading","loading","videoError","error","Loading","ErrorComponent","hls","url","durationInMs","SafeVideoPlayer","VideoPlayerLite","rest","_objectWithoutProperties","_excluded"],"mappings":"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","file":"js/video-player-2a3245034c59ba8a82f6.chunk.js","sourcesContent":["import React from 'react'\nimport ReactDOM from 'react-dom'\nimport videojs from 'video.js'\n\nimport { Forward15 } from 'images/bend'\nimport { SVGImage } from 'ui/bend'\n\nconst vjsComponent = videojs.getComponent('Button')\n\nconst SEEK_TIME = 15\n\nclass SeekForward extends vjsComponent {\n constructor(player) {\n super(player)\n\n this.state = {\n player\n }\n this.seek = this.seek.bind(this)\n\n player.ready(() => {\n this.mountElement()\n })\n\n /* Remove React root when component is destroyed */\n this.on('dispose', () => {\n ReactDOM.unmountComponentAtNode(this.el())\n })\n\n this.on('click', this.seek)\n // Handle touch events\n this.on('touchstart', this.seek)\n }\n\n mountElement() {\n ReactDOM.render(this.renderSeekerButton(), this.el())\n }\n\n seek() {\n const currentTime = this.state.player.currentTime()\n this.state.player.currentTime(currentTime + SEEK_TIME)\n }\n\n renderSeekerButton() {\n return (\n \n )\n }\n}\n\nvjsComponent.registerComponent('seekForward', SeekForward)\n\nexport default SeekForward\n","import React from 'react'\nimport ReactDOM from 'react-dom'\nimport videojs from 'video.js'\n\nimport { Rewind15 } from 'images/bend'\nimport { SVGImage } from 'ui/bend'\n\nconst vjsComponent = videojs.getComponent('Button')\n\nconst SEEK_TIME = 15\n\nclass SeekBackward extends vjsComponent {\n constructor(player) {\n super(player)\n\n this.state = {\n player\n }\n this.seek = this.seek.bind(this)\n\n player.ready(() => {\n this.mountElement()\n })\n\n /* Remove React root when component is destroyed */\n this.on('dispose', () => {\n ReactDOM.unmountComponentAtNode(this.el())\n })\n\n this.on('click', this.seek)\n // Handle touch events\n this.on('touchstart', this.seek)\n }\n\n mountElement() {\n ReactDOM.render(this.renderSeekerButton(), this.el())\n }\n\n seek() {\n const currentTime = this.state.player.currentTime()\n this.state.player.currentTime(currentTime - SEEK_TIME)\n }\n\n renderSeekerButton() {\n return \n }\n}\n\nvjsComponent.registerComponent('seekBackward', SeekBackward)\n\nexport default SeekBackward\n","export const SHOW_SETTINGS_EVENT = 'SHOW_SETTINGS_EVENT'\n","import React from 'react'\nimport ReactDOM from 'react-dom'\nimport videojs from 'video.js'\n\nimport { Settings as SettingsIcon } from 'images/bend'\nimport { SHOW_SETTINGS_EVENT } from '../VideoPlayerContext/customEvents'\n\nconst vjsComponent = videojs.getComponent('Button')\n\nclass Settings extends vjsComponent {\n constructor(player) {\n super(player)\n\n this.state = {\n player\n }\n\n this.toggleShow = this.toggleShowSettings.bind(this)\n\n player.ready(() => {\n this.mountElement()\n })\n\n /* Remove React root when component is destroyed */\n this.on('dispose', () => {\n ReactDOM.unmountComponentAtNode(this.el())\n })\n\n this.on('click', this.toggleShowSettings)\n // Handle touch events\n this.on('touchstart', this.toggleShowSettings)\n }\n\n mountElement() {\n ReactDOM.render(this.renderSettingsButton(), this.el())\n }\n\n toggleShowSettings() {\n this.player().trigger(SHOW_SETTINGS_EVENT)\n }\n\n renderSettingsButton() {\n return \n }\n}\n\nvjsComponent.registerComponent('settings', Settings)\n\nexport default Settings\n","export const INIT_RESOLUTIONS = 'INIT_RESOLUTIONS'\nexport const SET_FIRST_PLAY = 'SET_FIRST_PLAY'\nexport const SET_METADATA = 'SET_METADATA'\nexport const SET_BITRATE = 'SET_RESOLUTION'\nexport const TOGGLE_SETTINGS = 'TOGGLE_SETTINGS'\nexport const UPDATE_TIME = 'UPDATE_TIME'\nexport const UPDATE_VIDEO_PLAYER_STATUS = 'UPDATE_VIDEO_PLAYER_STATUS'\nexport const TRIAL_EXTEND = 'TRIAL_EXTEND'\n\nexport const AUTO_BITRATE = -1\n\nexport const initialState = {\n currentBitrate: AUTO_BITRATE, // placeholder\n meta: null,\n playStarted: false,\n resolutions: [],\n showSettings: false,\n time: 0,\n playerSatus: null,\n trialExtend: false\n}\n\nexport const initializeState = (state) => {\n const currentBitrate =\n JSON.parse(window.localStorage.getItem('video-bitrate')) || AUTO_BITRATE\n return {\n ...state,\n currentBitrate\n }\n}\n\nconst reducer = (state, action) => {\n switch (action.type) {\n case INIT_RESOLUTIONS: {\n return {\n ...state,\n resolutions: action.payload\n }\n }\n case SET_FIRST_PLAY: {\n return {\n ...state,\n playStarted: true\n }\n }\n case SET_METADATA: {\n return {\n ...state,\n meta: action.payload\n }\n }\n case SET_BITRATE: {\n return {\n ...state,\n currentBitrate: action.payload\n }\n }\n case TOGGLE_SETTINGS: {\n const currVal = state.showSettings\n return {\n ...state,\n showSettings: !currVal\n }\n }\n case UPDATE_TIME: {\n return {\n ...state,\n time: action.payload\n }\n }\n case UPDATE_VIDEO_PLAYER_STATUS: {\n return {\n ...state,\n playerSatus: action.payload\n }\n }\n case TRIAL_EXTEND: {\n return {\n ...state,\n trialExtend: action.payload\n }\n }\n default: {\n return state\n }\n }\n}\n\nexport default reducer\n","import React, {\n useCallback,\n useEffect,\n useReducer,\n useRef,\n useState\n} from 'react'\nimport PropTypes from 'prop-types'\n\n/* videojs requires videojs.css, but this cannot load asynchronously for some reason. Therefore, we add it to GlobalStyles */\nimport videojs from 'video.js'\n\n// Set up chromecast\nimport Chromecast from '@silvermine/videojs-chromecast'\nimport '@silvermine/videojs-chromecast/dist/silvermine-videojs-chromecast.css'\n\nimport 'videojs-hotkeys/videojs.hotkeys'\nimport 'videojs-contrib-quality-levels'\n\n// We import these components so that they will register with videojs. See options.controlBar.children below for use.\nimport '../vjsComponents'\n\nimport { getFileExtension, isiPhone, isSafari } from 'helpers'\nimport { SHOW_SETTINGS_EVENT } from './customEvents'\n\nimport reducer, {\n initialState,\n initializeState,\n AUTO_BITRATE,\n INIT_RESOLUTIONS,\n SET_FIRST_PLAY,\n SET_METADATA,\n SET_BITRATE,\n TOGGLE_SETTINGS,\n UPDATE_TIME,\n UPDATE_VIDEO_PLAYER_STATUS,\n TRIAL_EXTEND\n} from './reducer'\nimport { casting_initiated_event } from 'gtm/pushEvents'\n\nrequire('https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1')\n\n// initialize Chromecast plugin\nChromecast(videojs)\n\nconst Store = React.createContext(null)\nexport const useVideoPlayerContext = () => React.useContext(Store)\n\nconst SOURCE_TYPES = {\n m3u8: 'application/x-mpegURL',\n mp4: 'video/mp4',\n webm: 'video/webm',\n mov: 'video/mp4'\n}\n\n/*********\n * VideoPlayerContext sets up and manages our video player.\n * It exposes a few stateful objects that children can hook into:\n *\n * @param {string} src - The source of the video.\n * @param {string} poster - The url for the poster to be displayed before playing.\n * @param {number} videoId - Id of the video playing, this will trigger musicPlayer and tracking if present.\n * @param {Object} planMeta - An object with plan meta-information\n * @param {number} planMeta.planId - The id of the plan to which this video belongs\n * @param {number} planMeta.planEntryId - The planEntry id to which this video belongs\n * @param {string} planMeta.videoOriginType - The type of page that belongs the video\n *\n * @returns {Object} state - { currentBitrate, meta, resolutions, showSettings, time }\n * @returns {Object} actions - { setBitrate(), toggleShow() }\n * @returns {Object} videoPlayer - the video player object\n * @returns {Object} videoRef - the useRef() ref used to attach to the video player dom element.\n */\nconst VideoPlayerContext = ({\n src,\n type,\n poster,\n videoId,\n planMeta,\n resolutions,\n trialExtend,\n children\n}) => {\n const videoRef = useRef()\n const [videoPlayer, setVideoPlayer] = useState()\n const throttleTime = useRef(null) // {int} - We use a ref to throttle our event lookup to once per second.\n const [state, dispatch] = useReducer(reducer, initialState, initializeState)\n\n const toggleSettings = () => {\n dispatch({ type: TOGGLE_SETTINGS })\n }\n\n const setFirstPlay = () => {\n dispatch({ type: SET_FIRST_PLAY })\n }\n\n /**\n * Sets a user's target bitrate, updates state, and persists their choice to localStorage.\n * @param {number} bitrate - the target bitrate we wish to switch to.\n */\n const setBitrate = useCallback(\n (bitrate) => {\n const currentBitrate = state.currentBitrate\n\n if (currentBitrate !== bitrate) {\n window.localStorage.setItem('video-bitrate', bitrate)\n const qualityLevels = videoPlayer.qualityLevels()\n\n for (let i = 0; i < qualityLevels.length; i++) {\n let level = qualityLevels[i]\n if (level.bitrate === bitrate || bitrate === AUTO_BITRATE) {\n level.enabled = true\n } else {\n level.enabled = false\n }\n }\n\n dispatch({ type: SET_BITRATE, payload: bitrate })\n }\n },\n [videoPlayer, state]\n )\n\n /* Set up meta information */\n useEffect(() => {\n const params = new URLSearchParams(window.location.search)\n const meta = {\n ...planMeta,\n videoId,\n type: params.get('type'),\n uuid: params.get('uuid'),\n referrer: params.get('referrer') || document.referrer\n }\n\n dispatch({ type: SET_METADATA, payload: meta })\n }, [planMeta, videoId])\n\n /* Set up and instantiate video player */\n useEffect(() => {\n if (videoRef.current) {\n // Grab the file extension from the incoming source and map it to a valid source type\n // We allow an explicit type override, because local file blobs do not have extensions.\n const srcType = SOURCE_TYPES[type] || SOURCE_TYPES[getFileExtension(src)]\n\n // Set up video player options.\n // We use options.controlBar.children, rather than other ways to populate the control bar, so we can have it set tab-stops correctly.\n const options = {\n controls: true,\n bigPlayButton: false,\n controlBar: {\n pictureInPictureToggle: false,\n volumePanel: false,\n children: [\n 'seekBackward',\n 'playToggle',\n 'seekForward',\n 'currentTimeDisplay',\n 'progressControl',\n 'remainingTimeDisplay',\n 'fullscreenToggle'\n ]\n },\n sources: {\n src,\n type: srcType\n },\n techOrder: ['chromecast', 'html5'],\n poster\n }\n\n // we get the bunny token to bring and sign the chunks of this video\n let queryString = ''\n if (src.includes('?') && src.includes('token')) {\n queryString = src.substring(src.indexOf('?'))\n }\n\n // .ts files are the chunks of the streamming video (aka. file.m3u8)\n // Every .ts file have a lenght of 4 seconds,\n // This function allows us to append the auth-token to the request whenever a chunk file is requested.\n videojs.Vhs.xhr.beforeRequest = function (options) {\n if (/(\\.ts|video\\.m3u8)$/.test(options.uri)) {\n options.uri += queryString\n }\n }\n\n const vjsPlayer = videojs(videoRef.current, options)\n\n // we need to set the button position for Chromecast here, rather than in options.controlBar.children because that's the way this plugin works I guess. ¯\\_(ツ)_/¯\n vjsPlayer.chromecast({ buttonPositionIndex: 6 })\n\n setVideoPlayer(vjsPlayer)\n }\n\n return () => {\n // clear out player when component is unmounted.\n if (videoPlayer) {\n videoPlayer.dispose()\n }\n }\n }, [poster, src, type, videoPlayer, videoRef])\n\n /* Attach event listeners to videoPlayer once it is instantiated */\n useEffect(() => {\n if (videoPlayer) {\n // Disable right clicking on the player itself.\n const disableRightClick = () => {\n videoPlayer.contentEl().oncontextmenu = () => {\n return false\n }\n }\n\n // Set up hotkeys\n const setupHotkeys = () => {\n videoPlayer.hotkeys({\n volumeStep: 0.1,\n seekStep: 15,\n enableMute: true,\n enableFullscreen: true,\n enableVolumeScroll: false\n })\n }\n // A wrapper for all of our on('ready') callbacks\n const onReadyCallbacks = () => {\n disableRightClick()\n setupHotkeys()\n }\n\n const setStatus = ({ type }) => {\n dispatch({ type: UPDATE_VIDEO_PLAYER_STATUS, payload: type })\n }\n\n // Keep our state.time in sync to the nearest second.\n const handleTimeChange = () => {\n // handleTimeChange needs to use a throttleTime ref because it is a callback in an event listener.\n // This means that React can't update it via useCallback.\n const currentVideoTime = Math.floor(videoPlayer.currentTime())\n\n if (throttleTime.current !== currentVideoTime) {\n dispatch({ type: UPDATE_TIME, payload: currentVideoTime })\n throttleTime.current = currentVideoTime // keep throttle time ref updated.\n }\n }\n\n // Create a resolutions array, sorted highest bitrate to lowest, and add it to state.\n // Our resolution picker uses this state to work.\n const initResolutions = () => {\n if (!isSafari() || isiPhone()) {\n const qualityLevels = videoPlayer.qualityLevels()\n let resolutions = []\n\n // qualityLevels is not an iterable, but its getter prototype is overloaded to act as an array. ¯\\_(ツ)_/¯\n for (let i = 0; i < qualityLevels.length; i++) {\n const bitrate = qualityLevels[i].bitrate\n const resolution = qualityLevels[i].height\n if (resolution && bitrate) {\n resolutions.push({ bitrate, resolution })\n continue\n }\n // Videos on BunnyCDN have a bitrate and resolution in playlist.m3u8, so logic below only applies to AWS.\n // The switch logic remains below in case we switch back to AWS for our streaming CDN (e.g. if BunnyCDN\n // has an outage)\n switch (bitrate) {\n case 5000000: {\n resolutions.push({\n bitrate,\n resolution: '720'\n })\n break\n }\n case 2040000: {\n resolutions.push({\n bitrate,\n resolution: '480'\n })\n break\n }\n case 640000: {\n resolutions.push({\n bitrate,\n resolution: '360'\n })\n break\n }\n default: {\n break\n }\n }\n }\n\n // If there are resolutions present, then we enable settings menu.\n if (resolutions.length > 0) {\n // We can't ensure the order of our resolutions, so we sort them highest to lowest here.\n resolutions.sort((a, b) => b.resolution - a.resolution)\n videoPlayer.controlBar.addChild('settings')\n }\n\n dispatch({ type: INIT_RESOLUTIONS, payload: resolutions })\n }\n }\n\n videoPlayer.qualityLevels().on('addqualitylevel', (e) => {\n const qualityLevel = e.qualityLevel\n // We do not need, or want, to add state to our dep array, as:\n // 1) We do not want to trigger the effect on every state change.\n // 2) We only need the initial value in state.\n if (\n state.currentBitrate === qualityLevel.bitrate ||\n state.currentBitrate === AUTO_BITRATE\n ) {\n qualityLevel.enabled = true\n } else {\n qualityLevel.enabled = false\n }\n })\n const onTrialExtend = () =>\n dispatch({ type: TRIAL_EXTEND, payload: trialExtend })\n\n videoPlayer.on('ready', onTrialExtend)\n videoPlayer.on('ready', onReadyCallbacks)\n videoPlayer.on('pause', setStatus)\n videoPlayer.on('play', setStatus)\n videoPlayer.on('chromecastConnected', () => {\n // When chromecast is going, trigger casting_initiated event\n casting_initiated_event('chromecast')\n })\n videoPlayer.on('airplayConnected', () => {\n // When airplay is going, trigger casting_initiated event\n casting_initiated_event('airplay')\n })\n videoPlayer.on('loadedmetadata', initResolutions)\n videoPlayer.on('timeupdate', handleTimeChange)\n videoPlayer.on(SHOW_SETTINGS_EVENT, toggleSettings)\n videoPlayer.one('play', setFirstPlay)\n }\n\n return () => {\n if (videoPlayer) {\n return videoPlayer.dispose()\n }\n }\n }, [videoPlayer])\n\n const actions = {\n setBitrate,\n toggleSettings\n }\n\n return (\n \n {children}\n \n )\n}\n\nVideoPlayerContext.propTypes = {\n src: PropTypes.string.isRequired,\n poster: PropTypes.string,\n videoId: PropTypes.number,\n planMeta: PropTypes.shape({\n planId: PropTypes.number,\n planEntryId: PropTypes.number,\n videoOriginType: PropTypes.string\n }),\n children: PropTypes.node\n}\n\nexport default VideoPlayerContext\n","import VideoPlayerContext from './VideoPlayerContext'\nexport { useVideoPlayerContext } from './VideoPlayerContext'\nexport { AUTO_BITRATE } from './reducer'\n\nexport default VideoPlayerContext\n","import styled from 'styled-components'\n\n// import { MusicContainer } from './MusicPlayer'\n\nimport BlackButton from '@silvermine/videojs-chromecast/dist/images/ic_cast_black_24dp.png'\n\nconst Overlay = styled('div')`\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n pointer-events: none;\n transition: all 0.3s ease-in;\n background: linear-gradient(\n 122.87deg,\n rgba(255, 255, 255, 0.8) 22%,\n rgba(255, 255, 255, 0.2) 50.03%\n );\n visibility: visible;\n z-index: 1; /* Overlay video poster */\n`\n\nconst TitleContainer = styled('div')`\n display: flex;\n flex-direction: column;\n position: absolute;\n top: 24px;\n left: 24px;\n transition: all 0.3s ease-in;\n transform: translateX(0);\n opacity: 1;\n visibility: visible;\n z-index: 1; /* Overlay poster */\n`\n\n/*\n * VideoPlayerContainer is the wrapper for all of videoJS.\n * This also includes the transition handlers for title card, and overlay information.\n * MusicCard transitions are in _musicPlayerStyles.js, which imports VideoPlayerContainer.\n */\nconst VideoPlayerContainer = styled('div')`\n --video-player-animation-default: all 0.3s ease-in-out;\n\n overflow: hidden;\n\n .video-js {\n cursor: pointer;\n color: ${(props) => props.theme.colors.primary};\n font-family: ${(props) => props.theme.fonts.Proxima};\n font-size: 14px;\n height: auto;\n width: auto;\n\n &.vjs-has-started .vjs-control-bar {\n transition: var(--video-player-animation-default);\n }\n\n &.vjs-has-started.vjs-user-inactive.vjs-playing {\n ${Overlay} {\n transition: var(--video-player-animation-default);\n opacity: 0;\n visibility: hidden;\n }\n\n ${TitleContainer} {\n transition: var(--video-player-animation-default);\n transform: translateY(-100%);\n opacity: 0;\n visibility: hidden;\n background: transparent;\n }\n\n .vjs-control-bar {\n transform: translateY(100%);\n transition: visibility 0.3s, opacity 0.3s, transform 0.3s ease-in-out;\n }\n }\n\n #close-settings-menu {\n /* We need to override vjs button colors here*/\n background-color: ${(props) => props.theme.colors.grey1};\n\n :hover {\n background-color: ${(props) => props.theme.colors.grey2};\n }\n }\n\n .vjs-play-progress {\n /* Completed section of progress bar */\n background-color: ${(props) => props.theme.colors.primary};\n }\n\n .vjs-progress-control {\n /* allow for center align of progress knob */\n .vjs-slider-bar {\n display: flex;\n }\n\n /* increase size of progress knob and center it */\n .vjs-slider-bar:before {\n font-size: 20px;\n align-self: center;\n top: auto;\n }\n\n /* Make progress bar smaller until height change */\n .vjs-slider-horizontal {\n height: 2px;\n transition: height 0.1s ease-in-out;\n }\n }\n\n .vjs-progress-control:hover {\n /* Don't change progress knob on hover */\n .vjs-slider-bar:before {\n font-size: 20px;\n }\n\n /* Increase progress bar height on hover */\n .vjs-slider-horizontal {\n height: 4px;\n }\n }\n\n .vjs-load-progress {\n background: ${(props) => props.theme.colors.grey6};\n }\n\n .vjs-slider {\n /* Uncompleted section of progress-bar */\n background-color: ${(props) => props.theme.colors.grey2};\n }\n\n .vjs-control-bar {\n z-index: 2; /* Place over Overlay */\n display: flex;\n height: 48px;\n padding: 0px 12px;\n background-color: ${(props) => props.theme.colors.base};\n box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.06),\n 0px 8px 16px rgba(35, 41, 54, 0.08);\n opacity: ${(props) => (props.showSettings ? '0' : '1')};\n visibility: ${(props) => (props.showSettings ? 'hidden' : 'visible')};\n\n transition: opacity 0.3s ease-in-out, visibility 0.3s ease-in-out;\n\n .vjs-play-control span:before {\n font-size: 2em;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: unset;\n }\n\n .vjs-button {\n width: 40px !important; /* booo, must use !important to override CSS order (.vjs-control)*/\n }\n\n .vjs-icon-placeholder:before {\n line-height: 1.8em; /* magic numbers, yay! This is the same font-size as the play and full-screen icons */\n }\n\n .vjs-time-control {\n display: none;\n padding: 0;\n min-width: 40px;\n ${(props) => props.theme.mediaQueries.small} {\n /* display and center-align our current and remaining time divs above small breakpoint*/\n display: flex;\n align-items: center;\n justify-content: center;\n }\n }\n\n .vjs-chromecast-button .vjs-icon-placeholder {\n background: url(${BlackButton}) center center no-repeat;\n background-size: contain;\n width: 20px;\n height: 20px;\n margin: 0;\n }\n }\n }\n`\n\nexport {\n // MusicContainer,\n Overlay,\n TitleContainer,\n VideoPlayerContainer\n}\n","import React, { useContext, useEffect, useRef, useState } from 'react'\nimport Feed from 'feed-media-audio-player'\n\nimport { axios } from 'api'\nimport { useDebounce } from 'hooks'\nimport { isInRange } from 'helpers'\nimport { useVideoPlayerContext } from 'components_v2/VideoPlayer/VideoPlayerContext'\n\nconst Store = React.createContext()\nexport const useMusicContext = () => useContext(Store)\n\nconst MusicContextProvider = ({ musicEvents, children }) => {\n const { videoPlayer, state } = useVideoPlayerContext()\n\n const [musicPlayer, setMusicPlayer] = useState(null)\n const [shouldPlayMusic, setShouldPlayMusic] = useState()\n const [preferencesLoaded, setPreferencesLoaded] = useState(false) // we need to toggle this before rendering children, because shouldPlayMusic is tied to a controllable child. If we set it after rendering the component, we get an error and things go wonky.\n\n const [eventVolume, setEventVolume] = useState(1.0) // {float} - the desired volume ratio given to us from music events.\n const [userVolume, setUserVolume] = useState(\n parseInt(localStorage.getItem('musicVolume')) || 50\n )\n const debouncedUserVolume = useDebounce(userVolume, 150)\n const [stationId, setStationId] = useState(null)\n\n const [stationsObject, setStationsObject] = useState() // An object to hold the mapping between feedFM music ID (ephemeral) and station names assigned by us (permanent)\n const [currentSong, setCurrentSong] = useState()\n const [showMarquee, setShowMarquee] = useState(false)\n const [marqueeExiting, setMarqueeExiting] = useState(false)\n\n const chromeCastRef = useRef()\n\n /* Set user's musicEnabled preferences */\n useEffect(() => {\n // We rely on a promise tied to window object because we call this context multiple times per legacy page.\n // We don't want to slam the API that many times per page, so we bundle them up together.\n // TODO: react-refactor : get rid of this and put into a context.\n const globalPreferenceFetch = () => {\n if (!window.globalUserPreferencesFetch) {\n window.globalUserPreferencesFetch = new Promise((resolve, reject) => {\n fetch('/api/v2/users/preferences/music_enabled')\n .then((res) => res.json())\n .then((data) => resolve(data))\n .catch((response) => reject(response))\n })\n }\n\n return window.globalUserPreferencesFetch\n .then((data) => {\n if (shouldPlayMusic !== data) {\n setShouldPlayMusic(data)\n setPreferencesLoaded(true)\n }\n })\n .catch((res) => {\n // On error just auto-play music.\n setShouldPlayMusic(true)\n setPreferencesLoaded(true)\n })\n }\n\n globalPreferenceFetch()\n }, [])\n\n /* Keeps range input in sync with state */\n const handleUserVolumeChange = (e) => {\n setUserVolume(e.target.value)\n }\n\n /* Persist user's musicPlay choice to state and user preferences. Used in MusicPlayerCard.js */\n const toggleShouldPlay = () => {\n axios.put('/preferences', {\n music_enabled: !shouldPlayMusic\n })\n setShouldPlayMusic(!shouldPlayMusic)\n }\n\n /* Used to hide the music card after the song title exits the marquee. Used in MusicMarquee.js */\n const handleHideMarquee = () => {\n setMarqueeExiting(true)\n setTimeout(() => setShowMarquee(false), 300)\n }\n\n /* Initialize and setup feedFM music player */\n useEffect(() => {\n const setupPlayer = async () => {\n try {\n // Get player token and secret from server.\n const res = await axios.get('music/token', {\n params: {\n version: '1'\n }\n })\n if (res && res.data && res.data.token && res.data.secret) {\n const player = new Feed.Player(res.data.token, res.data.secret)\n\n // initializeAudio() hooks music player into audio streams before doing anything else.\n // This prevents an audio hiccup on first play.\n if (player) {\n player.initializeAudio()\n player.tune()\n setMusicPlayer(player)\n }\n }\n } catch (e) {\n // Fail silently?\n }\n }\n\n setupPlayer()\n }, [])\n\n const updateCurrentSong = (event) => {\n const album = event.audio_file.release.title\n const artist = event.audio_file.artist.name\n const song = event.audio_file.track.title\n setCurrentSong(`${artist} · ${album} · ${song}`)\n }\n\n const skipMusic = () => {\n if (musicPlayer.maybeCanSkip()) {\n musicPlayer.skip()\n return true\n } else {\n return false\n }\n }\n\n /* Configure stationsObject and add Event listeners to keep currentSong updated */\n useEffect(() => {\n if (musicPlayer) {\n const configureStationsObject = (stations) => {\n const stationsObject = {}\n stations.forEach((station) => {\n station.options.stationID.forEach((id) => {\n stationsObject[id] = station.id\n })\n })\n setStationsObject(stationsObject)\n }\n\n // Attach event listeners to music player\n musicPlayer.on('play-started', updateCurrentSong)\n musicPlayer.on('play-resumed', updateCurrentSong)\n\n musicPlayer.on('stations', (stations) => {\n configureStationsObject(stations)\n })\n\n musicPlayer.on('play-stopped', () => {\n setCurrentSong(null)\n })\n\n musicPlayer.initializeAudio()\n }\n }, [musicPlayer])\n\n /* Pause music player if shouldPlayMusic toggled */\n useEffect(() => {\n if (musicPlayer && !shouldPlayMusic) {\n if (musicPlayer.getCurrentState() === 'playing') {\n musicPlayer.pause()\n }\n }\n }, [musicPlayer, shouldPlayMusic])\n\n /**\n * Attach music player to video player to keep them in sync.\n *\n * We do not want to play on unpause, as we want to ensure that the user's music is synced to the most-up-to-date music event;\n * e.g. they pause, skip ahead, and then click play, we want to handle gracefully\n **/\n useEffect(() => {\n if (musicPlayer && videoPlayer) {\n videoPlayer.on('play', () => musicPlayer.initializeAudio())\n videoPlayer.on('pause', () => musicPlayer.pause())\n videoPlayer.on('chromecastConnected', () => {\n // When chromecast is going, stop the music playing.\n // We want to keep track of whether the user wants to autoplay music.\n chromeCastRef.current = shouldPlayMusic\n setShouldPlayMusic(false)\n })\n videoPlayer.on('chromecastDisconnected', () => {\n if (chromeCastRef.current) {\n setShouldPlayMusic(chromeCastRef.current)\n }\n })\n }\n }, [musicPlayer, videoPlayer])\n\n /* Sync debouncedVolume to musicPlayer, mitigated by eventVolume. */\n useEffect(() => {\n // We typeof check eventVolume here, because 0 is falsey.\n if (musicPlayer && debouncedUserVolume && typeof eventVolume === 'number') {\n // eventVolume {float} is a percentage of debouncedUserVolume {int}, so divide it by 100.\n const desiredVolume = debouncedUserVolume * (eventVolume / 100)\n musicPlayer.setVolume(desiredVolume)\n }\n }, [musicPlayer, debouncedUserVolume, eventVolume])\n\n /* Persist user's volume choice to local storage after debounce */\n useEffect(() => {\n if (debouncedUserVolume) {\n localStorage.setItem('musicVolume', debouncedUserVolume)\n }\n }, [debouncedUserVolume])\n\n /* Display music card when a song plays during a video view !! CONTRACTUAL REQUIREMENT !! */\n useEffect(() => {\n if (currentSong) {\n /* Reset musicCardShowing states */\n setMarqueeExiting(false)\n setShowMarquee(true)\n }\n }, [currentSong])\n\n // TODO: feedfm - make sure setStation works correctly\n /* Trigger a feedfm station change when the stationId changes */\n useEffect(() => {\n if (musicPlayer && stationId && stationsObject) {\n const feedStationId = stationsObject[stationId]\n if (feedStationId) {\n musicPlayer.setStationId(feedStationId)\n }\n }\n }, [musicPlayer, stationId, stationsObject])\n\n const handleChangeVolumeEvent = (event) => {\n const { startTime, endTime } = event\n const { stationId: eventStationId, startVolume, endVolume } = event.data\n\n // Sync station to changeVolumeEvent\n if (stationId !== eventStationId) {\n setStationId(eventStationId)\n }\n\n // Calculate and set eventVolume for changeVolumeEvent\n const stepAmount = (endVolume - startVolume) / (endTime - 1 - startTime)\n const currentStep = state.time - startTime\n const newVolume = currentStep * stepAmount + startVolume\n if (eventVolume !== newVolume) {\n setEventVolume(newVolume)\n }\n if (musicPlayer.getCurrentState() !== 'playing' && !videoPlayer.paused()) {\n musicPlayer.play()\n }\n }\n\n const handleFixedVolumeEvent = (event) => {\n const { stationId: eventStationId, volume } = event.data\n\n if (stationId !== eventStationId) {\n setStationId(eventStationId)\n }\n if (eventVolume !== volume) {\n setEventVolume(volume)\n }\n if (musicPlayer.getCurrentState() !== 'playing' && !videoPlayer.paused()) {\n musicPlayer.play()\n }\n }\n\n /* Check music event track whenever video's state.time updates */\n useEffect(() => {\n const checkEventTrack = () => {\n // We use for(let n of m) here so we can bail out early (unlike .forEach())\n for (let event of musicEvents) {\n // We walk the musicEvents array and the range on each event.\n // If we are within that range, run the function and then bail out early. Otherwise, keep looking.\n if (isInRange(state.time, event.startTime, event.endTime)) {\n switch (event.eventType) {\n case 'no_music': {\n if (musicPlayer.getCurrentState() !== 'idle') {\n musicPlayer.pause()\n setCurrentSong()\n }\n break\n }\n case 'change_volume': {\n handleChangeVolumeEvent(event)\n break\n }\n case 'fixed_volume': {\n handleFixedVolumeEvent(event)\n break\n }\n default: {\n break\n }\n }\n }\n }\n }\n\n if (musicPlayer && state.time && shouldPlayMusic && !videoPlayer.paused()) {\n checkEventTrack()\n }\n\n return () => {}\n }, [videoPlayer, musicEvents, musicPlayer, shouldPlayMusic, state.time])\n\n const contextValue = {\n currentSong,\n handleHideMarquee,\n handleUserVolumeChange,\n marqueeExiting,\n shouldPlayMusic,\n toggleShouldPlay,\n showMarquee,\n userVolume,\n skipMusic\n }\n\n return (\n \n {preferencesLoaded && children}\n \n )\n}\n\nexport default MusicContextProvider\n","import styled from 'styled-components'\n\nimport { Box, Flex } from 'ui/bend'\nimport { VideoPlayerContainer } from 'components_v2/VideoPlayer/_videoPlayerStyles'\n\nexport const MusicContainer = styled(Box)`\n /* inherits --video-player-animation-default from _videoPlayerStyles.js */\n --music-player-height-collapsed: 108px;\n --music-player-height-expanded: 115px;\n --music-player-sub-component-height: 24px;\n\n background: ${(props) => props.theme.colors.base};\n max-height: ${(props) =>\n props.expand\n ? 'var(--music-player-height-expanded)'\n : 'var(--music-player-height-collapsed)'};\n width: ${(props) => (props.expand ? '232px' : '142px')};\n box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.06),\n 0px 8px 16px rgba(35, 41, 54, 0.08);\n overflow: hidden;\n padding: 8px 12px;\n display: flex;\n flex-direction: column;\n position: absolute;\n top: 24px;\n right: 0;\n transition: var(--video-player-animation-default);\n transform: translateX(0);\n opacity: 1;\n visibility: visible;\n z-index: 1; /* Overlay poster */\n\n ${VideoPlayerContainer} > .vjs-has-started.vjs-user-active & {\n /* Ensure that music is max-height whenever user is active */\n max-height: var(--music-player-height-expanded);\n\n .music-info-block {\n margin-top: 10px;\n }\n\n /* show the music toggle switch if the user is active, even if marquee is playing */\n .music-toggle-switch {\n max-height: var(---music-player-sub-component-height);\n transform: translateY(0);\n opacity: 1;\n visibility: visible;\n }\n }\n\n /* Show volume only after music is playing and a user is actively engaged */\n ${VideoPlayerContainer} > .vjs-has-started.vjs-user-active &:not(.no_music_playing) .music-volume-slider {\n margin-top: 8px;\n max-height: var(---music-player-sub-component-height);\n transform: translateY(0);\n opacity: 1;\n visibility: visible;\n }\n\n /* Hide the music player after play has started if a user is inactive and the marquee shouldn't be showing -- CONTRACTUAL REQUIREMENT !!*/\n ${VideoPlayerContainer} > .vjs-has-started.vjs-user-inactive.vjs-playing &:not(.show-marquee) {\n transition: all 0.3s ease-out;\n transform: translateY(-100%);\n opacity: 0;\n visibility: hidden;\n background: transparent;\n }\n\n .music-toggle-switch,\n .music-volume-slider {\n transition: var(--video-player-animation-default);\n }\n\n .music-info-block {\n margin-top: 10px;\n }\n\n .music-volume-slider {\n margin-top: 8px;\n }\n\n &.show-marquee,\n &.marquee-exiting {\n /* This will collapse the music player when user is inactive and show-marquee and marquee-exit are on the music player. */\n max-height: var(--music-player-height-collapsed);\n\n .music-info-block {\n margin-top: 0px;\n }\n\n .music-toggle-switch {\n max-height: 0;\n transform: translateY(-100%);\n opacity: 0;\n visibility: hidden;\n }\n }\n\n &.show-marquee,\n &.marquee-exiting,\n &.no_music_playing {\n .music-volume-slider {\n margin-top: 0px;\n max-height: 0;\n transform: translateY(100%);\n opacity: 0;\n visibility: hidden;\n }\n }\n`\n\n// TODO: rework-animations\nexport const MusicInfoBlock = styled(Box)`\n transition: 0.3s;\n opacity: ${(props) => (props.state === 'entered' ? 1 : 0)};\n`\n\nexport const FeedFMCopyright = styled(Flex)`\n align-items: center;\n\n span {\n color: #636363;\n font-size: 10px;\n padding-right: 5px;\n }\n`\n","import React from 'react'\nimport styled from 'styled-components'\nimport { css } from '@styled-system/css'\nimport ContentModal from 'ui/acro/blocks/ContentModal'\nimport { P, H2 } from 'ui/bend'\nimport { useWindowResize } from 'hooks'\n\nconst FeedFMDisclimerModalWrapper = styled.div`\n padding: 0.625rem 6.25rem;\n @media (max-width: 768px) {\n padding: 16px 12px;\n }\n`\nconst Disclaimer = styled(P)(() =>\n css({\n fontSize: '16px',\n lineHeight: '24px',\n letterSpacing: '0.352px',\n marginTop: '32px'\n })\n)\n\nconst Title = styled(H2)(() =>\n css({\n fontSize: '32px',\n lineHeight: '40px',\n textAlign: 'center',\n color: '#000',\n '@media (max-width: 768px)': {\n fontSize: '20px'\n }\n })\n)\n\nexport const FeedFMDisclimer = ({ modal }) => {\n const { width } = useWindowResize()\n\n return (\n 1200 ? '840px' : width > 768 ? '70%' : '92%'}\n position='relative'\n margin='0 auto'\n left='auto'\n top='102px'\n borderRadius='0px'\n useModal={modal}\n >\n \n feed.fm disclaimer\n \n There is no affiliation, connection, association or endorsement of the\n products, goods or services displayed on this page by the copyright\n owners, featured recording artists and authors of the sound recordings\n (and the musical works embodied therein) transmitted through the\n Feed.fm player.\n \n \n \n )\n}\n","import React, { useMemo } from 'react'\n\nimport { Caption, Marquee } from 'ui/bend'\nimport { useMusicContext } from './MusicPlayerContext'\n\nconst MusicMarquee = ({ skipError }) => {\n const { currentSong, handleHideMarquee } = useMusicContext()\n\n // useMemo is here so we don't recalculate the desired ticker width/speed on every MusicContext() update, even ones unrelated to currentSong.\n // We don't want to add handleHideMarquee, because that will trigger a re-render (and thus interrupt our animation) when handleHideMarquee gets recreated\n return useMemo(\n () => (\n \n \n {skipError\n ? 'Skip Max Reached'\n : currentSong || 'Play music during class'}\n \n \n ),\n [currentSong, skipError]\n )\n}\n\nexport default MusicMarquee\n","import React, { useState, useEffect } from 'react'\nimport { Transition } from 'react-transition-group'\nimport styled from 'styled-components'\nimport { css } from '@styled-system/css'\n\nimport { Flex, P, RangeSlider, Switch, SVGImage } from 'ui/bend'\nimport { MusicVolumeIcon } from 'images/bend'\nimport { MediaForward, MediaForwardDisabled } from 'images/bend'\nimport { useVideoPlayerContext } from '../VideoPlayerContext'\nimport uuidv4 from 'uuid/v4'\nimport { axios } from 'api'\n\nimport {\n MusicContainer,\n MusicInfoBlock,\n FeedFMCopyright\n} from './_musicPlayerStyles'\nimport { useMusicContext } from './MusicPlayerContext'\nimport { FeedFMDisclimer } from './FeedFMDisclimer'\nimport MusicMarquee from './MusicMarquee'\nimport { InfoIcon } from 'components_v2/Icons'\nimport { useModal_deprecated } from 'hooks'\n\nconst BodyText = styled(P)(() =>\n css({\n width: '57%',\n textAlign: 'left',\n whiteSpace: 'normal',\n fontFamily: 'Proxima-Nova',\n fontStyle: 'normal',\n fontWeight: '400',\n fontSize: '16px',\n lineHeight: '140%',\n margin: '30px 0 40px 0'\n })\n)\n\nconst SkipButtonWrapper = styled.div`\n &:active {\n opacity: 0.2;\n }\n`\nconst MusicPlayerCard = () => {\n const {\n currentSong,\n handleUserVolumeChange,\n shouldPlayMusic,\n toggleShouldPlay,\n userVolume,\n showMarquee,\n marqueeExiting,\n skipMusic\n } = useMusicContext()\n\n const { state } = useVideoPlayerContext()\n const isVideoPlayerIsPlay = state.playerSatus !== 'pause'\n\n const [skipError, setSkipError] = useState(false)\n const [clickedTimes, setClickedTimes] = useState(0)\n const modal = useModal_deprecated()\n\n /*\n * Our CSS-in-JS is kinda' wonky for this component because it will (for now) always be embedded within VideoJS.\n * VideoJS mainly uses CSS classes to indicate changes in state, we need to rely on the structure of CSS to work for us rather than against us.\n * What this means is that lots of animations are handled in the parent component (i.e. VideoPlayerContainer inside of _videoPlayerStyles.js)\n * This is especially true because there are multiple, intersecting states (.vjs-user-active/inactive, .vjs-has-started, .vjs-playing).\n *\n * Therefore, we use classNames rather than state or CSS-in-JS props to signal these things\n * .show-marque, .music-toggle-switch, and .music-volume-slider classs let this higher-up stylesheet how we want to display music card\n * We MUST display the song information when the first song plays for contractual reasons -- CONTRACT REQUIREMENT !!\n *\n * As a result, please be aware that animation is broken between BOTH _videoPlayerStyles.js and _musicPlayerStyles.js\n */\n\n /* If we find ourselves doing more chained className stuff, we might want to make a helper or use classNames */\n const musicContainerClassName = () => {\n // If music shouldn't be playing, don't add any classnames.\n // We do this so that way if a user turns off music while either showMarquee or marqueeExiting is true, we can immediately bail out and not show any UI.\n if (!shouldPlayMusic || !currentSong) return 'no_music_playing'\n\n if (showMarquee) {\n // We want marqueeExiting to override showMarquee, so that it can gracefully exit.\n if (marqueeExiting) return 'marquee-exiting'\n return 'show-marquee'\n }\n }\n\n const openModal = () => {\n modal.open()\n }\n\n const skipMusicFunc = () => {\n const isSkipped = skipMusic()\n if (!isSkipped) {\n setSkipError(true)\n setTimeout(() => {\n setSkipError(false)\n }, 3000)\n }\n\n // passing skip data to GA4 event\n window.dataLayer?.push({\n event: 'music_skipped',\n status: !isSkipped ? 'fail' : 'success'\n })\n }\n\n useEffect(() => {\n setClickedTimes(clickedTimes + 1)\n if (state.meta?.videoOriginType && clickedTimes >= 1) {\n // We need a new client_uuid every post request.\n const client_uuid = uuidv4()\n const identifier =\n state.meta.videoOriginType === 'Plan'\n ? state.meta.planId\n : state.meta.planEntryId\n const postBody = {\n id: identifier,\n video_origin_type: 'MusicVideo',\n video_origin_subtype: state.meta.videoOriginType,\n occurred_at: new Date().toUTCString(),\n client_uuid,\n state: shouldPlayMusic ? 'on' : 'off'\n }\n\n axios\n .post('video_events/handle_video_event', postBody)\n .then((res) => {\n if (res.data.ga4Event) {\n window.dataLayer.push(res.data.ga4Event)\n }\n })\n .catch((err) => {\n console.log(err)\n })\n }\n }, [shouldPlayMusic])\n\n return (\n <>\n \n \n {/* We set margin to 0 here to override application.css in legacy pages */}\n
\n \n Music\n

\n {shouldPlayMusic && (\n \n Powered by Feed.fm\n\n \n \n )}\n
\n \n
\n \n {(state) => (\n \n \n \n \n \n \n\n \n \n \n \n \n )}\n \n \n \n )\n}\n\nexport default MusicPlayerCard\n","import React, { Fragment, useEffect, useRef, useState } from 'react'\n\nimport { axios } from 'api'\nimport { useAlert } from 'hooks'\nimport { ErrorBoundary, isiPhone } from 'helpers'\n\nimport MusicPlayerContext from './MusicPlayerContext'\nimport MusicPlayerCard from './MusicPlayerCard'\nimport { useVideoPlayerContext } from '../VideoPlayerContext'\n\nconst MusicPlayer = () => {\n const { state } = useVideoPlayerContext()\n const [musicEvents, setMusicEvents] = useState()\n const fetchRef = useRef() // ensure that we only fetch music events once per player.\n const setAlert = useAlert()\n\n /* Get music events for a given video. We do this above MusicPlayerContext so we can bail out if none exist before setting up the context provider */\n useEffect(() => {\n const getMusicEvents = async () => {\n fetchRef.current = true\n try {\n const res = await axios.get(`/videos/${state.meta.videoId}/music`, {\n params: {\n version: '1'\n }\n })\n if (res && res.data && res.data.length > 0) {\n setMusicEvents(res.data)\n }\n } catch (e) {\n // fail silently. The most important thing is to not block users.\n }\n }\n\n if (state.meta && state.meta.videoId) {\n if (!fetchRef.current) {\n getMusicEvents()\n }\n }\n }, [state.meta])\n\n /* setAlert for iPhone users, as they will not have access to music */\n useEffect(() => {\n if (musicEvents && isiPhone()) {\n setAlert({\n message:\n 'For the best video and music experience please download our iOS app',\n cta: {\n text: 'Download App',\n link: 'https://apps.apple.com/us/app/alo-moves/id601617403'\n }\n })\n }\n }, [musicEvents])\n\n /* We only render music player and its associated logic if there are musicEvents to process */\n return (\n \n {musicEvents && !isiPhone() && (\n \n \n \n )}\n \n )\n}\n\nconst SafeMusicPlayer = () => (\n \n \n \n)\n\nexport default SafeMusicPlayer\n","import MusicPlayer from './MusicPlayer'\nexport { MusicContainer } from './_musicPlayerStyles'\n\nexport default MusicPlayer\n","import React, { Fragment, useEffect, useRef, useState } from 'react'\nimport styled from 'styled-components'\nimport uuidv4 from 'uuid/v4'\n\nimport { useOutsideClick } from 'hooks'\nimport { Flex, HR, P, RadioButton } from 'ui/bend'\n\nimport { CloseButton } from 'ui/bend'\n\nimport { AUTO_BITRATE, useVideoPlayerContext } from './VideoPlayerContext'\n\nconst Container = styled(Flex)`\n position: absolute;\n flex-direction: column;\n min-width: 256px;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 10;\n background-color: ${(props) => props.theme.colors.base};\n transform: ${(props) => (props.show ? 'translateX(0)' : 'translateX(100%)')};\n opacity: ${(props) => (props.show ? '1' : '0')};\n visibility: ${(props) => (props.show ? 'visible' : 'hidden')};\n transition: transform 0.3s ease-in-out, opacity 0.3s ease-in-out,\n visibility 0.3s ease-in-out;\n box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.06),\n 0px 8px 16px rgba(35, 41, 54, 0.08);\n overflow: auto;\n`\n\nconst RadioButtonContainer = styled(Flex)`\n padding-top: 16px;\n padding-bottom: 16px;\n padding-left: 24px;\n flex-direction: column;\n`\n\nconst SettingsPopup = () => {\n const { state, actions } = useVideoPlayerContext()\n const [uuid] = useState(() => uuidv4()) // we need a unique id for each settings popup, as some pages render videoContext multiple times.\n const ref = useRef()\n\n useOutsideClick(ref, actions.toggleSettings, state.showSettings)\n\n /* Prevent user from selecting vjs-control-bar while menu is open */\n useEffect(() => {\n const controlBar = document.getElementsByClassName('vjs-control-bar')[0]\n // useKeyboardTrap_Dangerous() is not working for some reason - focus is being set on document.body and not trapped.\n if (state.showSettings) {\n if (controlBar) {\n controlBar.setAttribute('aria-hidden', true)\n }\n } else {\n if (controlBar) {\n controlBar.setAttribute('aria-hidden', false)\n }\n }\n }, [state.showSettings])\n\n return (\n \n \n

Select Quality

\n \n
\n
\n \n actions.setBitrate(AUTO_BITRATE)}\n >\n

{state.resolutions[0].resolution} (auto)

\n \n
\n {state.resolutions.map((resolution, index) => (\n \n actions.setBitrate(resolution.bitrate)}\n >\n

{resolution.resolution}

\n \n
\n
\n ))}\n
\n
\n )\n}\n\nexport default SettingsPopup\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport uuidv4 from 'uuid/v4'\n\nimport { axios, axiosPlain } from 'api'\nimport { useVideoPlayerContext } from './VideoPlayerContext'\nimport { humanReadableDate } from 'components_v2/Membership/Edit/SubscriptionStates/formatTimes'\n\nconst COMPLETE_AT_PERCENT = 79\n\nconst camelToSnake = (obj) => {\n return Object.fromEntries(\n Object.entries(obj).map(([key, value]) => [\n key.replace(/([A-Z])/g, (match) => `_${match.toLowerCase()}`),\n value\n ])\n )\n}\n\nconst useVideoTracking = ({ setSubscriptionEndTime = () => {} }) => {\n const { state } = useVideoPlayerContext()\n const trialExtend = state.trialExtend\n\n const [timeupdateEvents, setTimeupdateEvents] = useState([])\n const [additionalData, setAdditionalData] = useState({})\n const fetchRef = useRef()\n const [completed, setCompleted] = useState(false)\n const [triggeredTimeArray, setTriggeredTimeArray] = useState([])\n\n useEffect(() => {\n setCompleted(false)\n if (state.meta?.videoOriginType) {\n // We need a new client_uuid every post request.\n const client_uuid = uuidv4()\n const identifier =\n state.meta.videoOriginType === 'Plan'\n ? state.meta.planId\n : state.meta.planEntryId\n const postBody = {\n id: identifier,\n video_origin_type: state.meta.videoOriginType,\n occurred_at: new Date().toUTCString(),\n client_uuid\n }\n\n axiosPlain\n .post('video_events/handle_video_event', postBody)\n .then((res) => {\n if (res.data.ga4_event) {\n window.dataLayer.push(res.data.ga4_event)\n }\n })\n .catch((err) => {\n console.log(err)\n })\n }\n }, [state.playStarted])\n\n const getTimeupdateEvents = useCallback(async () => {\n fetchRef.current = true\n try {\n const res = await axios.get('video_events/time_updates', {\n params: {\n version: '1',\n video_id: state.meta.videoId\n }\n })\n\n if (res && res.data && res.data.timestamps) {\n setTimeupdateEvents(res.data.timestamps)\n }\n } catch (e) {\n // fail silently?\n }\n }, [state.meta])\n\n const getSuggestion = useCallback(() => {\n const type = state.meta.type\n const uuid = state.meta.uuid\n if (type) {\n if (type === 'series') {\n return { type: 'series' }\n } else if (type === 'playlist') {\n return {\n type: 'playlist',\n uuid\n }\n }\n } else {\n return null\n }\n }, [state.meta])\n\n /* Get timeupdate tracking events and set up additionalData based on `video` state.meta */\n useEffect(() => {\n if (state.meta && state.meta.videoId && state.meta.planEntryId) {\n if (!fetchRef.current) getTimeupdateEvents() // only get timeupdateEvents once\n\n setAdditionalData({\n referrer: state.meta.referrer,\n suggestion: getSuggestion()\n })\n }\n }, [state.meta])\n /* Set up manual event listeners once we have timeupdateEvents */\n useEffect(() => {\n if (state.meta) {\n if (\n timeupdateEvents &&\n timeupdateEvents.length > 0 &&\n state.playStarted\n ) {\n if (timeupdateEvents && Array.isArray(timeupdateEvents)) {\n timeupdateEvents.forEach((time) => {\n if (state.time >= time && !triggeredTimeArray.includes(time)) {\n // We need a new client_uuid every post request.\n setTriggeredTimeArray((state) => [...state, time])\n const client_uuid = uuidv4()\n\n const postBody = {\n plan_entry_id: state.meta.planEntryId,\n progress_seconds: time,\n occurred_at: new Date().toUTCString(),\n client_uuid,\n ...additionalData\n }\n\n axiosPlain\n .post('video_events/time_update/web', postBody, {\n params: {\n version: '1'\n }\n })\n .then((res) => {\n if (res.data?.ga4_event) {\n window.dataLayer.push(res.data.ga4_event)\n }\n })\n .catch((err) => {\n console.log(err)\n })\n }\n })\n }\n\n const progress_percentage =\n ((state.time * 1000.0) / state?.meta?.duration) * 100\n\n if (!completed && progress_percentage > COMPLETE_AT_PERCENT) {\n setCompleted(true)\n const client_uuid = uuidv4()\n const postBody = {\n plan_entry_id: state.meta.planEntryId,\n progress_seconds: state.time,\n occurred_at: new Date().toUTCString(),\n client_uuid,\n ...additionalData\n }\n\n axiosPlain\n .post('video_events/time_update/web', postBody, {\n params: {\n version: '1'\n }\n })\n .then((res) => {\n if (res.data?.ga4_event) {\n window.dataLayer.push({\n ...res.data.ga4_event,\n event: 'video_complete'\n })\n }\n })\n .catch((err) => {\n console.log(err)\n })\n }\n }\n }\n }, [\n timeupdateEvents,\n state.playStarted,\n state.time,\n state.meta,\n additionalData,\n triggeredTimeArray\n ])\n\n useEffect(() => {\n if (state.playStarted && trialExtend) {\n axios\n .post('users/extend_trial', camelToSnake(trialExtend))\n .then((resp) => {\n const subscriptionEndTime = resp?.data?.subscriptionEndTime\n if (subscriptionEndTime) {\n const date = new Date(subscriptionEndTime)\n setSubscriptionEndTime(humanReadableDate(date))\n }\n })\n .catch((err) => {\n console.log(err)\n })\n }\n }, [state.playStarted, trialExtend, setSubscriptionEndTime])\n}\n\nexport default useVideoTracking\n","import React, { useState } from 'react'\n\nimport { VideoPlayerContainer } from './_videoPlayerStyles'\nimport MusicPlayer from './MusicPlayer'\nimport SettingsPopout from './SettingsPopout'\nimport useVideoTracking from './useVideoTracking'\nimport { useVideoPlayerContext } from './VideoPlayerContext'\nimport { Notification } from 'components_v2/Home/SignedIn/common/components'\n\nconst VideoPlayerLayout = (props) => {\n const { videoRef, videoPlayer, state } = useVideoPlayerContext()\n const [subscriptionEndTime, setSubscriptionEndTime] = useState('')\n\n // We only track videos that have a planEntryId (so, not intro videos, etc.)\n useVideoTracking({ setSubscriptionEndTime })\n\n return (\n <>\n \n
\n \n\n {state.resolutions.length > 0 && }\n\n {videoPlayer && }\n
\n
\n {subscriptionEndTime && (\n setSubscriptionEndTime('')}\n />\n )}\n \n )\n}\n\nexport default VideoPlayerLayout\n","import React, { useEffect, useState } from 'react'\nimport PropTypes from 'prop-types'\nimport styled from 'styled-components'\n\nimport { axios } from 'api'\nimport { Box, Flex, Image, SVGImage, H3, H6 } from 'ui/bend'\nimport { Locked } from 'images'\n\nimport { unlock_membership_event } from 'gtm/pushEvents'\n\nconst LockedImage = styled(Image)`\n filter: brightness(50%);\n width: 100%;\n`\n\nconst VideoPlayerLocked = ({ videoId }) => {\n const [thumbnail, setThumbnail] = useState()\n\n useEffect(() => {\n const fetchThumbnail = async () => {\n try {\n const res = await axios.get(`videos/${videoId}/thumbnail`)\n if (res && res.data && res.data.thumbnail) {\n setThumbnail(res.data.thumbnail)\n }\n } catch (e) {\n // TODO: feedfm - There is no thumbnail or it didn't response properly. What do here?\n }\n }\n\n fetchThumbnail()\n }, [])\n\n return (\n \n {thumbnail && }\n unlock_membership_event('video')}\n >\n \n \n

\n Unlock this class\n

\n
\n Start Your Free Trial Today\n
\n \n \n
\n )\n}\n\nVideoPlayerLocked.propTypes = {\n videoId: PropTypes.number.isRequired\n}\n\nexport default VideoPlayerLocked\n","import React from 'react'\nimport PropTypes from 'prop-types'\n\nimport { useFetchAPI } from 'hooks'\nimport { ErrorBoundary } from 'helpers'\nimport { Loading } from 'ui/bend'\n\nimport VideoPlayerContext from './VideoPlayerContext'\nimport VideoPlayerLayout from './VideoPlayerLayout'\nimport VideoPlayerLocked from './VideoPlayerLocked'\n\nconst VideoPlayer = ({\n videoId,\n planId,\n planEntryId,\n videoOriginType,\n trialExtend\n}) => {\n const [{ data: video, loading: videoLoading, error: videoError }] =\n useFetchAPI(`videos/${videoId}`)\n return (\n }\n videoId={videoId}\n >\n {video && (\n \n \n \n )}\n \n )\n}\n\nVideoPlayer.propTypes = {\n videoId: PropTypes.number.isRequired,\n planId: PropTypes.number,\n planEntryId: PropTypes.number,\n videoOriginType: PropTypes.string\n}\n\nconst SafeVideoPlayer = (props) => (\n \n \n \n)\n\nexport default SafeVideoPlayer\n","import React from 'react'\nimport PropTypes from 'prop-types'\n\nimport VideoPlayerContext from './VideoPlayerContext'\nimport VideoPlayerLayout from './VideoPlayerLayout'\n\nconst VideoPlayerLite = ({ src, type, poster, ...rest }) => {\n return (\n \n \n \n )\n}\n\nVideoPlayerLite.propTypes = {\n src: PropTypes.string.isRequired,\n type: PropTypes.string,\n poster: PropTypes.string\n}\n\nexport default VideoPlayerLite\n","import VideoPlayer from './VideoPlayer'\nexport { default as VideoPlayerLite } from './VideoPlayerLite'\n\nexport default VideoPlayer\n"],"sourceRoot":""}