diff options
Diffstat (limited to 'www/js')
-rw-r--r-- | www/js/apps.js | 154 | ||||
-rw-r--r-- | www/js/auth.js | 160 | ||||
-rw-r--r-- | www/js/clock.js | 34 | ||||
-rw-r--r-- | www/js/importer.js | 86 | ||||
-rw-r--r-- | www/js/jingles.js | 10 | ||||
-rw-r--r-- | www/js/musicgrid.js | 12 | ||||
-rw-r--r-- | www/js/musicpools.js | 59 | ||||
-rw-r--r-- | www/js/router.js | 176 | ||||
-rw-r--r-- | www/js/shows.js | 76 | ||||
-rw-r--r-- | www/js/utils.js | 8 |
10 files changed, 463 insertions, 312 deletions
diff --git a/www/js/apps.js b/www/js/apps.js deleted file mode 100644 index dd5b337..0000000 --- a/www/js/apps.js +++ /dev/null @@ -1,154 +0,0 @@ -/* - * rhwebimport - * - * Copyright (C) 2014-2016 Christian Pointner <equinox@helsinki.at> - * Copyright (C) 2015-2016 Peter Grassberger <petertheone@gmail.com> - * - * This file is part of rhwebimport. - * - * rhwebimport is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * rhwebimport is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with rhwebimport. If not, see <http://www.gnu.org/licenses/>. - */ - -'use strict'; - -var Rdxport = Rdxport || {}; - -var apps_current = null; -var rdxport = null; -var importer = null; - -function apps_select(app) { - if (importer && importer.isUploading()) { - alert('Achtung: Es laufen noch imports.'); - return; - } - - $('.container').removeClass('fullWidth'); - - shows_cleanup(); - jingles_cleanup(); - musicpools_cleanup(); - musicgrid_cleanup(); - - switch(app) { - case "musicgrid": - $('#app-shows').hide(); - $('#nav-btn-shows').removeClass('active'); - $('#app-jingles').hide(); - $('#nav-btn-jingles').removeClass('active'); - $('#app-musicpools').hide(); - $('#nav-btn-musicpools').removeClass('active'); - - $('.container').addClass('fullWidth'); - $('#app-musicgrid').show(); - $('#nav-btn-musicgrid').addClass('active'); - - apps_current = app; - musicgrid_init(); - break; - case "musicpools": - $('#app-shows').hide(); - $('#nav-btn-shows').removeClass('active'); - $('#app-jingles').hide(); - $('#nav-btn-jingles').removeClass('active'); - $('#app-musicgrid').hide(); - $('#nav-btn-musicgrid').removeClass('active'); - - $('#app-musicpools').show(); - $('#nav-btn-musicpools').addClass('active'); - - apps_current = app; - musicpools_init(); - break; - case "jingles": - $('#app-shows').hide(); - $('#nav-btn-shows').removeClass('active'); - $('#app-musicpools').hide(); - $('#nav-btn-musicpools').removeClass('active'); - $('#app-musicgrid').hide(); - $('#nav-btn-musicgrid').removeClass('active'); - - $('#app-jingles').show(); - $('#nav-btn-jingles').addClass('active'); - - apps_current = app; - jingles_init(); - break; - default: - $('#app-jingles').hide(); - $('#nav-btn-jingles').removeClass('active'); - $('#app-musicpools').hide(); - $('#nav-btn-musicpools').removeClass('active'); - $('#app-musicgrid').hide(); - $('#nav-btn-musicgrid').removeClass('active'); - - $('#app-shows').show(); - $('#nav-btn-shows').addClass('active'); - - apps_current = app = 'shows'; - shows_init(); - } - if (locationHrefValue() !== app) { - history.pushState(null, null, '/' + app + '/'); - } -} - -function apps_init() { - importer = new Rdxport.Importer(); - - apps_current = locationHrefValue(); - - if(auth_token && auth_username) { - // todo: do this at a central place - rdxport = new Rdxport.Rdxport(auth_username, auth_token, '/rd-bin/rdxport.cgi'); - rdxport.setListDropboxesEndpoint('/rh-bin/listdropboxes.cgi'); - rdxport.setMusicgridEndpoint('/rh-bin/musicgrid.cgi'); - - apps_select(apps_current); - } - - $(window).on('popstate', function(event) { - if(auth_token && auth_username) { - // todo: do this at a central place - rdxport = new Rdxport.Rdxport(auth_username, auth_token, '/rd-bin/rdxport.cgi'); - rdxport.setListDropboxesEndpoint('/rh-bin/listdropboxes.cgi'); - rdxport.setMusicgridEndpoint('/rh-bin/musicgrid.cgi'); - - apps_select(locationHrefValue()); - } - }); - - $(document).ajaxError(function(event, jqXHR, settings, thrownError) { - //todo: add errors - }); - - window.onbeforeunload = function(e) { - if (importer && importer.isUploading()) { - return 'Achtung: Es laufen noch imports.'; - } - }; -} - -function apps_cleanup() { - shows_cleanup(); - jingles_cleanup(); - musicpools_cleanup(); - musicgrid_cleanup(); - - $(window).off('popstate'); - - importer = null; - rdxport = null; - apps_current = null; -} diff --git a/www/js/auth.js b/www/js/auth.js index d01b70d..691a19e 100644 --- a/www/js/auth.js +++ b/www/js/auth.js @@ -24,94 +24,84 @@ var Rdxport = Rdxport || {}; -var auth_username = null; -var auth_fullname = null; -var auth_token = null; - -function auth_loginSuccess(data) { - if (data.status == 'OK') { - auth_username = data.username; - auth_fullname = data.fullname; - auth_token = data.token; - - sessionStorage.setItem("auth_username", auth_username); - sessionStorage.setItem("auth_fullname", auth_fullname); - sessionStorage.setItem("auth_token", auth_token); - - // todo: do this at a central place - rdxport = new Rdxport.Rdxport(auth_username, auth_token, '/rd-bin/rdxport.cgi'); - rdxport.setListDropboxesEndpoint('/rh-bin/listdropboxes.cgi'); - rdxport.setMusicgridEndpoint('/rh-bin/musicgrid.cgi'); - - apps_select(apps_current); - - $('#username-field').html(auth_fullname + ' (' + auth_username + ')'); - $('#loginbox').slideUp(); - $('#mainwindow').fadeIn(); - } else { - alertbox.error('loginbox', "Fehler beim Login", data.errorstring); - auth_cleanup(); - } -} - -function auth_loginError(req, status, error) { - var message = req.status + ': ' + error; - if(req.status == 401) { - message = "Benutzer und/oder Passwort sind falsch!"; - } - alertbox.error('loginbox', "Fehler beim Login", message); - $("#password").val(''); -} - -function auth_logout() { - if (importer && importer.isUploading()) { - alert('Achtung: Es laufen noch imports.'); - return; - } - - auth_cleanup(); - apps_cleanup(); +Rdxport.Auth = function() { + this.username = sessionStorage.getItem('auth_username'); + this.fullname = sessionStorage.getItem('auth_fullname'); + this.token = sessionStorage.getItem('auth_token'); +}; + +Rdxport.Auth.prototype.isLoggedIn = function() { + return this.username && this.fullname && this.token; +}; + +Rdxport.Auth.prototype.set = function(username, fullname, token) { + this.username = username; + this.fullname = fullname; + this.token = token; + + sessionStorage.setItem('auth_username', this.username); + sessionStorage.setItem('auth_fullname', this.fullname); + sessionStorage.setItem('auth_token', this.token); +}; + +Rdxport.Auth.prototype.cleanup = function() { + sessionStorage.removeItem('auth_username'); + sessionStorage.removeItem('auth_fullname'); + sessionStorage.removeItem('auth_token'); + + this.username = null; + this.fullname = null; + this.token = null; +}; + +Rdxport.AuthView = function(model) { + this.model = model; +}; + +Rdxport.AuthView.prototype.renderLoggedIn = function() { + $('#loginbox').slideUp(); + $('#mainwindow').fadeIn(); + $('#username-field').text(this.model.fullname + ' (' + this.model.username + ')'); + + $('button.logout').off().on('click', function() { + router.route('logout'); + }); +}; - $(".alert").alert('close'); - $("#username").val(''); - $("#password").val(''); - $("#mainwindow").fadeOut(); - $('#username-field').html(''); +Rdxport.AuthView.prototype.renderLoginForm = function() { + $('.alert').alert('close'); $('#loginbox').slideDown(); -} + $('#mainwindow').fadeOut(); + $('#username-field').empty(); -function auth_init() { - auth_username = sessionStorage.getItem("auth_username"); - auth_fullname = sessionStorage.getItem("auth_fullname"); - auth_token = sessionStorage.getItem("auth_token"); - - if(auth_token && auth_username && auth_fullname) { - $("#loginbox").hide(); - $('#username-field').html(auth_fullname + ' (' + auth_username + ')'); - } else { - $("#mainwindow").hide(); - } - $("#loginform").submit(function(event) { + var self = this; + $('#loginform').on('submit', function(event) { event.preventDefault(); - Rdxport.Rdxport.authLogin( - '/rh-bin/authtoken.json', - $("#username").val(), - $("#password").val(), - auth_loginSuccess - ).fail(auth_loginError); + '/rh-bin/authtoken.json', + $("#username").val(), + $("#password").val(), + function(data) { + if (data.status == 'OK') { + self.model.set( + data.username, + data.fullname, + data.token + ); + + router.route(); + } else { + alertbox.error('loginbox', "Fehler beim Login", data.errorstring); + self.model.cleanup(); + } + } + ).fail(function(req, status, error) { + var message = req.status + ': ' + error; + if(req.status == 401) { + message = "Benutzer und/oder Passwort sind falsch!"; + } + alertbox.error('loginbox', "Fehler beim Login", message); + $("#password").val(''); + }); }); -} - -function auth_cleanup() { - sessionStorage.removeItem("auth_username"); - sessionStorage.removeItem("auth_fullname"); - sessionStorage.removeItem("auth_token"); - - auth_username = null; - auth_fullname = null; - auth_token = null; - - $("#username").val('').focus(); - $("#password").val(''); -} +}; diff --git a/www/js/clock.js b/www/js/clock.js index 96ec9e4..458d1c7 100644 --- a/www/js/clock.js +++ b/www/js/clock.js @@ -32,8 +32,16 @@ function Clock() { this.clock_rtt = 0; this.state = 'NEW'; + this.getRDTimeMS = function() { + return (+new Date()) + (this.last_message.tz_offset * 1000) + this.clock_offset; + } + + this.now = function() { + return new Date(this.getRDTimeMS()); + } + this.redraw = function() { - var rdtime_ms = (+new Date()) + (this.last_message.tz_offset * 1000) + this.clock_offset; + var rdtime_ms = this.getRDTimeMS(); var rdtime = new Date(rdtime_ms); var date_str = weekday_short[rdtime.getUTCDay()] + ', '; @@ -44,11 +52,11 @@ function Clock() { time_str += (rdtime.getUTCSeconds() > 9 ? ':' : ':0') + rdtime.getUTCSeconds(); this.draw_callbacks.fireWith(window, [date_str, time_str, get_rd_week(rdtime_ms)]); - } + }; this.addCallback = function(cb) { this.draw_callbacks.add(cb); - } + }; this.ntp_update = function(event) { var t4 = (+new Date()); @@ -59,18 +67,18 @@ function Clock() { this.clock_offset = ((msg.t2 - msg.t1) + (msg.t3 - msg.t4)) / 2; this.clock_rtt = (msg.t4 - msg.t1) - (msg.t3 - msg.t2); // console.log('got new ntp message from rhrdtime (rtt=' + this.clock_rtt + ' ms): new offset = ' + this.clock_offset + ' ms'); - } + }; this.ntp_request = function() { this.sock.send(JSON.stringify({ t1: (+new Date()), t2: 0, t3: 0, t4: 0, tz_offset: 0, week: 0 })); - } + }; this.sock_onopen = function() { // console.log('clock websocket connection established'); this.state = 'CONNECTED'; this.ntp_request(); this.interval_request = setInterval(this.ntp_request.bind(this), 2000); - } + }; this.sock_onclose = function(event) { if(this.state == 'STOPPED') { @@ -84,7 +92,7 @@ function Clock() { setTimeout(this.connect.bind(this), 1000); this.state = 'RECONNECTING'; } - } + }; this.connect = function() { this.sock = new WebSocket('wss://' + window.location.host + '/ntp'); @@ -92,12 +100,12 @@ function Clock() { this.sock.onopen = this.sock_onopen.bind(this); this.sock.onclose = this.sock_onclose.bind(this); this.state = 'CONNECTING'; - } + }; this.start = function() { this.connect(); this.interval_redraw = setInterval(this.redraw.bind(this), 200); - } + }; this.stop = function() { this.state = 'STOPPED'; @@ -106,13 +114,7 @@ function Clock() { clearInterval(this.interval_request); delete this.interval_request; this.sock.close(); - } -} - -var clock = new Clock(); - -function clock_init() { - clock.start(); + }; } function clock_add_callback(cb) { diff --git a/www/js/importer.js b/www/js/importer.js index 4ea55b3..b34c4b6 100644 --- a/www/js/importer.js +++ b/www/js/importer.js @@ -24,10 +24,88 @@ var Rdxport = Rdxport || {}; -Rdxport.Importer = function() { - this.$el = $('#uploadModal'); +Rdxport.Importer = function(username, token) { + this.username = username; + this.token = token; + this.$el = $('#uploadModal'); this.uploads = []; + this.webSocket = null; + + this.initWebSocket(); +}; + +Rdxport.Importer.CMD_LIST = 'list'; +Rdxport.Importer.CMD_NEW = 'new'; +Rdxport.Importer.CMD_RECONNECT = 'reconnect'; + +Rdxport.Importer.prototype.initWebSocket = function() { + var importer = this; + + var webSocket = new WebSocket('wss://import.helsinki.at/rhimportd'); + + webSocket.onclose = function(code, reason) { + console.log('close'); + console.log(code); + console.log(reason); + }; + + webSocket.onerror = function() { + console.log('error'); + }; + + webSocket.onopen = function() { + console.log('open'); + + console.log('send new'); + var sendOptions = { + COMMAND: Rdxport.Importer.CMD_NEW, + LOGIN_NAME: importer.username, + PASSWORD: importer.token, + TIMEOUT: 200, + REFERENCE_ID: "999", + SHOW_ID: 10000, + CLEAR_SHOW_CARTS: true, + SOURCE_URI: 'archiv://2016/03/31/05' + }; + console.log(sendOptions); + this.send(JSON.stringify(sendOptions)); + }; + + webSocket.onmessage = function(event) { + console.log('message'); + console.log(event.data); + }; + + /*this.webSocket = new WebSocket('wss://import.helsinki.at/rhimportd'); + + this.webSocket.onclose = function(code, reason) { + console.log('close'); + console.log(code); + console.log(reason); + }; + + this.webSocket.onerror = function() { + console.log('error'); + }; + + this.webSocket.onopen = function() { + console.log('open'); + + console.log('send reconnect'); + var reconnectOptions = { + COMMAND: Rdxport.Importer.CMD_RECONNECT, + LOGIN_NAME: importer.username, + PASSWORD: importer.token + }; + console.log(reconnectOptions); + this.send(JSON.stringify(reconnectOptions)); + }; + + this.webSocket.onmessage = function(event) { + console.log('message'); + console.log(event.data); + };*/ }; Rdxport.Importer.prototype.resetModal = function() { @@ -258,8 +336,8 @@ Rdxport.Upload.prototype.addCut = function(file) { file.cutNumber = cutNumberLeading; formData.append('COMMAND', 2); - formData.append('LOGIN_NAME', auth_username); - formData.append('PASSWORD', auth_token); + formData.append('LOGIN_NAME', auth.username); + formData.append('PASSWORD', auth.token); formData.append('CART_NUMBER', self.cart.number); formData.append('CUT_NUMBER', cutNumber); formData.append('CHANNELS', 2); diff --git a/www/js/jingles.js b/www/js/jingles.js index 02070ae..e819570 100644 --- a/www/js/jingles.js +++ b/www/js/jingles.js @@ -44,7 +44,7 @@ Rdxport.JingleGroupListView = function(model) { this.jingleGroupViews = []; - $('#app-jingles .groups').html(''); + $('#app-jingles .groups').empty(); var self = this; $(this.model).on('update', function() { @@ -87,7 +87,7 @@ Rdxport.JingleGroupView = function(model) { var self = this; $(this.model).on('update', function() { - $('table > tbody', self.$el).html(''); + $('table > tbody', self.$el).empty(); self.model.mainCart = self.model.carts[0]; self.mainCartView = new Rdxport.JingleCartView(self.model.mainCart, self, true); @@ -105,7 +105,7 @@ Rdxport.JingleGroupView.prototype.render = function() { this.$el = $('#hiddenTemplates .jingleGroupTemplate').clone().removeClass('jingleGroupTemplate'); this.$el.appendTo('#app-jingles .groups'); - $('h2', this.$el).html(this.model.title); + $('h2', this.$el).text(this.model.title); $('table tbody tr', this.$el).remove(); $('.uploadButton', this.$el).on('click', function() { @@ -114,7 +114,7 @@ Rdxport.JingleGroupView.prototype.render = function() { }; Rdxport.JingleGroupView.prototype.destroy = function() { - $('table > tbody', this.$el).html(''); + $('table > tbody', this.$el).empty(); }; Rdxport.JingleGroupView.prototype.uploadProgress = function(upload, file) { @@ -149,7 +149,7 @@ Rdxport.JingleGroupView.prototype.uploadError = function(upload, file, msg, xhr, //var msg = $(xmlDoc); //var responseCode = msg.find('ResponseCode').text(); //var errorString = msg.find('ErrorString').text(); - var reason = $('<span>').addClass('label').addClass('label-danger').text(responseCode).after($('<b>').html(' ' + errorString)); + var reason = $('<span>').addClass('label').addClass('label-danger').text(responseCode).after($('<b>').text(' ' + errorString)); var dismiss_button = '<button class="btn btn-info btn-xs">' + '<span class="glyphicon glyphicon-remove"></span> Ok</button>'; diff --git a/www/js/musicgrid.js b/www/js/musicgrid.js index dbb2210..a0a0c10 100644 --- a/www/js/musicgrid.js +++ b/www/js/musicgrid.js @@ -58,7 +58,7 @@ Rdxport.MusicgridView = function(model) { Rdxport.MusicgridView.prototype.clean = function() { $('tr td', this.$el) - .html('') + .empty() .removeClass('clock') .css('background-color', '') .css('color', '') @@ -71,7 +71,7 @@ Rdxport.MusicgridView.prototype.update = function() { $(this.model.clocks).each(function(index, clock) { var $td = $('tr[data-dow="' + clock.dow + '"] td[data-hour="' + clock.hour +'"]', this.$el); $td.addClass('clock'); - $td.html(clock.name); + $td.text(clock.name); $td.attr('title', clock.title); $td.css('background-color', clock.color); if($td.isBackgroundDark()) { @@ -105,9 +105,9 @@ Rdxport.MusicpoolModal.prototype.selectClock = function(dow, hour, clockName) { var $modalHeader = $('#musicpoolModal .modal-header'); var $modalBody = $('#musicpoolModal .modal-body'); - $('h4', $modalHeader).html('Musikpool auswählen für Tag: ' + dow + ' Stunde: ' + hour + '.'); + $('h4', $modalHeader).text('Musikpool auswählen für Tag: ' + dow + ' Stunde: ' + hour + '.'); - $('tbody', $modalBody).html(''); + $('tbody', $modalBody).empty(); var self = this; $(this.model).off().on('update', function() { @@ -128,8 +128,8 @@ Rdxport.MusicpoolModal.prototype.selectClock = function(dow, hour, clockName) { }); var $tr = $('<tr>'); - $tr.append($('<td>').html(musicpool.clock)); - $tr.append($('<td>').html(musicpool.title)); + $tr.append($('<td>').text(musicpool.clock)); + $tr.append($('<td>').text(musicpool.title)); $tr.append($('<td>').html($button)); $('tbody', $modalBody).append($tr); diff --git a/www/js/musicpools.js b/www/js/musicpools.js index 400c0bd..5b3d491 100644 --- a/www/js/musicpools.js +++ b/www/js/musicpools.js @@ -26,9 +26,9 @@ var Rdxport = Rdxport || {}; var musicpoolsView = null; -function musicpools_init() { +function musicpools_init(subpage) { var musicpools = new Rdxport.GroupList(); - musicpoolsView = new Rdxport.MusicpoolsView(musicpools); + musicpoolsView = new Rdxport.MusicpoolsView(musicpools, subpage); } function musicpools_cleanup() { @@ -36,11 +36,13 @@ function musicpools_cleanup() { musicpoolsView = null; } -Rdxport.MusicpoolsView = function(model) { +Rdxport.MusicpoolsView = function(model, subpage) { this.model = model; this.musicpoolViews = []; - this.currentPoolId = sessionStorage.getItem('currentPoolId'); + this.currentPoolId = null; + + this.setCurrentPoolId(subpage); var self = this; $(this.model).on('update', function() { @@ -54,6 +56,16 @@ Rdxport.MusicpoolsView = function(model) { }; Rdxport.MusicpoolsView.prototype.setCurrentPoolId = function(currentPoolId) { + if (!currentPoolId) { + return; + } + if (this.currentPoolId !== currentPoolId) { + if (this.currentPoolId) { + history.pushState(null, null, '/musicpools/' + currentPoolId + '/'); + } else { + history.replaceState(null, null, '/musicpools/' + currentPoolId + '/'); + } + } this.currentPoolId = currentPoolId; sessionStorage.setItem('currentPoolId', this.currentPoolId); }; @@ -84,22 +96,31 @@ Rdxport.MusicpoolsView.prototype.updateSelector = function() { var $musicpoolSelector = $('#musicpool-selector'); $musicpoolSelector.off(); - $('option', $musicpoolSelector).remove(); - - $(this.model.groups).each(function(index, musicpool) { - var name = musicpool.title + ' (' + musicpool.clock + ')'; - $musicpoolSelector.append($('<option>').attr('value', musicpool.clock).text(name)); + $('li', $musicpoolSelector).remove(); + + $(this.model.groups).sort(function(a, b) { + return a.title.toLowerCase() >= b.title.toLowerCase() + }).each(function(index, musicpool) { + var name = '<strong>' + musicpool.title + '</strong> (' + musicpool.clock + ')'; + var link = $('<a>').attr('href', '#').html(name).click(function() { + self.setCurrentPoolId(musicpool.clock); + self.getCurrentPoolView().model.fetchCarts(); + }); + $musicpoolSelector.append($('<li>').append(link)); }); - - if (this.currentPoolId === null) { - this.setCurrentPoolId(this.model.groups[0].clock); + if($musicpoolSelector.children().length == 0) { + $musicpoolSelector.append($('<li>').append($('<a>').text('Keinen Musikpool gefunden!'))); } - $('option[value="' + this.currentPoolId + '"]', $musicpoolSelector).attr('selected', 'selected'); - $musicpoolSelector.on('change', function() { - self.setCurrentPoolId($('option:selected', $musicpoolSelector).attr('value')); - self.getCurrentPoolView().model.fetchCarts(); - }); + // todo: maybe integrate this into setCurrentShowId? + if (!this.currentPoolId) { + var currentPoolId = sessionStorage.getItem('currentPoolId'); + if (currentPoolId) { + this.setCurrentPoolId(currentPoolId); + } else { + this.setCurrentPoolId(this.model.groups[0].id); + } + } this.getCurrentPoolView().model.fetchCarts(); }; @@ -136,7 +157,7 @@ Rdxport.MusicpoolView.prototype.render = function() { this.$el = $('#hiddenTemplates .musicpoolTemplate').clone().removeClass('musicpoolTemplate'); $('#app-musicpools .musicpoolContainer').html(this.$el); - $('h2', this.$el).html(this.model.title); + $('#musicpool-title').text(this.model.title); $('table tbody tr', this.$el).remove(); this.cartViews = []; @@ -184,7 +205,7 @@ Rdxport.MusicpoolView.prototype.uploadError = function(upload, file, msg, xhr, a //var msg = $(xmlDoc); //var responseCode = msg.find('ResponseCode').text(); //var errorString = msg.find('ErrorString').text(); - var reason = $('<span>').addClass('label').addClass('label-danger').text(responseCode).after($('<b>').html(' ' + errorString)); + var reason = $('<span>').addClass('label').addClass('label-danger').text(responseCode).after($('<b>').text(' ' + errorString)); var dismiss_button = '<button class="btn btn-info btn-xs">' + '<span class="glyphicon glyphicon-remove"></span> Ok</button>'; diff --git a/www/js/router.js b/www/js/router.js new file mode 100644 index 0000000..cfeaf23 --- /dev/null +++ b/www/js/router.js @@ -0,0 +1,176 @@ +/* + * rhwebimport + * + * Copyright (C) 2014-2016 Christian Pointner <equinox@helsinki.at> + * Copyright (C) 2015-2016 Peter Grassberger <petertheone@gmail.com> + * + * This file is part of rhwebimport. + * + * rhwebimport is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * rhwebimport is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with rhwebimport. If not, see <http://www.gnu.org/licenses/>. + */ + +'use strict'; + +var clock = null; +var auth = null; +var router = null; +var importer = null; +var rdxport = null; + +$(document).ready(function() { + clock = new Clock(); + clock.start(); + auth = new Rdxport.Auth(); + router = new Rdxport.Router(auth); + router.route(); +}); + +Rdxport.Router = function(auth) { + this.auth = auth; + this.authView = new Rdxport.AuthView(this.auth); +}; + +Rdxport.Router.prototype.route = function(page, subpage) { + if (!this.auth.isLoggedIn()) { + this.login(); + return; + } + if (importer && importer.isUploading()) { + alert('Achtung: Es laufen noch imports.'); + return; + } + + if (!importer) { + importer = new Rdxport.Importer(this.auth.username, this.auth.token); + window.onbeforeunload = function(event) { + if (importer.isUploading()) { + return 'Achtung: Es laufen noch imports.'; + } + }; + } + if (!rdxport) { + rdxport = new Rdxport.Rdxport(this.auth.username, this.auth.token, '/rd-bin/rdxport.cgi'); + rdxport.setListDropboxesEndpoint('/rh-bin/listdropboxes.cgi'); + rdxport.setMusicgridEndpoint('/rh-bin/musicgrid.cgi'); + } + + /*$(document).ajaxError(function(event, jqXHR, settings, thrownError) { + //todo: add errors + });*/ + + var href = ['', '']; + if (!page && !subpage) { + href = locationHrefValue(); + page = href[1]; + subpage = href[2]; + } + + shows_cleanup(); + jingles_cleanup(); + musicpools_cleanup(); + musicgrid_cleanup(); + + this.authView.renderLoggedIn(); + $('.navbar-nav li').removeClass('active'); + $('.app-tab').hide(); + $('.container').removeClass('fullWidth'); + + var self = this; + $('.navbar-nav li a').off().on('click', function(event) { + event.preventDefault(); + var href = $(this).attr('href').split('/'); + self.route(href[1], href[2]); + }); + $(window).off('popstate').on('popstate', function(event) { + var href = locationHrefValue(); + self.route(href[1], href[2]); + }); + + switch (page) { + default : + page = 'shows'; + // fallthrough + case 'shows': + this.shows(subpage); + break; + case 'jingles': + this.jingles(); + break; + case 'musicpools': + this.musicpools(subpage); + break; + case 'musicgrid': + this.musicgrid(); + break; + case 'logout': + this.logout(); + break; + } + + href = locationHrefValue(); + if (href[1] !== page && page !== 'logout' && (!href[2] || href[2] !== subpage)) { + var url = '/' + page + '/'; + if (subpage) { + url += subpage + '/'; + } + history.pushState(null, null, url); + } +}; + +Rdxport.Router.prototype.login = function() { + this.authView.renderLoginForm(); +}; + +Rdxport.Router.prototype.logout = function() { + if (importer && importer.isUploading()) { + alert('Achtung: Es laufen noch imports.'); + return; + } + + shows_cleanup(); + jingles_cleanup(); + musicpools_cleanup(); + musicgrid_cleanup(); + this.auth.cleanup(); + + importer = null; + rdxport = null; + + this.login(); +}; + +Rdxport.Router.prototype.shows = function(subpage) { + $('#app-shows').show(); + $('#nav-btn-shows').addClass('active'); + shows_init(subpage); +}; + +Rdxport.Router.prototype.jingles = function() { + $('#app-jingles').show(); + $('#nav-btn-jingles').addClass('active'); + jingles_init(); +}; + +Rdxport.Router.prototype.musicpools = function(subpage) { + $('#app-musicpools').show(); + $('#nav-btn-musicpools').addClass('active'); + musicpools_init(subpage); +}; + +Rdxport.Router.prototype.musicgrid = function() { + $('.container').addClass('fullWidth'); + $('#app-musicgrid').show(); + $('#nav-btn-musicgrid').addClass('active'); + musicgrid_init(); +}; diff --git a/www/js/shows.js b/www/js/shows.js index 8fcba8b..233a5c3 100644 --- a/www/js/shows.js +++ b/www/js/shows.js @@ -26,9 +26,9 @@ var Rdxport = Rdxport || {}; var showListView = null; -function shows_init() { +function shows_init(subpage) { var showList = new Rdxport.GroupList(); - showListView = new Rdxport.ShowListView(showList); + showListView = new Rdxport.ShowListView(showList, subpage); drawClock('Do, 1.1.1970', '00:00:00', 0); clock_add_callback(drawClock); @@ -39,11 +39,13 @@ function shows_cleanup() { importer.cancelAllUploads(); } -Rdxport.ShowListView = function(model) { +Rdxport.ShowListView = function(model, subpage) { this.model = model; this.showViews = []; - this.currentShowId = sessionStorage.getItem('currentShowId'); + this.currentShowId = null; + + this.setCurrentShowId(subpage); var self = this; $(this.model).on('update', function() { @@ -57,6 +59,16 @@ Rdxport.ShowListView = function(model) { }; Rdxport.ShowListView.prototype.setCurrentShowId = function(currentShowId) { + if (!currentShowId) { + return; + } + if (this.currentShowId !== currentShowId) { + if (this.currentShowId) { + history.pushState(null, null, '/shows/' + currentShowId + '/'); + } else { + history.replaceState(null, null, '/shows/' + currentShowId + '/'); + } + } this.currentShowId = currentShowId; sessionStorage.setItem('currentShowId', this.currentShowId); }; @@ -68,9 +80,6 @@ Rdxport.ShowListView.prototype.getCurrentShowView = function() { if (this.showViews.length === 0) { return null; } - if (this.currentShowId === null) { - this.setCurrentShowId(this.model.groups[0].id); - } var self = this; var showViewFound = null; $(this.showViews).each(function(index, showView) { @@ -87,22 +96,34 @@ Rdxport.ShowListView.prototype.updateSelector = function() { var $showSelector = $('#show-selector'); $showSelector.off(); - $('option', $showSelector).remove(); + $('li', $showSelector).remove(); - $(this.model.groups).each(function(index, show) { - var name = show.title + ' (' + show.rhythm + ', ' + weekday[show.dayofweek] + ', ' + show.starttime + ', ' + show.length + ' Min.)'; - $showSelector.append($('<option>').attr('value', show.id).text(name)); + $(this.model.groups).sort(function(a, b) { + if(a.title.toLowerCase() == b.title.toLowerCase()) { + return b.rhythm - a.rhythm; + } + return a.title.toLowerCase() >= b.title.toLowerCase() + }).each(function(index, show) { + var name = show.id + ' | <strong>' + show.title + '</strong> (' + show.rhythm + ', ' + weekday[show.dayofweek] + ', ' + show.starttime + ', ' + show.length + ' Min.)'; + var link = $('<a>').attr('href', '#').html(name).click(function() { + self.setCurrentShowId(show.id); + self.getCurrentShowView().model.fetchCarts(); + }); + $showSelector.append($('<li>').append(link)); }); - - if (this.currentShowId === null) { - this.setCurrentShowId(this.model.groups[0].id); + if($showSelector.children().length == 0) { + $showSelector.append($('<li>').append($('<a>').text('Keine Sendung gefunden!'))); } - $('option[value="' + this.currentShowId + '"]', $showSelector).attr('selected', 'selected'); - $showSelector.on('change', function() { - self.setCurrentShowId($('option:selected', $showSelector).attr('value')); - self.getCurrentShowView().model.fetchCarts(); - }); + // todo: maybe integrate this into setCurrentShowId? + if (!this.currentShowId) { + var currentShowId = sessionStorage.getItem('currentShowId'); + if (currentShowId) { + this.setCurrentShowId(currentShowId); + } else { + this.setCurrentShowId(this.model.groups[0].id); + } + } this.getCurrentShowView().model.fetchCarts(); }; @@ -189,10 +210,23 @@ Rdxport.ShowView = function(model) { Rdxport.ShowView.prototype.render = function() { $('#show-title').text(this.model.title); $('#show-dow').text(weekday[this.model.dayofweek]); - $('#show-rhythm').text(this.model.rhythm); $('#show-starttime').text(this.model.starttime); $('#show-length').text(this.model.length + ' Min.'); + for(var w = 0; w < 4; w++) { + if(this.model.rhythm.charAt(w) == '1') { + var s = $('#show-rhythm-w' + (w+1)).attr('class', 'label') + switch(w+1) { + case 1: s.addClass('label-info'); break; + case 2: s.addClass('label-warning'); break; + case 3: s.addClass('label-success'); break; + case 4: s.addClass('label-danger'); break; + } + } else { + $('#show-rhythm-w' + (w+1)).attr('class', 'label label-disabled') + } + } + var $tableBody = $('#app-shows table tbody'); $('tr', $tableBody).remove(); @@ -249,7 +283,7 @@ Rdxport.ShowView.prototype.uploadError = function(upload, file, msg, xhr, acknow //var msg = $(xmlDoc); //var responseCode = msg.find('ResponseCode').text(); //var errorString = msg.find('ErrorString').text(); - var reason = $('<span>').addClass('label').addClass('label-danger').text(responseCode).after($('<b>').html(' ' + errorString)); + var reason = $('<span>').addClass('label').addClass('label-danger').text(responseCode).after($('<b>').text(' ' + errorString)); var dismiss_button = '<button class="btn btn-info btn-xs">' + '<span class="glyphicon glyphicon-remove"></span> Ok</button>'; diff --git a/www/js/utils.js b/www/js/utils.js index 26b0822..7e7a656 100644 --- a/www/js/utils.js +++ b/www/js/utils.js @@ -108,8 +108,8 @@ function get_rd_week(msEpoch) { } function locationHrefValue() { - var value = window.location.href.match(/import.helsinki.at\/([a-z]+)\/?.*/); - return value ? value[1] : ''; + var value = window.location.href.match(/import.helsinki.at\/([a-z]+)\/?([a-z0-9]+)?\/?.*/); + return value ? value : ''; } /* @@ -141,6 +141,10 @@ jQuery.fn.brightness = function() { } }; +jQuery.fn.sort = function() { + return this.pushStack(jQuery.makeArray([].sort.apply(this, arguments))); +}; + function updateProgressBar($el, upload) { if(upload.uploadprogress.progress < 99) { var bytes_str = Number((upload.uploadprogress.bytesSent/1024)/1024).toFixed(1) + " von " + |