All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ui.js.app.engage-ui.js Maven / Gradle / Ivy

There is a newer version: 16.7
Show newest version
/**
 * Licensed to The Apereo Foundation under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 *
 * The Apereo Foundation licenses this file to you under the Educational
 * Community License, Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of the License
 * at:
 *
 *   http://opensource.org/licenses/ecl2.txt
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 */

/* global define, pushHistory */

define(['jquery', 'bootbox.min', 'underscore', 'alertify/alertify', 'js-yaml.min', 'bootstrap-accessibility',
  'jquery.liveSearch', 'seedrandom.min', 'jquery.utils',
  'dropdowns-enhancement'
],
function($, bootbox, _, alertify, jsyaml) {

  // bool
  var debug = false;
  var askedForLogin = false;
  var checkLoggedOut = false;

  // URL's and Endpoints
  var restEndpoint = '/search/';
  var playerEndpoint = '/play/';
  var infoMeURL = '/info/me.json';
  var configURL = '/ui/config/engage-ui/config.yml';
  var springSecurityLoginURL = '/j_spring_security_check';
  var springSecurityLogoutURL = '/j_spring_security_logout';

  // various variables
  var mediaContainer = '
'; var page = 1; var sort = ''; var totalEntries = -1; var bufferEntries = 18; // number of entries to load for one page. var restData = ''; var active = 'episodes'; var tabIndexNumber = 100; var seriesRgbMax = new Array(220, 220, 220); //color range. var seriesRgbOffset = new Array(20, 20, 20); //darkest possible color var sortMap = {}; var sortDescription = ''; // localization placeholder var title_enterUsernamePassword = 'Login with your Opencast account'; var placeholder_username = 'Username'; var placeholder_password = 'Password'; var placeholder_rememberMe = 'Remember me'; var msg_enterUsernamePassword = 'Please enter your username and password:'; var msg_html_sthWentWrong = '

Something went wrong. Try again!

'; var msg_html_noepisodes = '

No episodes available

'; var msg_html_noseries = '

No series available

'; var msg_html_loading = '

Loading...

'; var msg_html_mediapackageempty = '

No episodes available

'; var msg_html_nodata = '

No data available

'; var msg_loginSuccessful = 'Successfully logged in. Please reload the page if the page does not reload automatically.'; var msg_not_logged_in = 'Not logged in'; var msg_loginFailed = 'Failed to log in.'; var msg_live_in_progress = 'Live (in progress)'; var msg_live_not_in_progress = 'Live (not in progress)'; var springLoggedInStrCheck = 'j_spring_security_check'; var $navbarEpisodes = '#navbarEpisodes'; var $navbarSeries = '#navbarSeries'; var $headerLogo = '#headerLogo'; var $nav_switch_li = '#nav-switch li'; var $oc_search_form = '#oc-search-form'; var $oc_sort_dropdown = '.oc-sort-dropdown'; var $main_container = '#main-container'; var $next = '.next'; var $previous = '.previous'; var $more_content = '#more'; var $no_more_content = '#no-more'; var id_mhlogolink = 'mhlogolink'; var $nav_username = '#nav-username'; var $nav_loginlogoutLink = '#nav-loginlogoutLink'; var $name_loginlogout = '#name-loginlogout'; var $glyph_loginlogout = '#glyph-loginlogout'; var epFromGet = '', searchQuery = ''; function log(args) { if (debug && window.console) { // eslint-disable-next-line no-console console.log(args); } } function detectLanguage() { return navigator.language || navigator.userLanguage || navigator.browserLanguage || navigator.systemLanguage || 'en-US'; } function getDefaultLanguage(language) { var lang = language.substring(0, language.indexOf('-')); if (!lang || lang.length <= 0) { lang = language; } switch (lang) { case 'de': return 'de-DE'; case 'da': return 'da-DK'; case 'el': return 'el-GR'; case 'en': return 'en-US'; case 'es': return 'es-ES'; case 'fr': return 'fr-FR'; case 'gl': return 'gl-ES'; case 'he': return 'he-IL'; case 'it': return 'it-IT'; case 'nl': return 'nl-NL'; case 'pl': return 'pl-PL'; case 'sl': return 'sl-SI'; case 'sv': return 'sv-SE'; case 'tr': return 'tr-TR'; case 'zh': return 'zh-CN'; default: return null; } } function loadAndTranslate(callbackFunction, lang) { log('loadAndTranslate'); if (!lang) lang = detectLanguage(); var selectedLanguage = lang; if (getDefaultLanguage(lang) !== null) { selectedLanguage = getDefaultLanguage(lang); } var jsonstr = window.location.origin + '/engage/ui/language/' + selectedLanguage + '.json'; log('Detected Language: ' + selectedLanguage); var template; // load template $.ajax({ url: window.location.origin + '/engage/ui/template/desktop.html', dataType: 'html' }).fail(function() { $('body').append('Error loading template.'); }).done(function(tData) { // set template data template = _.template(tData); // load translation $.ajax({ url: jsonstr, dataType: 'json' }).fail(function() { log('Failed to load language data for ' + selectedLanguage + '. Try to load alternative.'); // load default en-US loadAndTranslate(callbackFunction, 'en-US'); }).done(function(data) { log('Append template and set variables.'); setTemplateAndVariables(data, template); }).then(callbackFunction); }); // ajax translation } function GetURLParameter(sParam) { var sPageURL = window.location.search.substring(1); var sURLVariables = sPageURL.split('&'); for (var i = 0; i < sURLVariables.length; i++) { var sParameterName = sURLVariables[i].split('='); if (sParameterName[0] == sParam) { return sParameterName[1]; } } } function setTemplateAndVariables(tData, template) { log('setTemplateAndVariables'); $('body').append(template(tData)); sortMap['DATE_CREATED_DESC'] = tData.recording_date_new; sortMap['DATE_CREATED'] = tData.recording_date_old; sortMap['DATE_PUBLISHED_DESC'] = tData.publishing_date_new; sortMap['DATE_PUBLISHED'] = tData.publishing_date_old; sortMap['TITLE'] = tData.title_a_z; sortMap['TITLE_DESC'] = tData.title_z_a; sortMap['CREATOR'] = tData.author_a_z; sortMap['CREATOR_DESC'] = tData.author_z_a; sortMap['CONTRIBUTOR'] = tData.contributor_a_z; sortMap['CONTRIBUTOR_DESC'] = tData.contributor_z_a; sortMap['PUBLISHER'] = tData.publisher_a_z; sortMap['PUBLISHER_DESC'] = tData.publisher_z_a; sortMap['SERIES_ID'] = tData.series; sortMap['LANGUAGE'] = tData.language; sortMap['LICENSE'] = tData.license; sortMap['SUBJECT'] = tData.subject; sortMap['DESCRIPTION'] = tData.description; // set variables title_enterUsernamePassword = tData.login_title; placeholder_username = tData.username; placeholder_password = tData.password; placeholder_rememberMe = tData.remember_me; msg_enterUsernamePassword = tData.login_request; msg_html_sthWentWrong = '

' + tData.sthWentWrong + '

'; msg_html_noepisodes = '

' + tData.no_episodes + '

'; msg_html_noseries = '

' + tData.no_series + '

'; msg_html_loading = '

' + tData.loading + '

'; msg_html_mediapackageempty = '

' + tData.no_episodes + '

'; msg_html_nodata = '

' + tData.no_data + '

'; msg_loginSuccessful = tData.login_success; msg_loginFailed = tData.login_failed; msg_not_logged_in = tData.not_logged_in; msg_live_in_progress = tData.live_in_progress; msg_live_not_in_progress = tData.live_not_in_progress; } function initialize() { log('Start initialize.'); $('#' + id_mhlogolink).attr('href', '/engage/ui'); getInfo(); getConfig(); registerHandler(); debug = GetURLParameter('debug'); if (debug) { $.enableLogging(true); } // load series or episodes var loadSer = GetURLParameter('s') != undefined && GetURLParameter('s') == 1, loadEp = GetURLParameter('e') != undefined && GetURLParameter('e') == 1; // get page from url parameter var pageNotGet = GetURLParameter('p') == undefined; page = pageNotGet ? 1 : parseInt(GetURLParameter('p')); // load episodes from specific series epFromGet = GetURLParameter('epFrom'); epFromGet = epFromGet == undefined ? '' : 'sid=' + epFromGet + '&'; // search query from form searchQuery = GetURLParameter('q') == undefined ? '' : 'q=' + GetURLParameter('q') + '&'; log('Searching for: ' + searchQuery); if (searchQuery != '') $('#searchInput').val(decodeURIComponent(GetURLParameter('q').replace(/\+/g, ' '))); // sort if (GetURLParameter('sort') == undefined) { sort = ''; } else { sort = 'sort=' + GetURLParameter('sort') + '&'; sortDescription = GetURLParameter('sort'); $('#' + sortDescription).prop('checked', true); $('#buttonSorting').text(sortMap[sortDescription]); } // sort = GetURLParameter("sort") == undefined ? "" : "sort="+GetURLParameter("sort")+"&"; var prefix = location.search == '' ? '?p=' : '&p='; if (loadEp || (!loadEp && !loadSer)) { $($nav_switch_li).removeClass('active'); $('#navbarEpisodes').addClass('active'); // load Episodes and set pagination loadEpisodes(true, epFromGet + searchQuery + sort, function() { if (page < Math.floor(totalEntries / bufferEntries) + 1) { $('#lastPage').attr('href', pageNotGet ? location.href + prefix + (Math.floor(totalEntries / bufferEntries) + 1) : location.href.replace(/(p=[\d]*)/, 'p=' + (Math.floor(totalEntries / bufferEntries) + 1))); $('#nextPage').attr('href', pageNotGet ? location.href + prefix + (page + 1) : location.href.replace(/(p=[\d]*)/, 'p=' + (page + 1))); } else { $($next).addClass('disabled'); } }); } else if (loadSer) { $($nav_switch_li).removeClass('active'); $('#navbarSeries').addClass('active'); // load Series and set pagination loadSeries(true, searchQuery + sort, function() { if (page < Math.floor(totalEntries / bufferEntries) + 1) { $('#lastPage').attr('href', pageNotGet ? location.href + prefix + (Math.floor(totalEntries / bufferEntries) + 1) : location.href.replace(/(p=[\d]*)/, 'p=' + (Math.floor(totalEntries / bufferEntries) + 1))); $('#nextPage').attr('href', pageNotGet ? location.href + prefix + (page + 1) : location.href.replace(/(p=[\d]*)/, 'p=' + (page - 1))); } else { $($next).addClass('disabled'); } }); } if (page == 1) { $($previous).addClass('disabled'); } else { $('#prevPage').attr('href', pageNotGet ? location.href + prefix + (page - 1) : location.href.replace(/(p=[\d]*)/, 'p=' + (page - 1))); $('#firstPage').attr('href', pageNotGet ? location.href + prefix + '1' : location.href.replace(/(p=[\d]*)/, 'p=1')); } endlessScrolling(); $($main_container).html(msg_html_loading); } function endlessScrolling() { log('init endless scrolling'); $(window).scroll(function() { $($more_content).hide(); $($no_more_content).hide(); $($more_content).show(); if ($(window).scrollTop() + $(window).height() > $(document).height() - 200) { $($more_content).show(); } if ($(window).scrollTop() + $(window).height() == $(document).height()) { $($more_content).hide(); $($no_more_content).hide(); page++; if (page > 1) { $($previous).removeClass('disabled'); } if ((page - 1) * bufferEntries > totalEntries) { $($no_more_content).show(); $($next).addClass('disabled'); } else { log('loading data'); $($more_content).show(); if (active == 'series') { loadSeries(false, epFromGet + searchQuery + sort); } else { loadEpisodes(false, epFromGet + searchQuery + sort); } } } }); } $(document).ready(function() { loadAndTranslate(initialize); }); function login() { if (!askedForLogin) { askedForLogin = true; var box = bootbox.dialog({ title: title_enterUsernamePassword, message: '', buttons: { cancel: { label: 'Cancel', className: 'btn-default', callback: function() { askedForLogin = false; } }, login: { label: 'Log in', className: 'btn-success', callback: function() { var username = $('#username').val().trim(); var password = $('#password').val().trim(); if ((username !== null) && (username.length > 0) && (password !== null) && (password.length > 0)) { $.ajax({ type: 'POST', url: springSecurityLoginURL, data: { 'j_username': username, 'j_password': password, '_spring_security_remember_me': $('#rememberMe').is(':checked') } }).done(function(msg) { password = ''; if (msg.indexOf(springLoggedInStrCheck) == -1) { location.reload(); alertify.success(msg_loginSuccessful + ' \'' + username + '\'.'); loadAndTranslate(initialize); } else { alertify.error(msg_loginFailed + ' \'' + username + '\'.'); } askedForLogin = false; }).fail(function() { password = ''; alertify.error(msg_loginFailed + ' \'' + username + '\'.'); askedForLogin = false; }); } else { askedForLogin = false; } } } }, className: 'usernamePassword-modal', onEscape: function() { askedForLogin = false; }, closeButton: false }); box.bind('shown.bs.modal', function(){ box.find('input#username').focus(); }); } } function logout() { $.ajax({ type: 'GET', url: springSecurityLogoutURL, complete: function() { location.reload(); loadAndTranslate(initialize); } }); } function setAnonymousUser() { $($nav_username).html(msg_not_logged_in); $($name_loginlogout).html('Login'); $($glyph_loginlogout).removeClass('glyphicon-log-out').addClass('glyphicon-log-in'); $($nav_loginlogoutLink).unbind('click'); $($nav_loginlogoutLink).click(login); } function setUsername(name) { $($nav_username).html(name); $($name_loginlogout).html('Logout'); $($glyph_loginlogout).removeClass('glyphicon-log-in').addClass('glyphicon-log-out'); $($nav_loginlogoutLink).unbind('click'); $($nav_loginlogoutLink).click(logout); } function getConfig() { log('Get config'); $.ajax({ url: configURL, dataType: 'text', success: function(data) { log('Configuration loaded'); var config = jsyaml.load(data); $($headerLogo).attr('src', config.logo || ''); } }); } function getInfo() { log('Get info'); $.ajax({ url: infoMeURL, dataType: 'json', success: function(data) { log('User information loaded'); if (data) { if (data.roles && (data.roles.length > 0)) { var notAnonymous = false; for (var i = 0; i < data.roles.length; ++i) { if (data.roles[i] != 'ROLE_ANONYMOUS') { notAnonymous = true; } } if (notAnonymous) { if (checkLoggedOut) { window.location = springSecurityLogoutURL; } log('User is not anonymous'); if (data.username) { log('Username found: ' + data.username); setUsername(data.username); } else if (data.user && data.user.username) { log('Username found: ' + data.user.username); setUsername(data.user.username); } else { log('Username not found'); } } else { checkLoggedOut = false; log('User is anonymous'); setAnonymousUser(); } } else { log('Error: No role'); setAnonymousUser(); } } } }); } function registerHandler() { /* handle search input */ $($oc_search_form).submit(function() { if (active == 'series') { $('#oc-search-form .form-group').append( '' ); } else if (active == 'episodes') { $('#oc-search-form .form-group').append( '' ); } else { log('Error!'); } return true; }); $($oc_sort_dropdown).on('change', function() { $($oc_search_form).submit(); }); log('Handler registered'); } function loadEpisodes(cleanGrid, rest, callback) { log('Loading Episodes with: ' + rest); active = 'episodes'; var requestUrl = restEndpoint + 'episode.json?limit=' + bufferEntries + '&offset=' + ((page - 1)) * bufferEntries + '&' + rest; $.ajax({ url: requestUrl, dataType: 'json', success: function(data) { // clear main grid if (cleanGrid) { $($main_container).empty(); window.scrollTo(0, 0); tabIndexNumber = 100; } if (data && data['search-results'] && data['search-results']['total']) { // number of total search results totalEntries = data['search-results']['total']; var total = data['search-results']['limit']; if (data['search-results'] == undefined || total == undefined) { log('Error: Search results (total) undefined'); $($main_container).append(msg_html_sthWentWrong); return; } if (total == 0) { $($main_container).append(msg_html_noepisodes); $($next).addClass('disabled'); return; } var result = data['search-results']['result']; if (page == 1) { $($previous).addClass('disabled'); } if (result.length < bufferEntries || total < bufferEntries) { $($next).addClass('disabled'); } else { $($next).removeClass('disabled'); } if (total == 1) { buildGrid(result); return; } $.each(result, function(index, val) { buildGrid(val); }); } else { $($main_container); } } }).then(callback); } function buildGrid(data) { if (data) { var serID = data['id']; if (data['id'] == undefined) { log('Error: Episode with no ID.'); serID = '0'; } var seriesClass = ''; if (data.mediapackage) { seriesClass = 'series' + _.escape(data.mediapackage.series) + ' '; } var tile = mediaContainer + '' + '
' + '
' + '

' + _.escape(data.dcTitle) + '

'; // append thumbnail var thumb = ''; var time = 0; var creator = '
'; var seriestitle = '
'; var date = '
'; var live = '
'; var canLaunch = true; if (data.mediapackage) { if (data.mediapackage.attachments && data.mediapackage.attachments.attachment) { // Try finding the best preview image: // presentation/search+preview > presenter/search+preview > any other preview for (var i = 0; i < data.mediapackage.attachments.attachment.length; i++) { var att = data.mediapackage.attachments.attachment[i]; if (att.url && att.type.indexOf('+preview') > 0) { if (thumb == '' || att.type.indexOf('/search+preview') > 0) { thumb = data.mediapackage.attachments.attachment[i].url; if (att.type == 'presentation/search+preview') { // Stop if we got presentation/search+preview. We do not want to overwrite that. break; } } } } tile = tile + '
'; } tile = tile + '
'; if (data.dcCreator) { creator = _.escape(data.dcCreator); } tile = tile + '
' + creator + '
'; if (data.mediapackage.seriestitle) { seriestitle = _.escape(data.mediapackage.seriestitle); } tile = tile + '
' + seriestitle + '
'; if (data.dcCreated) { date = new Date(data.dcCreated); } tile = tile + '
' + date.toLocaleDateString() + '
'; if (data.mediapackage.duration) { time = data.mediapackage.duration; var seconds = Math.floor((time / 1000) % 60); var minutes = Math.floor((time / (1000 * 60) % 60)); var hours = Math.floor((time / (1000 * 60 * 60) % 60)); if (seconds < 10) { seconds = '0' + seconds; } if (minutes < 10) { minutes = '0' + minutes; } if (hours < 10) { hours = '0' + hours; } tile = tile + '
' + hours + ':' + minutes + ':' + seconds + '
'; } if (data.mediapackage.media && data.mediapackage.media.track) { // Check if there's a 'live' track if (data.mediapackage.media.track.live) { // Is event in progress? var start = new Date(data.mediapackage.start); var end = new Date(start.getTime() + parseInt (data.mediapackage.duration)); var now = new Date(); if (now < start || now >= end) { live = _.escape(msg_live_not_in_progress); canLaunch = false; } else live = _.escape(msg_live_in_progress); } } tile += '
' + live + '
' + '
'; $($main_container).append(tile); if (canLaunch) { $('#' + _.escape(data['id'])).attr('href', _.escape(playerEndpoint + data['id'])); $('#' + _.escape(data['id'])).on('keypress', function(ev) { if (ev.which == 13 || ev.which == 32) { $(location).attr('href', _.escape(playerEndpoint + data['id'])); } }); } if (data.mediapackage.seriestitle) { var color = generateSeriesColor(data.mediapackage.series); $('.' + seriesClass).css({ 'background': color }); } } else { $($main_container).html(msg_html_mediapackageempty); } } else { $($main_container).html(msg_html_nodata); } /* TODO: Swipe events etc. for mobile devices */ } function createSeriesGrid(data) { log('build series grid'); if (data && data.id) { var seriesClass = 'series' + _.escape(data.id) + ' '; var color = generateSeriesColor(data.id); var creator = '
'; var contributor = '
'; var tile = mediaContainer + ' ' + '
' + '
' + '

' + (data.dcTitle ? _.escape(data.dcTitle) : 'Unknown title') + '

'; if (data.dcCreator) { creator = _.escape(data.dcCreator); } tile = tile + '
' + creator + '
'; if (data.dcContributor) { contributor = _.escape(data.dcContributor); } tile += '
' + contributor + '
' + '
'; $($main_container).append(tile); $('#' + _.escape(data.id)).attr('href', '?e=1&p=1&epFrom=' + _.escape(data.id)); $('#' + _.escape(data.id)).on('keypress', function(ev) { log('keypress'); if (ev.which == 13 || ev.which == 32) { restData = 'sid=' + data.id; page = 1; active = 'episodes'; $($navbarEpisodes).addClass('active'); $($navbarSeries).removeClass('active'); pushHistory(1, 'episodes', restData); loadEpisodes(true); } }); $('.' + seriesClass).css({ 'background': color }); log('Series Color: ' + seriesClass + ' ' + color); } else { log('Error: Data for creating series grid is empty.'); } } function loadSeries(cleanGrid, rest, callback) { log('Loading Series with: ' + rest); active = 'series'; var requestUrl = restEndpoint + '/series.json' + '?limit=' + bufferEntries + '&offset=' + (page - 1) * bufferEntries + '&' + rest; $.ajax({ url: requestUrl, dataType: 'json', success: function(data2) { if (data2 && data2['search-results'] && data2['search-results']['total']) { if (cleanGrid) { $($main_container).empty(); window.scrollTo(0, 0); tabIndexNumber = 100; } totalEntries = data2['search-results']['total']; var total = data2['search-results']['limit']; if (total == 0) { $($main_container).append(msg_html_noseries); $($next).addClass('disabled'); return; } var result = data2['search-results']['result']; if (page == 1) { $($previous).addClass('disabled'); } if (result.length < bufferEntries || total < bufferEntries) { $($next).addClass('disabled'); } else { $($next).removeClass('disabled'); } if (total == 1) { createSeriesGrid(result); return; } $.each(result, function(index, val) { createSeriesGrid(val); }); } else { $($main_container).append(msg_html_noseries); } } }).then(callback); } function generateSeriesColor(value) { var rgb = new Array(0, 0, 0); for (let i = 0; i < value.length; ++i) { rgb[(i % 3)] += value.charCodeAt(i); } for (let i = 0; i < 3; ++i) { rgb[i] = ((rgb[i] % seriesRgbMax[i]) + seriesRgbOffset[i]).toString(16); if (rgb[i].length < 1) { rgb[i] = '0' + rgb[i]; } } return '#' + rgb[0] + rgb[1] + rgb[2]; } });



© 2015 - 2025 Weber Informatics LLC | Privacy Policy