g_filter = { conf: null, tracks: [], keywords: [] }; g_ndcsidebarscroll = null; g_sessionsPerPage = 12; g_isSessionDetailHtml = false; // 현재 읽고 있는 파일이 세션 상세 html인지 여부 g_currentHash = ""; g_conf_separatedViewMode = true; // true일 경우, 세션 상세 html 페이지가 별도로 분리된다. g_escaper = $('
') // processExternalVideo / onYouTubePlayerAPIReady g_youtube_videoId = ""; function getProps(obj, subProps) { if (typeof obj === "undefined" || $.isArray(subProps) == false) return obj; var curObj = obj; for (var i = 0; i < subProps.length; i++) { curObj = curObj[subProps[i]]; if (typeof curObj === "undefined") break; } return curObj; } var NDCREPLAY = NDCREPLAY || {}; NDCREPLAY.sessionMap = { // key : conference name, value : conference info confMap: {}, parse: function () { var _self = this; $.each(g_sessionSrcList, function () { $.each(this.sessions, function () { _self.confMap[this.conf] = _self.confMap[this.conf] || new ConferenceInfo(this.conf); _self.confMap[this.conf].addSession(this); }); }); for (var confName in _self.confMap) { _self.confMap[confName].tracks.sort(function (a, b) { if (b == '키노트') return 1; return a.localeCompare(b); }) } }, search: function (filter) { var resultList = []; var confFilter = getProps(filter, ["conf"]); for (var confKey in this.confMap) if (typeof confFilter === "undefined" || confFilter == confKey) resultList = resultList.concat(this.confMap[confKey].search(filter)); return resultList; }, getSession: function (sessionId) { for (var confKey in this.confMap) { var resultSession = this.confMap[confKey].getSession(sessionId); if (resultSession != null) return resultSession; } return null; } }; function ConferenceInfo(confName) { this.confName = confName; this.tracks = []; this.sessions = []; } ConferenceInfo.prototype.addSession = function (sessionObject) { var _self = this; $.each(sessionObject.tracks, function () { var track = this + ""; if (_self.tracks.indexOf(track) >= 0) return true; _self.tracks.push(track); }); this.sessions.push(sessionObject); } ConferenceInfo.prototype.search = function (filter) { var resultList = []; var tracksFilter = getProps(filter, ["tracks"]); // or search. ex) tracks:["프로그래밍","운영"] var keywordsFilter = getProps(filter, ["keywords"]); // or search. ex) keywords:["던전", "유저"] $.each(this.sessions, function () { if (typeof tracksFilter !== "undefined" && tracksFilter.length > 0 && typeof tracksFilter[0] !== "undefined") { var tracksFound = false; for (var i = 0; i < this.tracks.length; i++) if (tracksFilter.indexOf(this.tracks[i]) >= 0) tracksFound = true; if (tracksFound == false) return true; // continue } if (typeof keywordsFilter !== "undefined" && keywordsFilter.length > 0) { var keywordsFound = false; for (var i = 0; i < keywordsFilter.length; i++) { var currentKeyword = keywordsFilter[i].toLowerCase(); if (typeof this.title !== 'undefined' && this.title.toLowerCase().indexOf(currentKeyword) >= 0 || typeof this.subtitle !== 'undefined' && this.subtitle.toLowerCase().indexOf(currentKeyword) >= 0 || typeof this.speaker !== 'undefined' && this.speaker.toLowerCase().indexOf(currentKeyword) >= 0) keywordsFound = true; if (keywordsFound) break; } if (keywordsFound == false) return true; // continue } resultList.push(this); }); return resultList; } ConferenceInfo.prototype.getSession = function (sessionId) { for (var i = 0; i < this.sessions.length; i++) if (this.sessions[i].id == sessionId) return this.sessions[i]; return null; } function redirectToListPage(queryParam) { var url = window.location.href.replace(window.location.hash, ""); window.location.href = url + "/../../../index.html" + queryParam; } function showSessionList(filter, page) { if (g_isSessionDetailHtml) { redirectToListPage("#" + stringifyFilterPageQuery(filter, page)); return; } page = page || 1; page = parseInt(page, 10); g_filter = filter; $("#tracksListDivider").removeClass("hidden"); $("#tracksList").removeClass("hidden"); var searchTxt = (g_filter.keywords || []).join(", "); $("#txtSearch").val(searchTxt); if (typeof g_filter.conf === 'undefined') { $("#confName").text("전체 보기"); $("#tracksListDivider").addClass("hidden"); $("#tracksList").addClass("hidden"); $("#confNameAndTrack").text("전체 보기"); } else { $("#confName").text(g_filter.conf); $("#confNameAndTrack").text(g_filter.conf); } if (typeof g_filter.tracks === 'undefined' || g_filter.tracks.length == 0) { $("#tracksListDivider").addClass("hidden"); $("#tracksList").addClass("hidden"); } else { $("#tracksList").text(g_filter.tracks.join(" | ")); $("#confNameAndTrack").text($("#confNameAndTrack").text() + " / " + g_filter.tracks.join(" | ")); } var resultList = NDCREPLAY.sessionMap.search(filter); $.each(resultList, function () { this.compareKey = this.title.replace(/[^A-Za-z가-힣]+/g, ''); }); resultList.sort(function (a, b) { return a.compareKey.localeCompare(b.compareKey); }); var tbodyStart = $("#tblSessionList > tbody:last").children().remove(); $.each(resultList, function (idx, session) { if (Math.floor(idx / g_sessionsPerPage) != (page - 1)) return true; // continue var newTr = $("").appendTo($("#tblSessionList")); newTr.attr('session-id', session.id).click(onClickSession); var titleHtml = '' + g_escaper.text(session.title).html() + ''; if (typeof session.subtitle !== 'undefined') titleHtml = titleHtml + '
' + g_escaper.text(session.subtitle).html(); var titleTd = $("").appendTo(newTr).html(titleHtml); var innerDiv = $("
").css("font-size", "12px").addClass("visible-xs visible-sm visible-md visible-lg").appendTo(titleTd); var innerSpan = $("").appendTo(innerDiv).addClass("visible-xs visible-sm visible-md visible-lg").html(" " + session.tracks[0] + "" + session.speaker + " (" + session.from + ")"); /* $("").appendTo(newTr).html(session.tracks[0]).addClass("visible-sm visible-md visible-lg"); $("").appendTo(newTr) .html("" + session.speaker + "
" + session.from ) .addClass("ex-overflowtd") .addClass("visible-lg"); $("").appendTo(newTr).html(session.conf).addClass("visible-md").addClass("visible-lg").css("text-align", "center"); */ }); // session list pagination refreshPagination(resultList.length, page); if (resultList.length == 0) { $("#sessionListPagination").addClass("hidden"); $("#tblSessionList").addClass("hidden"); $("#divSessionListNotFound").removeClass("hidden"); } else { $("#sessionListPagination").removeClass("hidden"); $("#tblSessionList").removeClass("hidden"); $("#divSessionListNotFound").addClass("hidden"); } if (g_isSessionDetailHtml == false) { g_currentHash = stringifyFilterPageQuery(filter, page); window.location.hash = g_currentHash; } $(document).scrollTop(0); switchSessionListAndDetail(true); } function refreshPagination(totalLength, currentPage) { // < minPage . . . . maxPage > var totalPages = Math.floor(totalLength / g_sessionsPerPage) + 1; var minPage = Math.max(1, currentPage - 2); var maxPage = Math.min(minPage + 4, totalPages); var paginationDiv = $('#sessionListPagination'); paginationDiv.addClass("pagination"); paginationDiv.children().remove(); var prevLi = $('
  • ') .addClass('prev') .html('<') .click(function () { showSessionList(g_filter, currentPage - 1); }) .appendTo(paginationDiv); if (currentPage == 1) prevLi.addClass('hidden'); for (var pageNum = minPage; pageNum <= maxPage; pageNum++) { var pageLi = $('
  • ') .addClass('page') .data('page', pageNum) .html('' + pageNum + '') .click(function () { showSessionList(g_filter, $(this).data('page')); }) .appendTo(paginationDiv); if (pageNum == currentPage) pageLi.addClass('active'); } var nextLi = $('
  • ') .addClass('next') .html('>') .click(function () { showSessionList(g_filter, currentPage + 1); }) .appendTo(paginationDiv); if (currentPage == totalPages) nextLi.addClass('hidden'); } function stringifyFilterPageQuery(filter, page) { if (JSON.stringify(filter) == "{}" && page == 1) return ""; var queryObject = {}; if (typeof filter.conf !== 'undefined' && filter.conf != "") queryObject["c"] = filter.conf; if (typeof filter.tracks !== 'undefined' && filter.tracks.length != 0) queryObject["t"] = filter.tracks; if (typeof filter.keywords !== 'undefined') queryObject["k"] = filter.keywords; if (typeof page !== 'undefined' && page != "" && page != 1) queryObject["p"] = page; return $.param(queryObject); } function parseFilterPageQuery(query) { if (query == "") return { f: {}, p: 1 }; var queryObject = $.deparam(query); var filter = {}; var page = 1; if (typeof queryObject["c"] !== 'undefined' && queryObject["c"] != "") filter.conf = queryObject["c"]; if (typeof queryObject["t"] !== 'undefined' && queryObject["t"] != "") filter.tracks = queryObject["t"]; if (typeof queryObject["k"] !== 'undefined' && queryObject["k"] != "") filter.keywords = queryObject["k"]; if (typeof queryObject["p"] !== 'undefined' && queryObject["p"] != "") page = queryObject["p"]; return { f: filter, p: page }; } function switchSessionListAndDetail(showSessionList) { if (showSessionList) { $("#divSessionListV2Container").removeClass("hidden"); $("#searchBox").removeClass("hidden"); $("#upperInfoBar").addClass("hidden"); $("#divSessionDetail").addClass("hidden"); $("#backButtonBox").addClass("hidden"); } else { $("#divSessionListV2Container").addClass("hidden"); $("#searchBox").addClass("hidden"); $("#upperInfoBar").removeClass("hidden"); $("#divSessionDetail").removeClass("hidden"); $("#backButtonBox").removeClass("hidden"); } } function onClickSession() { var sessionId = $(this).attr('session-id'); var sessionDetail = NDCREPLAY.sessionMap.getSession(sessionId); if (g_conf_separatedViewMode) { var hashString = window.location.hash; if (hashString == "#") hashString = ""; window.location.href = getSessionLinks(sessionDetail)[2] + hashString; return; } fillAndSwitchToSessionView(sessionId); } function fillAndSwitchToSessionView(sessionId) { var sessionDetail = NDCREPLAY.sessionMap.getSession(sessionId); $("#sessionDetailTitle").attr('data-conf', sessionDetail.conf); $("#sessionDetailTitle").attr('data-session', sessionDetail.id); $("#sessionDetailTitle").text(sessionDetail.title); if (typeof sessionDetail.subtitle !== 'undefined') $("#sessionDetailSubtitle").text(sessionDetail.subtitle); else $("#sessionDetailSubtitle").text(''); $("#sessionDetailSpeaker").text(sessionDetail.speaker); $("#sessionDetailFrom").text(sessionDetail.from); $("#sessionDetailSpeakerSmall").text(sessionDetail.speaker); $("#sessionDetailFromSmall").text(sessionDetail.from); $("#sessionDetailDesc").text(sessionDetail.desc || ("from " + sessionDetail.conf)); $("#sessionDetailSpeakerIntro").text(sessionDetail.speaker_intro || ("from " + sessionDetail.from)); $('#sessionDetailScript').text("자막이 없습니다."); displaySessionView(); } function getSessionLinks(session) { return [ "http://ndc.vod.nexoncdn.co.kr/" + session.conf + "/slides/" + session.id + "/index.html", "http://ndc.vod.nexoncdn.co.kr/" + session.conf + "/videos/" + session.id + ".mp4", "./" + session.conf + "/sessions/" + session.id + ".html" ]; } function displaySessionView() { switchSessionListAndDetail(false); if ($("#sessionDetailSubtitle").text() != '') $("#sessionDetailSubtitle").removeClass('hidden'); var session = NDCREPLAY.sessionMap.getSession($("#sessionDetailTitle").attr('data-session')); $("#confName").text(session.conf); var uniqueTracks = []; $.each(session.tracks, function () { if (uniqueTracks.indexOf("" + this) >= 0) return true; uniqueTracks.push("" + this); }); $("#tracksList").text(uniqueTracks.join(" | ")); var slideLink = getSessionLinks(session)[0]; var slideLinkMobileSafari = ''; // TODO $("#sessionDetailSlideContainer").toggleClass('hidden', !session.slidePublic); $("#sessionDetailSlideLinkContainer").toggleClass('hidden', !session.slidePublic); $("#sessionDetailVideoContainer").toggleClass('hidden', !session.videoPublic); $("#sessionDetailScriptContainer").toggleClass('hidden', !session.scriptPublic); // or : $('#sessionDetailScript').text("자막이 없습니다."); $("#mobileSafariLoadingContainer").addClass('hidden'); $("#sessionDetailSlideContainerMobileSafariIFrameAlert").addClass('hidden'); if (navigator.userAgent.match(/(iPod|iPhone|iPad)/) && navigator.userAgent.match(/AppleWebKit/)) { if (slideLinkMobileSafari == '') { loadSlide_iphone(); // iphone workaround $(window).on("orientationchange", function (event) { if (window.orientation % 180 == 0) loadSlide_iphone(); }); } else { slideLink = slideLinkMobileSafari; } } $("#sessionDetailSlide").attr('src', slideLink); $("#sessionDetailSlideExternalLink").attr('href', slideLink); if (session.videoPublic) { if (processExternalVideo($("#sessionDetailVideo").attr('data-externalVideoUrl')) == false) { $("#sessionVideoSource").attr('src', getSessionLinks(session)[1]); videojs(document.getElementById('sessionVideo'), { "width": "100%", "height": "100%" }, function () { }) .on('fullscreenchange', function (ev) { var session = NDCREPLAY.sessionMap.getSession($("#sessionDetailTitle").attr('data-session')); if (session.slidePublic) $("#sessionDetailSlideContainer").toggleClass('hidden', videojs(ev.target).isFullscreen()); }); } } } function processExternalVideo(externalVideoUrl) { if (typeof externalVideoUrl === 'undefined') return false; if (externalVideoUrl == "") return false; // https://stackoverflow.com/a/8260383 var regExp_yt = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/; var match_yt = externalVideoUrl.match(regExp_yt); g_youtube_videoId = ""; if (match_yt && match_yt[7].length == 11) g_youtube_videoId = match_yt[7]; if (g_youtube_videoId == "") return false; // https://developers.google.com/youtube/player_parameters var tag = document.createElement('script'); tag.src = "https://www.youtube.com/player_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); return true; } function onYouTubePlayerAPIReady() { if (g_youtube_videoId == "") return; var g_yt_player = new YT.Player('sessionDetailVideo', { height: '100%', width: '100%', videoId: g_youtube_videoId, rel: 0 }); } var loadSlide_loadingNow = false; var loadSlide_outerHTMLCache = ""; var loadSlide_interval = null; function loadSlide_iphone() { if (loadSlide_loadingNow) return; loadSlide_loadingNow = true; var session = NDCREPLAY.sessionMap.getSession($("#sessionDetailTitle").attr('data-session')); var slideLink = getSessionLinks(session)[0]; // 매 로드 때마다 내용을 리셋한다. if (loadSlide_outerHTMLCache == "") loadSlide_outerHTMLCache = $('#sessionDetailSlideContainer')[0].outerHTML; $('#sessionDetailSlideContainer')[0].outerHTML = loadSlide_outerHTMLCache; $("#sessionDetailSlideContainer").addClass('hidden'); $("#sessionDetailSlide").attr('src', slideLink); $("#mobileSafariLoadingContainer").removeClass('hidden'); //$("#sessionDetailSlideContainerMobileSafariIFrameAlert").removeClass('hidden'); loadSlide_interval = setInterval(function () { var iFrameAlert = $("#sessionDetailSlideContainerMobileSafariIFrameAlert"); var repeatCount = (iFrameAlert.attr('data-cnt') || 0); iFrameAlert.attr('data-cnt', (repeatCount + 1) % 3); var iFrameAlertMsg = "슬라이드 불러오는 중."; for (var i = 0; i < repeatCount; i++) iFrameAlertMsg += ".."; iFrameAlert.text(iFrameAlertMsg); }, 300); setTimeout(function () { clearInterval(loadSlide_interval); loadSlide_showSlide() }, 5000); return; } function loadSlide_showSlide() { $("#sessionDetailSlideContainer").removeClass('hidden'); $("#mobileSafariLoadingContainer").addClass('hidden'); $("#sessionDetailSlideContainerMobileSafariIFrameAlert").addClass('hidden'); loadSlide_loadingNow = false; } function filterByMenu(menuItem) { filter = {}; if (menuItem.attr('ndc-conf') != "") filter.conf = menuItem.attr('ndc-conf'); var filterTrack = menuItem.attr('ndc-track'); if (typeof (filterTrack) !== 'undefined' && filterTrack != "") filter.tracks = [filterTrack]; showSessionList(filter); } function generateConfTrackLink(title, conf, track) { return $('') .attr('href', '#') .text(title) .attr('ndc-conf', conf) .attr('ndc-track', track) .click(function (e) { e.preventDefault(); filterByMenu($(this)); }); } function buildNavMenuFromConfMap(navbarItems, confMap) { for (var confName in confMap) { var dropDown = $('
  • ').addClass("dropDown"); dropDown.appendTo(navbarItems); var title = $('').attr('href', '#').addClass("dropdown-toggle").attr('data-toggle', 'dropdown'); title.click(function (e) { e.preventDefault(); }); title.text(confName); //.append($('').addClass("caret")); dropDown.append(title); createDropDownUl(confMap[confName]).appendTo(dropDown); } // TEST $('#navbarItems').html(''); var sessionListLeft = $("#divSessionListLeft"); sessionListLeft.html(''); sessionListLeft.append($('
  • ')); var linkBase = $('