-
Notifications
You must be signed in to change notification settings - Fork 0
/
bundle.js.map
7 lines (7 loc) · 29.2 KB
/
bundle.js.map
1
2
3
4
5
6
7
{
"version": 3,
"sources": ["ieeevisdb.ts", "youtubeplayer.ts", "videoplayer.ts", "main.ts"],
"sourcesContent": ["import {AdminsData, Log, Room, RoomDayLogs, Session} from \"./session\";\r\n\r\ndeclare var firebase: Firebase;\r\n\r\nexport class IeeeVisDb {\r\n private sessionRef?: FirebaseRef;\r\n private roomRef?: FirebaseRef;\r\n private adminsRef?: FirebaseRef;\r\n private logsRef?: FirebaseRef;\r\n\r\n constructor() {\r\n this.initFirebase();\r\n }\r\n\r\n initFirebase() {\r\n firebase.initializeApp({\r\n apiKey: \"AIzaSyCfFQ-eN52od55QBFZatFImgZgEDHK_P4E\",\r\n authDomain: \"ieeevis.firebaseapp.com\",\r\n databaseURL: \"https://ieeevis-default-rtdb.firebaseio.com\",\r\n projectId: \"ieeevis\",\r\n storageBucket: \"ieeevis.appspot.com\",\r\n messagingSenderId: \"542997735159\",\r\n appId: \"1:542997735159:web:6d9624111ec276a61fd5f2\",\r\n measurementId: \"G-SNC8VC6RFM\"\r\n });\r\n firebase.analytics();\r\n\r\n this.logsRef = firebase.database().ref('logs/');\r\n }\r\n\r\n loadRoom(roomId: string, onRoomUpdated: (room: Room) => void) {\r\n this.roomRef = firebase.database().ref('rooms/' + roomId) as FirebaseRef;\r\n\r\n this.roomRef.on('value', (snapshot) => {\r\n onRoomUpdated(snapshot.val() as Room);\r\n });\r\n }\r\n\r\n loadSession(sessionId: string, onSessionUpdated: (session: Session) => void) {\r\n this.sessionRef = firebase.database().ref('sessions/' + sessionId);\r\n\r\n this.sessionRef!.on('value', (snapshot) => {\r\n onSessionUpdated(snapshot.val() as Session);\r\n });\r\n }\r\n\r\n loadAllSessions(callback: (sessionsData: {[id: string]: Session}) => void) {\r\n const ref = firebase.database().ref('sessions/');\r\n ref.on('value', snapshot => callback(snapshot.val()));\r\n }\r\n\r\n loadAdmins(callback: (adminsData: AdminsData) => void) {\r\n this.adminsRef = firebase.database().ref('admins');\r\n\r\n this.adminsRef!.on('value', (snapshot) => {\r\n callback(snapshot.val() as AdminsData);\r\n });\r\n }\r\n\r\n set(path: string, value: string|number|{}) {\r\n this.sessionRef?.child(path).set(value);\r\n }\r\n\r\n setRoom(path: string, value: string|number) {\r\n this.roomRef?.child(path).set(value);\r\n }\r\n\r\n log(log: Log) {\r\n const date = new Date(log.time);\r\n const month = date.getUTCMonth() + 1;\r\n const day = date.getUTCDate();\r\n const year = date.getUTCFullYear();\r\n const dayString = `${year}-${month}-${day}`;\r\n\r\n const hour = date.getUTCHours();\r\n const minute = date.getUTCMinutes();\r\n const second = date.getUTCSeconds();\r\n const milli = date.getUTCMilliseconds();\r\n const timeString = `${hour}:${minute}:${second}:${milli}`;\r\n\r\n this.logsRef?.child(dayString).child(log.room).child(timeString).set(log);\r\n }\r\n\r\n loadLogs(room: string, day: string, callback: (logs: RoomDayLogs) => void) {\r\n const logsRef = firebase.database().ref(`logs/${day}/${room}`);\r\n\r\n logsRef!.on('value', (snapshot) => {\r\n callback(snapshot.val() as RoomDayLogs);\r\n });\r\n }\r\n}\r\n\r\ninterface FirebaseRef {\r\n child: (childName: string) => FirebaseRef;\r\n set: (value: string|number|{}) => void;\r\n on: (event: \"value\", cb: (data: any) => void) => void;\r\n}\r\n\r\ninterface Firebase {\r\n initializeApp: (data: {\r\n apiKey: string,\r\n authDomain: string,\r\n databaseURL: string,\r\n projectId: string,\r\n storageBucket: string,\r\n messagingSenderId: string,\r\n appId: string,\r\n measurementId: string\r\n }) => void;\r\n analytics: () => void;\r\n database: () => {\r\n ref: (name: string) => FirebaseRef\r\n }\r\n}\r\n", "export interface YoutubePlayer {\r\n playVideo: () => void;\r\n //playVideoAt: (time: number) => void;\r\n pauseVideo: () => void;\r\n stopVideo: () => void;\r\n loadVideoById: (videoId: string|{ startSeconds: number; endSeconds: number; videoId: string }, startTime?: number, size?: string) => void;\r\n mute: () => void;\r\n unMute: () => void;\r\n seekTo: (timeS: number, allowSeekAhead: boolean) => void;\r\n getDuration: () => number;\r\n getCurrentTime: () => number;\r\n setSize(width: number, height: number): void;\r\n}\r\n\r\nexport enum PlayerState {\r\n UNSTARTED = -1,\r\n ENDED = 0,\r\n PLAYING = 1,\r\n PAUSED = 2,\r\n BUFFERING = 3,\r\n CUED = 5\r\n}", "import {PlayerState, YoutubePlayer} from \"./youtubeplayer\";\r\nimport {SessionStage, SessionStatus} from \"./session\";\r\n\r\ndeclare var YT: YouTube;\r\n\r\nexport class IeeeVisVideoPlayer {\r\n player?: YoutubePlayer;\r\n audioContext = new AudioContext();\r\n\r\n private width = 400;\r\n private height = 300;\r\n\r\n youtubeApiReady = false;\r\n youtubePlayerLoaded = false;\r\n youtubePlayerReady = false;\r\n\r\n private lastVideoId? = '';\r\n\r\n constructor(private elementId: string,\r\n private getCurrentStage: OmitThisParameter<() => (SessionStage | undefined)>,\r\n private getCurrentVideoId: OmitThisParameter<() => string | undefined>,\r\n private getCurrentSessionStatus: () => (SessionStatus | undefined)) {\r\n this.init();\r\n }\r\n\r\n onYouTubeIframeAPIReady() {\r\n this.youtubeApiReady = true;\r\n }\r\n\r\n updateVideo() {\r\n if(!this.youtubeApiReady) {\r\n return;\r\n }\r\n const currentVideoId = this.getCurrentVideoId();\r\n\r\n if(!this.youtubePlayerLoaded) {\r\n this.loadYoutubePlayer();\r\n } else {\r\n if(!currentVideoId && this.player) {\r\n this.player.stopVideo();\r\n } else {\r\n if(currentVideoId && this.lastVideoId !== currentVideoId) {\r\n this.changeYoutubeVideo();\r\n }\r\n }\r\n }\r\n this.lastVideoId = currentVideoId;\r\n }\r\n\r\n setSize(width: number, height: number) {\r\n this.width = width;\r\n this.height = height;\r\n\r\n if(!this.player) {\r\n return;\r\n }\r\n this.player.setSize(width, height);\r\n }\r\n\r\n private init() {\r\n const tag = document.createElement('script');\r\n tag.src = \"https://www.youtube.com/iframe_api\";\r\n const firstScriptTag = document.getElementsByTagName('script')[0];\r\n firstScriptTag.parentNode!.insertBefore(tag, firstScriptTag);\r\n }\r\n\r\n private onPlayerReady() {\r\n console.log('player ready', this.player);\r\n this.youtubePlayerReady = true;\r\n\r\n if(this.audioContext.state === \"suspended\") {\r\n this.player!.mute();\r\n }\r\n this.player!.playVideo();\r\n\r\n this.updateVideo();\r\n }\r\n\r\n private lastCatchupChecksLedToCatchup: boolean[] = [];\r\n\r\n private onPlayerStateChange(state: {target: YoutubePlayer, data: PlayerState}) {\r\n if(!this.getCurrentVideoId()) {\r\n return;\r\n }\r\n if(state.data === PlayerState.UNSTARTED) {\r\n // This is to force the player to go to 0 because it does not recognize 0 as a start time in loadVideoById.\r\n this.player!.seekTo(this.getCurrentStartTimeS() || 0, true);\r\n }\r\n\r\n if(state.data === PlayerState.PLAYING || state.data === PlayerState.BUFFERING) {\r\n const startTime = this.getCurrentStartTimeS() || 0;\r\n const currentTime = this.player!.getCurrentTime();\r\n const shouldCatchUp = Math.abs(startTime - currentTime) > 5;\r\n\r\n this.lastCatchupChecksLedToCatchup.push(shouldCatchUp);\r\n const consideredChecks = 4;\r\n this.lastCatchupChecksLedToCatchup = this.lastCatchupChecksLedToCatchup.slice(-1 * consideredChecks); // Last 4 checks\r\n const numChecks = this.lastCatchupChecksLedToCatchup.length;\r\n const enoughChecks = numChecks >= consideredChecks;\r\n const notAllLastChecksForcedCatchup = this.lastCatchupChecksLedToCatchup.indexOf(false) !== -1;\r\n\r\n if(shouldCatchUp && (notAllLastChecksForcedCatchup || !enoughChecks)) {\r\n this.player!.seekTo(startTime, true);\r\n console.log('lagging behind. seek.', this.getCurrentStartTimeS(), this.player!.getCurrentTime(), this.player!.getDuration(), this.player);\r\n }\r\n if(shouldCatchUp && !notAllLastChecksForcedCatchup) {\r\n console.log('would normally catch up now, but skipping to prevent multi-seek.', this.lastCatchupChecksLedToCatchup, numChecks, enoughChecks);\r\n }\r\n }\r\n }\r\n\r\n private loadYoutubePlayer() {\r\n this.youtubePlayerLoaded = true;\r\n\r\n this.player = new YT.Player(this.elementId, {\r\n width: this.width,\r\n height: this.height,\r\n videoId: this.getCurrentVideoId(),\r\n\r\n playerVars: {\r\n 'playsinline': 1,\r\n 'autoplay': 1,\r\n 'controls': 1,\r\n 'rel': 0,\r\n 'modestbranding': 1,\r\n 'mute': 0,\r\n start: this.getCurrentStartTimeS(),\r\n },\r\n events: {\r\n 'onReady': this.onPlayerReady.bind(this),\r\n 'onStateChange': this.onPlayerStateChange.bind(this),\r\n }\r\n });\r\n }\r\n\r\n private changeYoutubeVideo() {\r\n // The seeking in the following line does not work for 0 (see workaround above).\r\n const currentVideoId = this.getCurrentVideoId();\r\n if(!currentVideoId) {\r\n return;\r\n }\r\n this.player!.loadVideoById(currentVideoId, this.getCurrentStartTimeS());\r\n this.player!.playVideo();\r\n }\r\n\r\n private getCurrentStartTimeS() {\r\n if(!this.getCurrentStage()!.live || !this.youtubePlayerReady) {\r\n const timeMs = new Date().getTime();\r\n const videoStartTimestampMs = this.getCurrentSessionStatus()?.videoStartTimestamp || 0;\r\n\r\n return Math.round((timeMs - videoStartTimestampMs) / 1000);\r\n } else if(this.getCurrentStage()!.live) {\r\n const videoStartTimestampMs = this.getCurrentSessionStatus()?.liveStreamStartTimestamp;\r\n if(!videoStartTimestampMs) {\r\n return 0;\r\n }\r\n const timeDiffMs = new Date().getTime() - videoStartTimestampMs;\r\n return Math.round(timeDiffMs / 1000);\r\n }\r\n }\r\n}\r\n\r\ninterface YouTube {\r\n Player: YouTubePlayerConstructor;\r\n}\r\n\r\ninterface YouTubePlayerConstructor {\r\n new(elementId: string, data: any): YoutubePlayer\r\n}\r\n", "import {Room, Session, SessionState, SessionStage} from \"./session\";\r\nimport {IeeeVisDb} from \"./ieeevisdb\";\r\nimport {IeeeVisVideoPlayer} from \"./videoplayer\";\r\n\r\ntype PANEL_FOCUS = \"none\" | \"qa\" | \"chat\";\r\n\r\nclass IeeeVisStream {\r\n static PLAYER_ELEMENT_ID = 'ytplayer';\r\n static CONTENT_WRAPPER_ID = 'content';\r\n static GATHERTOWN_WRAPPER_ID = 'gathertown';\r\n\r\n room?: Room;\r\n currentSession?: Session;\r\n player: IeeeVisVideoPlayer;\r\n db: IeeeVisDb;\r\n\r\n width = window.innerWidth;\r\n height = window.innerHeight; // Placeholder values. Will be replaced in the resize function.\r\n\r\n PANEL_WIDTH_PERCENT = 40;\r\n CHAT_PADDING_LEFT_PX = 20;\r\n static HEADERS_HEIGHT = 41;\r\n HORIZONTAL_PADDING = 30;\r\n CAPTIONS_HEIGHT_PX = 150;\r\n\r\n currentPanelFocus: PANEL_FOCUS = \"none\";\r\n\r\n constructor(private ROOM_ID: string) {\r\n this.db = new IeeeVisDb();\r\n this.player = new IeeeVisVideoPlayer(IeeeVisStream.PLAYER_ELEMENT_ID,\r\n this.getCurrentStage.bind(this),\r\n this.getCurrentVideoId.bind(this),\r\n () => this.currentSession?.currentStatus);\r\n this.db.loadRoom(ROOM_ID, room => this.onRoomUpdated(room));\r\n\r\n this.loadPreviewImage();\r\n\r\n this.resize();\r\n window.addEventListener('resize', this.resize.bind(this));\r\n\r\n this.checkPanelFocus();\r\n }\r\n\r\n onYouTubeIframeAPIReady() {\r\n this.player.onYouTubeIframeAPIReady();\r\n }\r\n\r\n loadChat() {\r\n document.getElementById('discord-wrap')!.innerHTML = `\r\n <iframe\r\n id=\"discord-iframe\"\r\n src=\"https://ieeevis-e.widgetbot.co/channels/884159773287805038/${this.room!.discord}\"\r\n ></iframe>`;\r\n }\r\n\r\n loadSlido() {\r\n const frame = document.getElementById('slido-frame')!;\r\n const url = `https://app.sli.do/event/${this.room!.slido}?section=${this.room!.slido_room}`;\r\n frame.setAttribute('src', url);\r\n }\r\n\r\n checkPanelFocus() {\r\n window.setInterval(() => {\r\n const lastFocus = this.currentPanelFocus;\r\n\r\n if(document.activeElement == document.getElementById('discord-iframe')) {\r\n this.currentPanelFocus = \"chat\";\r\n } else if (document.activeElement == document.getElementById('slido-frame')) {\r\n this.currentPanelFocus = \"qa\";\r\n } else {\r\n this.currentPanelFocus = \"none\";\r\n }\r\n\r\n if(lastFocus != this.currentPanelFocus) {\r\n this.resize();\r\n }\r\n }, 200);\r\n }\r\n\r\n updateGathertown() {\r\n const gatherWrap = document.getElementById(IeeeVisStream.GATHERTOWN_WRAPPER_ID)!;\r\n\r\n gatherWrap.innerHTML = this.getCurrentStage()?.state !== \"SOCIALIZING\" ? \"\" :\r\n `<iframe title=\"gather town\"\r\n allow=\"camera;microphone\"\r\n id=\"gathertown-iframe\"\r\n src=\"https://gather.town/app/uT2p5cFP0oXFZg4E/ieee-vis-2021?spawnToken=nLvBRdVP_nCJOs3p\"></iframe>`;\r\n }\r\n\r\n loadPreviewImage() {\r\n console.log('loading preview', this.getCurrentStage()?.imageUrl);\r\n const url = this.getCurrentStage()?.imageUrl;\r\n const html = !url ? '' : `<img src=\"${url}\" alt=\"Preview Image\" id=\"preview-img\" />`;\r\n const previewWrap = document.getElementById('image-outer')!;\r\n previewWrap.innerHTML = html;\r\n }\r\n\r\n onRoomUpdated(room: Room) {\r\n this.room = room;\r\n\r\n this.loadChat();\r\n this.loadSlido();\r\n\r\n this.db.loadSession(room.currentSession, session => this.onSessionUpdated(room.currentSession, session));\r\n }\r\n\r\n onSessionUpdated(id: string, session: Session) {\r\n if(this.room?.currentSession != id) {\r\n // Do not listen to last session's update events.\r\n return;\r\n }\r\n const lastSession: Session | undefined = this.currentSession ? {...this.currentSession} : undefined;\r\n const lastYtId = this.getCurrentVideoId();\r\n this.currentSession = session;\r\n\r\n document.getElementById('session-name')!.innerText = this.getCurrentStage()?.title || '';\r\n\r\n this.player.updateVideo();\r\n if(this.getCurrentStage()?.imageUrl != this.getCurrentStageOfSession(lastSession)?.imageUrl) {\r\n this.loadPreviewImage();\r\n }\r\n this.updateGathertown();\r\n this.updateCaptions();\r\n\r\n this.resize();\r\n }\r\n\r\n updateCaptions() {\r\n const captionsWrap = document.getElementById('captions-outer')!;\r\n if(this.getCurrentStage()?.has_live_captions) {\r\n captionsWrap.style.display = '';\r\n const url = this.getCurrentStage()!.live_captions_url;\r\n captionsWrap.innerHTML =\r\n `<iframe id=\"captions-iframe\" src=\"${url}\" height=\"${this.CAPTIONS_HEIGHT_PX}\" width=\"100%\"></iframe>`;\r\n } else {\r\n captionsWrap.style.display = 'none';\r\n }\r\n }\r\n\r\n getCurrentStage(): SessionStage | undefined {\r\n return this.getCurrentStageOfSession(this.currentSession);\r\n }\r\n\r\n getCurrentStageOfSession(session: Session | undefined) {\r\n if(!session || !session?.currentStatus) {\r\n return;\r\n }\r\n return session?.stages[session?.currentStatus?.videoIndex];\r\n }\r\n\r\n getCurrentVideoId() {\r\n return this.getCurrentStage()?.youtubeId;\r\n }\r\n\r\n resize() {\r\n this.width = window.innerWidth;\r\n this.height = window.innerHeight - 15;\r\n\r\n const state = this.getCurrentStage()?.state;\r\n\r\n if(!state) {\r\n return;\r\n }\r\n\r\n if(state === \"SOCIALIZING\") {\r\n // Show gathertown, hide YouTube\r\n document.getElementById('youtube-outer')!.style.display = 'none';\r\n document.getElementById('image-outer')!.style.display = 'none';\r\n document.getElementById('gathertown-outer')!.style.display = '';\r\n\r\n } else if(state === \"PREVIEW\") {\r\n document.getElementById('youtube-outer')!.style.display = 'none';\r\n document.getElementById('image-outer')!.style.display = '';\r\n document.getElementById('gathertown-outer')!.style.display = 'none';\r\n } else {\r\n // Hide gathertown, show YouTube\r\n document.getElementById('youtube-outer')!.style.display = '';\r\n document.getElementById('image-outer')!.style.display = 'none';\r\n document.getElementById('gathertown-outer')!.style.display = 'none';\r\n }\r\n\r\n const contentWidth = this.width * (100 - this.PANEL_WIDTH_PERCENT) / 100 - this.HORIZONTAL_PADDING;\r\n const mainContentHeight = this.height - IeeeVisStream.HEADERS_HEIGHT;\r\n\r\n let playerHeight = mainContentHeight;\r\n if(this.getCurrentStage()?.has_live_captions && this.getCurrentStage()?.live_captions_url) {\r\n playerHeight -= this.CAPTIONS_HEIGHT_PX;\r\n }\r\n\r\n const contentWrap = document.getElementById(IeeeVisStream.CONTENT_WRAPPER_ID)!;\r\n contentWrap.style.width = `${contentWidth}px`;\r\n this.player.setSize(contentWidth, playerHeight);\r\n\r\n const previewImg = document.getElementById('preview-img');\r\n if(previewImg) {\r\n document.getElementById('image-outer')!.style.height = `${mainContentHeight}px`;\r\n previewImg.style.maxWidth = `${contentWidth}px`;\r\n previewImg.style.maxHeight = `${mainContentHeight}px`;\r\n }\r\n\r\n const gatherFrame = document.getElementById('gathertown-iframe');\r\n if(gatherFrame) {\r\n gatherFrame.setAttribute('width', `${contentWidth}`);\r\n gatherFrame.setAttribute('height', `${mainContentHeight}`);\r\n }\r\n\r\n const qaShown = [\"WATCHING\", \"QA\"].indexOf(state) !== -1;\r\n const numHeaders = qaShown ? 2 : 1;\r\n const panelWidth = this.width * this.PANEL_WIDTH_PERCENT / 100 - this.CHAT_PADDING_LEFT_PX;\r\n const panelContentHeight = this.height - IeeeVisStream.HEADERS_HEIGHT * numHeaders;\r\n\r\n const qaWrap = document.getElementById('qa')!;\r\n qaWrap.style.display = qaShown ? '' : 'none';\r\n\r\n let qaHeightPercent = 0;\r\n if(qaShown) {\r\n qaHeightPercent = 40;\r\n\r\n if(state === \"QA\") {\r\n qaHeightPercent = 60;\r\n }\r\n if(this.currentPanelFocus === \"qa\") {\r\n qaHeightPercent = 70;\r\n } else if(this.currentPanelFocus === \"chat\") {\r\n qaHeightPercent = 30;\r\n }\r\n }\r\n\r\n document.getElementById('sidepanel')!.style.width = `${panelWidth}px`;\r\n\r\n const slidoFrame = document.getElementById('slido-frame')!;\r\n const slidoTopOffset = 0; // +0 offset for the top bar. Must match CSS.\r\n const slidoHeight = qaHeightPercent / 100 * panelContentHeight + slidoTopOffset;\r\n\r\n if(slidoFrame) {\r\n slidoFrame.setAttribute('width', `${panelWidth}`);\r\n slidoFrame.style.height = `${slidoHeight}px`;\r\n document.getElementById('slido-wrap')!.style.height = `${slidoHeight - slidoTopOffset}px`;\r\n }\r\n\r\n const discordFrame = document.getElementById('discord-iframe');\r\n if(discordFrame) {\r\n discordFrame.setAttribute('width', `${panelWidth}`);\r\n discordFrame.style.height = `${(100 - qaHeightPercent) / 100 * panelContentHeight}px`;\r\n document.getElementById('discord-wrap')!.style.height = `${(100 - qaHeightPercent) / 100 * panelContentHeight}px`;\r\n }\r\n }\r\n}\r\n\r\nconst roomId = location.search.indexOf('room=') === -1 ? '' :\r\n location.search.substr(location.search.indexOf('room=') + 'room='.length);\r\nexport declare var onYouTubeIframeAPIReady: () => void;\r\n\r\nif(roomId) {\r\n const stream = new IeeeVisStream(roomId);\r\n document.getElementById('wrapper')!.style.display = 'flex';\r\n onYouTubeIframeAPIReady = () => {\r\n stream.onYouTubeIframeAPIReady();\r\n }\r\n} else {\r\n document.getElementById('param-error')!.style.display = 'block';\r\n}\r\n"],
"mappings": "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",
"names": []
}